diff --git a/common/cool/coolconfig/config.go b/common/cool/coolconfig/config.go index b669ee75..e2f39420 100644 --- a/common/cool/coolconfig/config.go +++ b/common/cool/coolconfig/config.go @@ -6,7 +6,6 @@ import ( "time" "github.com/gogf/gf/v2/frame/g" - "github.com/gogf/gf/v2/util/gconv" ) // cool config @@ -50,7 +49,11 @@ type ServerList struct { } func (s *ServerList) GetID() string { - return gconv.String(100000*s.OnlineID + s.Port) + return RuntimeIDString(s.OnlineID, s.Port) +} + +func (s *ServerList) RuntimeID() uint32 { + return ComposeRuntimeID(s.OnlineID, s.Port) } // OSS相关配置 diff --git a/common/cool/coolconfig/runtime_id.go b/common/cool/coolconfig/runtime_id.go new file mode 100644 index 00000000..c4a8c0b4 --- /dev/null +++ b/common/cool/coolconfig/runtime_id.go @@ -0,0 +1,22 @@ +package coolconfig + +import "github.com/gogf/gf/v2/util/gconv" + +const runtimeIDPortBits = 16 +const runtimeIDPortMask uint32 = 0xFFFF + +// ComposeRuntimeID 将 serverID 和 port 组合成运行时复合 ID。 +// 高 16 位保存 serverID,低 16 位保存 port。 +func ComposeRuntimeID(serverID, port uint32) uint32 { + return ((serverID & runtimeIDPortMask) << runtimeIDPortBits) | (port & runtimeIDPortMask) +} + +// SplitRuntimeID 将运行时复合 ID 拆分为 serverID 和 port。 +func SplitRuntimeID(runtimeID uint32) (serverID, port uint32) { + return runtimeID >> runtimeIDPortBits, runtimeID & runtimeIDPortMask +} + +// RuntimeIDString 返回运行时复合 ID 的字符串形式。 +func RuntimeIDString(serverID, port uint32) string { + return gconv.String(ComposeRuntimeID(serverID, port)) +} diff --git a/common/cool/rpc.go b/common/cool/rpc.go index c4792f7c..5ecb6791 100644 --- a/common/cool/rpc.go +++ b/common/cool/rpc.go @@ -1,25 +1,27 @@ package cool +import "blazing/cool/coolconfig" + // 存值示例 func AddClient(id uint32, client *ClientHandler) { // 普通map:Clientmap[id] = client Clientmap.Store(id, client) // sync.Map存值 } -// 清理指定client(uid=100000*onlineID+port) +// 清理指定 client(高 16 位 serverID,低 16 位 port) func DeleteClientOnly(uid uint32) { Clientmap.Delete(uid) } -// 清理指定client(onlineID+port) +// 清理指定 client(由 serverID 和 port 组合) func DeleteClient(id, port uint32) { - Clientmap.Delete(100000*id + port) + Clientmap.Delete(coolconfig.ComposeRuntimeID(id, port)) } // 取值示例 func GetClient(id, port uint32) (*ClientHandler, bool) { // 普通map:client, ok := Clientmap[id] - val, ok := Clientmap.Load(100000*id + port) // sync.Map取值 + val, ok := Clientmap.Load(coolconfig.ComposeRuntimeID(id, port)) // sync.Map取值 if !ok { return nil, false } diff --git a/common/rpc/rpc.go b/common/rpc/rpc.go index 221728c0..e4af98a3 100644 --- a/common/rpc/rpc.go +++ b/common/rpc/rpc.go @@ -3,6 +3,7 @@ package rpc import ( "blazing/common/data/share" "blazing/cool" + "blazing/cool/coolconfig" "context" "fmt" @@ -190,7 +191,7 @@ func setupLogicReverseClient(ctx context.Context, revClient cool.ClientHandler) return err } - key := 100000*id + port + key := coolconfig.ComposeRuntimeID(id, port) go func() { <-ctx.Done() cool.DeleteClientOnly(key) @@ -210,6 +211,6 @@ func registerReverseLogicClient(ctx context.Context, id, port uint32) error { if ok && aa != nil { //如果已经存在且这个端口已经被存过 aa.QuitSelf(0) } - cool.AddClient(100000*id+port, &revClient) + cool.AddClient(coolconfig.ComposeRuntimeID(id, port), &revClient) return nil } diff --git a/logic/server.go b/logic/server.go index d32a281b..0f225b4d 100644 --- a/logic/server.go +++ b/logic/server.go @@ -81,7 +81,7 @@ func Start() { controller.Maincontroller.RPCClient = rpcClient //将RPC赋值Start - controller.Maincontroller.UID = gconv.Uint32(cool.Config.ServerInfo.GetID()) //赋值服务器ID + controller.Maincontroller.UID = cool.Config.ServerInfo.RuntimeID() //赋值服务器复合ID controller.Init(true) xmlres.Initfile() diff --git a/logic/service/fight/pvp/service.go b/logic/service/fight/pvp/service.go index 42898d37..74743d8b 100644 --- a/logic/service/fight/pvp/service.go +++ b/logic/service/fight/pvp/service.go @@ -13,8 +13,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "strconv" - "strings" "sync" "sync/atomic" "time" @@ -983,6 +981,5 @@ func isCoordinator() bool { } func localRuntimeServerID() uint32 { - id, _ := strconv.ParseUint(strings.TrimSpace(cool.Config.ServerInfo.GetID()), 10, 32) - return uint32(id) + return cool.Config.ServerInfo.RuntimeID() } diff --git a/logic/service/player/player.go b/logic/service/player/player.go index f92587e2..fdb53620 100644 --- a/logic/service/player/player.go +++ b/logic/service/player/player.go @@ -478,7 +478,8 @@ func (player1 *Player) Kick(isquit bool) { timeout := false select { case <-CloseChan: - // 正常流程:连接关闭回调已执行,CloseChan 被关闭 + // 连接已关闭后同步落盘,保证踢人链路返回前完成保存。 + player1.SaveOnDisconnect() case <-time.After(kickTimeout): timeout = true } diff --git a/modules/config/controller/admin/server.go b/modules/config/controller/admin/server.go index 94024c6b..0f328f97 100644 --- a/modules/config/controller/admin/server.go +++ b/modules/config/controller/admin/server.go @@ -34,7 +34,13 @@ type QuitSReq struct { func (this *ServerController) Quit(ctx context.Context, req *QuitSReq) (res *cool.BaseRes, err error) { res = &cool.BaseRes{} - serv := service.NewServerService().GetServerID(req.ID) + serverService := service.NewServerService() + if req.Code != 0 { + if err = serverService.SetServerOpen(req.ID, 0); err != nil { + return res, err + } + } + serv := serverService.GetServerID(req.ID) aa, ok := cool.GetClient(serv.OnlineID, serv.Port) if ok && aa != nil { //如果已经存在且这个端口已经被存过 diff --git a/modules/config/service/server.go b/modules/config/service/server.go index 460a3b1d..f81ea47d 100644 --- a/modules/config/service/server.go +++ b/modules/config/service/server.go @@ -167,6 +167,15 @@ func (s *ServerService) StartUPdate(OnlineID uint16, isinstall int) model.Server return tttt } +func (s *ServerService) SetServerOpen(OnlineID uint32, isOpen uint8) error { + m := cool.DBM(s.Model).Where("online_id", OnlineID) + var tttt model.ServerList + m.Scan(&tttt) + tttt.IsOpen = isOpen + _, err := m.Save(tttt) + return err +} + func (s *ServerService) SetServerID(OnlineID uint32, Port uint32) error { m := cool.DBM(s.Model).Where("online_id", OnlineID) var tttt model.ServerList diff --git a/modules/player/service/info.go b/modules/player/service/info.go index b7473217..67b294de 100644 --- a/modules/player/service/info.go +++ b/modules/player/service/info.go @@ -190,6 +190,7 @@ func (s *InfoService) Kick(id uint32) error { if !ok || cl == nil { // 目标服务器不在线,清理僵尸在线标记并视为成功 _ = share.ShareManager.DeleteUserOnline(id) + cool.DeleteClientOnly(useid1) return nil } @@ -211,6 +212,7 @@ func (s *InfoService) Kick(id uint32) error { } if cl2, ok2 := cool.GetClientOnly(useid2); !ok2 || cl2 == nil { _ = share.ShareManager.DeleteUserOnline(id) + cool.DeleteClientOnly(useid2) return nil } if isDisconnectedLogicReverseClientError(callErr) { @@ -227,6 +229,7 @@ func (s *InfoService) Kick(id uint32) error { } if cl2, ok2 := cool.GetClientOnly(useid2); !ok2 || cl2 == nil { _ = share.ShareManager.DeleteUserOnline(id) + cool.DeleteClientOnly(useid2) return nil } return fmt.Errorf("kick timeout, user still online: uid=%d server=%d", id, useid2)