diff --git a/src/server/game/gm_handler.go b/src/server/game/gm_handler.go index fdb4335f..17f12aab 100644 --- a/src/server/game/gm_handler.go +++ b/src/server/game/gm_handler.go @@ -270,7 +270,7 @@ func ReqGmCommand_(player *Player, Command string) error { N: ChampshipMod.GetN(), }, End: GoUtil.ZeroTimestamp() + 86400, // 第二天零点删除 - HandleType: MsgMod.HANDLE_MOD_CHAMPSHIP_INRANK, + HandleType: MsgMod.HANDLE_MDO_CHAMPSHIP_INRANK, } SendMsgToCenterAsync(m) case "resetUserInfo": diff --git a/src/server/game/message_mgr.go b/src/server/game/message_mgr.go index 44e24183..c010525e 100644 --- a/src/server/game/message_mgr.go +++ b/src/server/game/message_mgr.go @@ -26,7 +26,7 @@ type MessageMiddleware func(MessageHandlerFunc) MessageHandlerFunc var save_msg_type = []int{ msg.HANDLE_MOD_PLAYER_MSG, - msg.HANDLE_MOD_CHAMPSHIP_INRANK, + msg.HANDLE_MDO_CHAMPSHIP_INRANK, msg.HANDLE_MOD_USER_VAR_SET, } @@ -125,6 +125,31 @@ func (m *MessageMgr) MessageMgrInit() { m.Use(TimeoutMiddleware(5 * time.Second)) m.NodeRegister() m.CenterRegister() + FixBug() +} + +func FixBug() { + messageMgrData := getMessageData() + // 先更新 PlayerList(需要加锁) + G_GameLogicPtr.MessageMgr.lock.Lock() + defer G_GameLogicPtr.MessageMgr.lock.Unlock() + now := GoUtil.Now() + for k, v := range messageMgrData.MessageList { + if k < 100000 { + delete(messageMgrData.MessageList, k) + continue + } + // 反向遍历以安全删除元素 + for i := len(v.Messages) - 1; i >= 0; i-- { + if v.Messages[i].Type == msg.HANDLE_TYPE_CHAMPSHIP_NOTIFY || (v.Messages[i].End != 0 && v.Messages[i].End < now) { + // 删除消息 + v.Messages = append(v.Messages[:i], v.Messages[i+1:]...) + } + } + if len(v.Messages) == 0 { + delete(messageMgrData.MessageList, k) + } + } } // 注册处理器 @@ -143,7 +168,7 @@ func (m *MessageMgr) NodeRegister() { func (m *MessageMgr) CenterRegister() { if conf.Server.ServerType == "center" { m.RegisterHandler(msg.HANDLE_MOD_PLAYER_LOGIN, MessageHandlerFunc(PlayerLoginHandler)) - m.RegisterHandler(msg.HANDLE_MOD_PLAYER_LOGOUT, MessageHandlerFunc(PlayerLogoutHandler)) + m.RegisterHandler(msg.HANDLE_MDO_PLAYER_LOGOUT, MessageHandlerFunc(PlayerLogoutHandler)) m.RegisterHandler(msg.HANDLE_MOD_PLAYER_MSG, MessageHandlerFunc(CenterPlayerMsgHandler)) m.RegisterHandler(msg.HANDLE_MOD_COMSUME_MSG, MessageHandlerFunc(ComsumerMsgHandler)) m.RegisterHandler(msg.HANDLE_MOD_VAR_SET, MessageHandlerFunc(SetVarDataHandler)) @@ -151,7 +176,7 @@ func (m *MessageMgr) CenterRegister() { m.RegisterHandler(msg.HANDLE_MOD_USER_VAR_SET, MessageHandlerFunc(SetUserVarDataHandler)) m.RegisterHandler(msg.HANDLE_MOD_USER_VAR_GET, MessageHandlerFunc(GetUserVarDataHandler)) m.RegisterHandler(msg.HANDLE_MOD_CATNIP_PARTNER, MessageHandlerFunc(CatnipPartnerHandler)) - m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_INRANK, MessageHandlerFunc(ChampshipInRankHandler)) + m.RegisterHandler(msg.HANDLE_MDO_CHAMPSHIP_INRANK, MessageHandlerFunc(ChampshipInRankHandler)) m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_RANK_INFO, MessageHandlerFunc(ChampshipRankInfoHandler)) m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_RANK_LIST, MessageHandlerFunc(ChampshipRankListHandler)) m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_PRE_RANK, MessageHandlerFunc(ChampshipRankPreHandler)) @@ -860,6 +885,9 @@ func sendMessageSync(m *msg.Msg, node int) (*msg.Msg, error) { // 保存消息到本地 func saveMessage(m *msg.Msg) error { + G_GameLogicPtr.MessageMgr.lock.Lock() + defer G_GameLogicPtr.MessageMgr.lock.Unlock() + // 使用不加锁的内部方法,避免死锁 messages := getMessgeUnsafe(int64(m.To)) messages.mu.Lock() defer messages.mu.Unlock() @@ -916,6 +944,7 @@ func deleteMessage(m *msg.Msg) error { } messages := getMessge(int64(m.To)) messages.mu.Lock() + defer messages.mu.Unlock() // 使用更安全的方式删除元素:找到索引后再删除,避免在range中修改切片 foundIndex := -1 @@ -936,21 +965,12 @@ func deleteMessage(m *msg.Msg) error { messages.Messages[len(messages.Messages)-1] = nil // 清除最后一个元素的引用 messages.Messages = messages.Messages[:len(messages.Messages)-1] } - - shouldDelete := len(messages.Messages) == 0 - messages.mu.Unlock() // 先释放 messages.mu 锁,避免死锁 - - if shouldDelete { + if len(messages.Messages) == 0 { // 如果消息列表为空,则删除该玩家的消息列表 messageMgrData := getMessageData() - // 双重检查:再次确认消息列表是否为空(防止在锁释放期间有新消息添加) - if list, ok := messageMgrData.MessageList[int64(m.To)]; ok { - list.mu.Lock() - if len(list.Messages) == 0 { - delete(messageMgrData.MessageList, int64(m.To)) - } - list.mu.Unlock() - } + G_GameLogicPtr.MessageMgr.lock.Lock() + defer G_GameLogicPtr.MessageMgr.lock.Unlock() + delete(messageMgrData.MessageList, int64(m.To)) } return nil } diff --git a/src/server/game/mod/msg/Msg.go b/src/server/game/mod/msg/Msg.go index 1d9681a2..ad79e4e5 100644 --- a/src/server/game/mod/msg/Msg.go +++ b/src/server/game/mod/msg/Msg.go @@ -41,14 +41,14 @@ const ( HANDLE_MOD_PLAYER_LOGIN = 20003 // 玩家登录消息 HANDLE_MOD_COMSUME_MSG = 20004 // 消费消息 HANDLE_MOD_CLUSTER_SYNC = 20005 // 集群同步消息 - HANDLE_MOD_PLAYER_LOGOUT = 20006 // 玩家登出消息 + HANDLE_MDO_PLAYER_LOGOUT = 20006 // 玩家登出消息 HANDLE_MOD_VAR_GET = 20007 // 获取变量 HANDLE_MOD_VAR_SET = 20008 // 设置变量 HANDLE_MOD_CATNIP_PARTNER = 20009 // 猫薄荷伙伴 HANDLE_MOD_USER_VAR_GET = 20010 // 获取玩家变量 HANDLE_MOD_USER_VAR_SET = 20011 // 设置玩家变量 HANDLE_MOD_REPLY_PLAYER_MSG = 20012 // 回复玩家消息 - HANDLE_MOD_CHAMPSHIP_INRANK = 20013 // 锦标赛入榜 + HANDLE_MDO_CHAMPSHIP_INRANK = 20013 // 锦标赛入榜 HANDLE_MOD_CHAMPSHIP_RANK_INFO = 20014 // 锦标赛排名信息 HANDLE_MOD_CHAMPSHIP_RANK_LIST = 20015 // 锦标赛排行榜 HANDLE_MOD_CHAMPSHIP_PRE_RANK = 20016 // 锦标赛上期排名 diff --git a/src/server/game/player_data.go b/src/server/game/player_data.go index 969d0799..1fe85f8c 100644 --- a/src/server/game/player_data.go +++ b/src/server/game/player_data.go @@ -473,7 +473,7 @@ func (p *Player) ClearData() { G_GameLogicPtr.DelPlayer(p) SendMsgToCenterAsync(&MsgMod.Msg{ From: Uid, - HandleType: MsgMod.HANDLE_MOD_PLAYER_LOGOUT, + HandleType: MsgMod.HANDLE_MDO_PLAYER_LOGOUT, }) } @@ -1043,7 +1043,7 @@ func (p *Player) HandleInChampshipRank() { N: ChampshipMod.GetN(), }, End: GoUtil.ZeroTimestamp() + 86400, // 第二天零点删除 - HandleType: MsgMod.HANDLE_MOD_CHAMPSHIP_INRANK, + HandleType: MsgMod.HANDLE_MDO_CHAMPSHIP_INRANK, } SendMsgToCenterAsync(m) }