修复CPU占用问题,添加servers.JOIN,LEAVE,LIST包

This commit is contained in:
2025-07-11 02:27:16 +08:00
parent e5e02d2430
commit f5290d8585
13 changed files with 303 additions and 113 deletions

View File

@ -3,6 +3,7 @@ package minecraft
import (
"coreapp/util"
"coreapp/util/ws"
"fmt"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"google.golang.org/protobuf/proto"
@ -41,14 +42,15 @@ func (typ ServerType) Prefix() string {
}
type Server struct {
Id string `json:"id"`
Name string `json:"name"`
Group string `json:"group"`
Host string `json:"host"`
Port int `json:"port"`
Type ServerType `json:"type"`
Motd string `json:"motd"`
LastHB time.Time
Id string `json:"id"`
Name string `json:"name"`
Group string `json:"group"`
Host string `json:"host"`
Port int `json:"port"`
Type ServerType `json:"type"`
Motd string `json:"motd"`
Players []string `json:"players"`
LastHB time.Time
}
var servers = sync.Map{}
@ -88,11 +90,12 @@ func ServerMiddleware() gin.HandlerFunc {
}
func ServerList(c *gin.Context) {
serverList := make(map[string]*Server)
var serverList []Server
// 遍历 sync.Map
servers.Range(func(key, value interface{}) bool {
serverList[key.(string)] = value.(*Server)
server := value.(*Server)
serverList = append(serverList, *server)
return true // 继续遍历
})
@ -104,12 +107,12 @@ func ServerList(c *gin.Context) {
}
type ServerRegisterData struct {
Name string `json:"name"`
Name string `json:"name,omitempty"`
Host string `json:"host"`
Port int `json:"port"`
Type ServerType `json:"type"`
Group string `json:"group"`
Motd string `json:"motd"`
Group string `json:"group,omitempty"`
Motd string `json:"motd,omitempty"`
}
func ServerRegister(c *gin.Context) {
@ -223,6 +226,23 @@ func ServerMessage(c *gin.Context) {
if c.GetString("serverId") == "PROXY" {
serverProxyConn = wrapped
serverProxyLastHB = time.Now()
servers.Range(func(_, value any) bool {
server := value.(*Server)
newPkt := &ServerNewPacket{
ServerId: server.Id,
Name: server.Name,
Host: server.Host,
Port: int32(server.Port),
Group: server.Group,
Motd: server.Motd,
}
buf, err := serverWrapPacket(ServerPacketType_NEW, newPkt)
if err != nil {
panic(err)
}
wrapped.WriteChan <- ws.Binary(buf)
return true
})
go serverProxyReadLoop(wrapped)
} else {
go serverReadLoop(wrapped, c.GetString("serverId"))
@ -230,6 +250,9 @@ func ServerMessage(c *gin.Context) {
}
func serverReadLoop(conn *ws.Conn, serverId string) {
defer func() {
fmt.Printf("%s closed\n", serverId)
}()
for {
// 使用 Load 读取,避免并发问题
serverVal, ok := servers.Load(serverId)
@ -266,6 +289,43 @@ func serverReadLoop(conn *ws.Conn, serverId string) {
if serverProxyConn != nil {
serverProxyConn.WriteChan <- ws.Binary(msg)
}
case ServerPacketType_JOIN:
var payload ServerPlayerPacket
err := proto.Unmarshal(pkt.GetPayload(), &payload)
if err != nil {
continue
}
server.Players = append(server.Players, payload.Player)
case ServerPacketType_LEAVE:
var payload ServerPlayerPacket
err := proto.Unmarshal(pkt.GetPayload(), &payload)
if err != nil {
continue
}
for i, player := range server.Players {
if player == payload.Player {
server.Players = append(server.Players[:i], server.Players[i+1:]...)
break
}
}
case ServerPacketType_LIST:
var payload ServerListPacket
err := proto.Unmarshal(pkt.GetPayload(), &payload)
if err != nil {
panic(err)
}
reply := &ServerListPacket{
ServerId: payload.ServerId,
}
if s, ok := servers.Load(payload.ServerId); ok {
reply.Players = s.(*Server).Players
buf, err := proto.Marshal(reply)
if err != nil {
panic(err)
}
conn.WriteChan <- ws.Binary(buf)
return
}
}
default:
if conn.IsClosed() {
@ -280,28 +340,26 @@ func serverProxyReadLoop(conn *ws.Conn) {
serverProxyConn = nil
}()
for {
select {
case msg := <-conn.ReadChan:
if msg == nil {
return
msg := <-conn.ReadChan
if msg == nil {
return
}
pkt := &ServerPacket{}
err := proto.Unmarshal(msg, pkt)
if err != nil {
continue
}
switch pkt.GetTyp() {
case ServerPacketType_PING:
serverProxyLastHB = time.Now()
resp := &ServerPacket{
Typ: ServerPacketType_PONG,
}
pkt := &ServerPacket{}
err := proto.Unmarshal(msg, pkt)
buf, err := proto.Marshal(resp)
if err != nil {
panic(err)
}
switch pkt.GetTyp() {
case ServerPacketType_PING:
serverProxyLastHB = time.Now()
resp := &ServerPacket{
Typ: ServerPacketType_PONG,
}
buf, err := proto.Marshal(resp)
if err != nil {
panic(err)
}
conn.WriteChan <- ws.Binary(buf)
}
conn.WriteChan <- ws.Binary(buf)
}
}
}
@ -312,7 +370,7 @@ var serverUpgrader = websocket.Upgrader{
}
func generateServerId(prefix string) string {
return string(prefix) + util.RandStringNumber(rand.Intn(2)+1) + strings.ToUpper(util.RandStringAlphabet(rand.Intn(2)+1))
return prefix + util.RandStringNumber(rand.Intn(2)+1) + strings.ToUpper(util.RandStringAlphabet(rand.Intn(2)+1))
}
var serverHBTicker = time.NewTicker(time.Second * 5)