From 408bd4df5bb4a6b27a6584dd5920974fa746c962 Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:10:03 +0800 Subject: [PATCH] 2 --- src/server/cluster/cluster_func.go | 29 ++-- src/server/game/GameLogic.go | 28 ---- src/server/game/activity_func.go | 11 -- src/server/game/friend_mgr.go | 62 -------- src/server/game/game_type.go | 13 +- src/server/game/message_handler.go | 47 ++----- src/server/game/message_mgr.go | 168 +++++++++++++++------- src/server/game/mod/msg/Msg.go | 27 +++- src/server/game/player_data.go | 12 +- src/server/game/register_network_func.go | 35 ++--- src/server/game/var.go | 73 ++++++++++ src/server/game/var_mgr.go | 172 +++++++++++++++-------- src/server/game_util/GoUtil.go | 4 + 13 files changed, 397 insertions(+), 284 deletions(-) create mode 100644 src/server/game/var.go diff --git a/src/server/cluster/cluster_func.go b/src/server/cluster/cluster_func.go index eca8db02..5a157b40 100644 --- a/src/server/cluster/cluster_func.go +++ b/src/server/cluster/cluster_func.go @@ -50,8 +50,9 @@ func HandShakeRecv(a *Agent, m *msg.Msg) error { }) } else { syncMsg := &msg.Msg{ - Type: msg.CLUSTER_FRIEND_SYNC, - To: ServerId, + Type: msg.CLUSTER_FRIEND_SYNC, + To: ServerId, + HandleType: msg.HANDLE_MOD_CLUSTER_SYNC, } sendGameMsg(syncMsg) } @@ -96,7 +97,7 @@ func connectRemote(RemoteAddr string, ConnType int, ConnLabel string) error { client.NewAgent = newAgent client.ConnType = ConnType client.ConnLabel = ConnLabel - client.ConnectInterval = time.Duration(time.Minute * 5) + client.ConnectInterval = time.Duration(time.Minute * 1) if ConnType == ClusterCenterId { // 中心服断开重连 client.AutoReconnect = true } @@ -126,23 +127,21 @@ func CallServerMsg(m *msg.Msg, serverId int) (*msg.Msg, error) { if m.UniKey == "" { m.UniKey = GoUtil.UniKey(fmt.Sprintf("%v,Cluster Msg", m)) } + v, ok := serverAgent.Load(serverId) + // 之后再发送消息 + if !ok { + return nil, fmt.Errorf("server %d not online", serverId) + } // 先注册回调通道,避免发送出去后对方快速返回导致丢失 newChan := make(chan *msg.Msg, 1) registerChanel(m.UniKey, newChan) defer unregisterChanel(m.UniKey) - - // 之后再发送消息 - if v, ok := serverAgent.Load(serverId); ok { - data, err := GoUtil.GobMarshal(m) - if err != nil { - log.Debug("CallServerMsg GobMarshal err %v", err) - return nil, err - } - v.(network.Agent).WriteMsg(data) - } else { - return nil, fmt.Errorf("server %d not online", serverId) + data, err := GoUtil.GobMarshal(m) + if err != nil { + log.Debug("CallServerMsg GobMarshal err %v", err) + return nil, err } - + v.(network.Agent).WriteMsg(data) // 等待返回(直接接收一次) timeout := time.After(15 * time.Second) select { diff --git a/src/server/game/GameLogic.go b/src/server/game/GameLogic.go index 7b650c7a..c9ced423 100644 --- a/src/server/game/GameLogic.go +++ b/src/server/game/GameLogic.go @@ -286,33 +286,6 @@ func (ad *GameLogic) SetUserData(Uid int, Op int, Data interface{}) { }) } -func (ad *GameLogic) SetDataSync(Uid int, Op int, Data interface{}) error { - _, err := ad.VarMgr.Call(&MsgMod.Msg{ - From: Uid, - To: Uid, - Type: MsgMod.HANDLE_TYPE_VAR_EXPIRE_SET, - SendT: GoUtil.Now(), - Extra: VarOpration{Type: Op, Data: Data}, - }) - return err -} - -func (ad *GameLogic) SetCatnipPartner(Uid int, GameId int, PartnerUid int, EndT int64) error { - _, err := ad.VarMgr.Call(&MsgMod.Msg{ - From: Uid, - To: Uid, - Type: MsgMod.HANDLE_TYPE_SET_CATNIP_PARTNER, - SendT: GoUtil.Now(), - End: EndT, - Extra: map[string]interface{}{ - "uid": Uid, - "game_id": GameId, - "partner_uid": PartnerUid, - }, - }) - return err -} - func (ad *GameLogic) GetUserData(Uid int) *VarUserData { result, err := ad.FriendMgr.Call(&MsgMod.Msg{ From: Uid, @@ -665,7 +638,6 @@ func (ad *GameLogic) ReplaceExistPlayerAndAgent(a gate.Agent, player *Player) er if ok { Timer.Stop() } - player.SyncFriendMsg() log.Debug("player %d 重连", player.M_DwUin) return nil } diff --git a/src/server/game/activity_func.go b/src/server/game/activity_func.go index a840a5cc..18a9d579 100644 --- a/src/server/game/activity_func.go +++ b/src/server/game/activity_func.go @@ -417,14 +417,3 @@ func (p *Player) CatnipBackData() { } p.PushClientRes(res) } - -// 设置猫草大作战游戏锁 -func (p *Player) SetCatnipGameLock(Uid int, GameId int) error { - ActivityInfo := p.GetActivityInfoById(activity.ACT_TYPE_CATNIP) - return G_GameLogicPtr.SetDataSync(int(p.M_DwUin), VAR_OP_CATNIP_LOCK, CatnipLock{ - Uid: int(p.M_DwUin), - Partner: Uid, - GameId: GameId, - End: int(ActivityInfo.EndT), // 锁 - }) -} diff --git a/src/server/game/friend_mgr.go b/src/server/game/friend_mgr.go index e44e1083..feced6e3 100644 --- a/src/server/game/friend_mgr.go +++ b/src/server/game/friend_mgr.go @@ -45,7 +45,6 @@ func (f *FriendMgr) Init() { f.RegisterHandler(msg.HANDLE_TYPE_APPLY, f.sendToPlayer) f.RegisterHandler(msg.HADNLE_TYPE_AGREE, f.sendToPlayer) f.RegisterHandler(msg.HANDLE_TYPE_DEL, f.sendToPlayer) - f.RegisterHandler(msg.HANDLE_TYPE_SYNC, f.sync) f.RegisterHandler(msg.HANDLE_TYPE_REFUSE, f.sendToPlayer) f.RegisterHandler(msg.HANDLE_TYPE_INVITE_ADD_FRIEND, f.sendToPlayer) f.RegisterHandler(msg.HANDLE_TYPE_INVITE_FRIEND, f.sendToPlayer) @@ -90,8 +89,6 @@ func (f *FriendMgr) Init() { f.RegisterHandler(msg.HANDLE_TYPE_VAR_USER_GET, f.GetVarUserData) f.RegisterHandler(msg.HANDLE_TYPE_VAR_USER_SET, f.SetVarUserData) - f.RegisterHandler(msg.HANDLE_TYPE_VAR_EXPIRE_SET, f.SetExpireVarData) - f.RegisterHandler(msg.HANDLE_TYPE_CHAMPSHIP_LOGIN, f.SendMsgToCenter) f.RegisterHandler(msg.HANDLE_TYPE_CHAMPSHIP_INRANK, f.SendMsgToCenter) } @@ -175,34 +172,6 @@ func (f *FriendMgr) SetVarUserData(m *msg.Msg) (interface{}, error) { }, nil } -func (f *FriendMgr) SetExpireVarData(m *msg.Msg) (interface{}, error) { - VarOp := m.Extra.(VarOpration) - switch VarOp.Type { - case VAR_OP_CATNIP_LOCK: - data := VarOp.Data.(CatnipLock) - MyKey := GoUtil.GetCatnipLockKey(data.Uid, data.GameId) - OtherKey := GoUtil.GetCatnipLockKey(data.Partner, data.GameId) - ExpireData := G_GameLogicPtr.VarMgr.GetExpireVar(OtherKey) - if _, ok := ExpireData.D.(*CatnipLock); ok { - return nil, fmt.Errorf("catnip lock already exists for %d in game %d", data.Uid, data.GameId) - } - G_GameLogicPtr.VarMgr.SetExpireVar(MyKey, &VarExpireData{ - T: int64(data.End + 24*3600), // 设置过期时间 - D: &data, - }) - G_GameLogicPtr.VarMgr.SetExpireVar(OtherKey, &VarExpireData{ - T: int64(data.End + 24*3600), // 设置过期时间 - D: &CatnipLock{ - Uid: data.Partner, - Partner: data.Uid, - GameId: data.GameId, - End: data.End, - }, - }) - } - return nil, nil -} - // 发送消息给玩家 func sendToPlayer(m *msg.Msg) error { p := G_GameLogicPtr.GetPlayer(int64(m.To)) @@ -222,24 +191,6 @@ func sendToPlayerOnline(m *msg.Msg) error { return nil } -func FriendMgrSend(m1 *msg.Msg) error { - if m1.SendT == 0 { - m1.SendT = GoUtil.Now() - } - m := m1.Clone() - ToServer := GoUtil.GetServerIdByUid(m.To) - if ToServer != conf.Server.ServerID { - err := mergeCluster.SendServerMsg(m, ToServer) - if err != nil { // 区服不在线 - G_GameLogicPtr.FriendMgrSend(m) - return err - } - return nil - } - G_GameLogicPtr.FriendMgrSend(m) - return nil -} - // 集群好友消息同步 func ClusterFriendSync(m *msg.Msg) error { if v, ok := G_GameLogicPtr.FriendMgr.getData().ClusterMsg[m.To]; ok { @@ -264,16 +215,3 @@ func (f *FriendMgr) SendMsgToCenter(m *msg.Msg) (interface{}, error) { func (f *FriendMgr) CallMsgToCenter(m *msg.Msg) (interface{}, error) { return mergeCluster.CallServerMsg(m, conf.Server.CenterNode) } - -func FriendMgrCall(m *msg.Msg) interface{} { - ToServer := GoUtil.GetServerIdByUid(m.To) - if ToServer != conf.Server.ServerID { - r, err := mergeCluster.CallServerMsg(m, ToServer) - if err != nil { // 区服不在线 - log.Debug("FriendMgrCall err %v", err) - return nil - } - return r - } - return G_GameLogicPtr.FriendMgrCall(m.Clone()) -} diff --git a/src/server/game/game_type.go b/src/server/game/game_type.go index fcbae002..69b10613 100644 --- a/src/server/game/game_type.go +++ b/src/server/game/game_type.go @@ -54,8 +54,17 @@ type VarUserData struct { } type VarExpireData struct { - D interface{} - T int64 + D interface{} + T int64 // 过期时间戳 + U int64 // 最后更新时间 + mu sync.Mutex +} + +type CatnipPartner struct { + Uid int + Partner int + GameId int + EndTime int64 } const ( diff --git a/src/server/game/message_handler.go b/src/server/game/message_handler.go index 74272463..0aa35ac0 100644 --- a/src/server/game/message_handler.go +++ b/src/server/game/message_handler.go @@ -509,38 +509,6 @@ func (p *Player) handle(m *msg.Msg) error { return nil } -// 同步好友请求 -func (p *Player) SyncFriendMsg() { - MsgList := G_GameLogicPtr.FriendMgrCall(&msg.Msg{Type: msg.HANDLE_TYPE_SYNC, From: int(p.M_DwUin)}) - FriendMod := p.PlayMod.getFriendMod() - MsgId := FriendMod.GetSyncId() - if MsgList == nil { - return - } - ml := MsgList.([]*msg.Msg) - if len(ml) == 0 { - return - } - sort.Slice(ml, func(i, j int) bool { - return ml[i].Id < ml[j].Id - }) - maxId := int64(0) - for _, v := range ml { - maxId = max(maxId, v.Id) - if v.H == 1 { - continue - } - if v.Id > 0 && v.Id <= MsgId { - continue - } - log.Debug("uid : %d, handle friend msg : %v", p.M_DwUin, v) - p.handle(v) - v.H = 1 - } - FriendMod.SetSyncId(maxId) - p.PlayMod.save() -} - func SyncMailMsg(p *Player) { ServerMailList := G_GameLogicPtr.MailMgr.Sync(int(p.M_DwUin), p.GetPlayerBaseMod().GetRegisterTime()) MailMod := p.PlayMod.getMailMod() @@ -1302,3 +1270,18 @@ func (player *Player) IsWeeklyDiscount() bool { LimitEventMod := player.PlayMod.getLimitedTimeEventMod() return ChargeMod.IsWeeklyDiscountDay() || LimitEventMod.CheckExist(limitedTimeEvent.EVENT_TYPE_CAT_DAY_SALE) } + +func (p *Player) SetCatnipPartner(GameId, Partner int, EndTime int64) error { + _, err := SendMsgToCenterSync(&msg.Msg{ + From: int(p.M_DwUin), + To: int(p.M_DwUin), + Type: msg.HANDLE_MOD_CATNIP_PARTNER, + Extra: CatnipPartner{ + GameId: GameId, + Partner: Partner, + EndTime: EndTime, + Uid: int(p.M_DwUin), + }, + }) + return err +} diff --git a/src/server/game/message_mgr.go b/src/server/game/message_mgr.go index 0abca11b..368737a0 100644 --- a/src/server/game/message_mgr.go +++ b/src/server/game/message_mgr.go @@ -78,8 +78,10 @@ func (m *MessageMgr) MessageMgrInit() { 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)) } else { m.RegisterHandler(msg.HANDLE_MOD_PLAYER_MSG, MessageHandlerFunc(PlayerMsgHandler)) + m.RegisterHandler(msg.HANDLE_MOD_CLUSTER_SYNC, MessageHandlerFunc(ClusterSyncHandler)) } } @@ -88,13 +90,48 @@ func (s *MessageMgr) RegisterHandler(HandlerType int, fun MessageHandlerFunc) { s.handler[HandlerType] = fun } -func getData() *MessageData { +func getMessageData() *MessageData { return G_GameLogicPtr.MessageMgr.data.(*MessageData) } +// ----------------------------------- 处理函数实现 --------------------------- +func CatnipPartnerHandler(data *msg.Msg) (interface{}, error) { + m, ok := data.Extra.(*CatnipPartner) + if !ok { + return nil, fmt.Errorf("invalid catnip partner data") + } + return G_GameLogicPtr.VarMgr.HandleCatnipPartner(m.Uid, m.Partner, m.GameId, m.EndTime) + +} + +// 节点连接时,同步消息 +func ClusterSyncHandler(data *msg.Msg) (interface{}, error) { + // 遍历所有玩家,发送登录消息 + G_GameLogicPtr.M_Players.Range(func(k, v interface{}) bool { + SendMsgToCenterAsync(&msg.Msg{ + From: int(v.(*Player).M_DwUin), + HandleType: msg.HANDLE_MOD_PLAYER_LOGIN, + Extra: conf.Server.ServerID, + }) + return true + }) + // 发送暂存区消息 + messageMgrData := getMessageData() + messageMgrData.mu.Lock() + defer messageMgrData.mu.Unlock() + TempMessageList := messageMgrData.MessageList + messageMgrData.MessageList = make(map[int64]*MessageList) + for PlayerId, Message := range TempMessageList { + for _, msgItem := range Message.Messages { + go SendMsgToNodeAsync(msgItem, messageMgrData.PlayerList[PlayerId]) + } + } + return nil, nil +} + func PlayerLoginHandler(data *msg.Msg) (interface{}, error) { // 关闭 Worker Pool - messageMgrData := getData() + messageMgrData := getMessageData() messageMgrData.mu.Lock() defer messageMgrData.mu.Unlock() messageMgrData.PlayerList[int64(data.From)] = data.Extra.(int) @@ -112,16 +149,13 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) { messages.mu.Lock() defer messages.mu.Unlock() for _, message := range messages.Messages { - err := SendMsgToNode(message, node) - if err != nil { - log.Error("Failed to send message to player %d: %v", data.From, err) - } + go sendMessageAsync(message, node) } return nil, nil } func PlayerLogoutHandler(data *msg.Msg) (interface{}, error) { - messageMgrData := getData() + messageMgrData := getMessageData() messageMgrData.mu.Lock() defer messageMgrData.mu.Unlock() delete(messageMgrData.PlayerList, int64(data.From)) @@ -130,8 +164,8 @@ func PlayerLogoutHandler(data *msg.Msg) (interface{}, error) { } func ComsumerMsgHandler(data *msg.Msg) (interface{}, error) { - messageMgrData := getData() - Message, ok := messageMgrData.MessageList[int64(data.To)] + messageMgrData := getMessageData() + Message, ok := messageMgrData.MessageList[int64(data.From)] if !ok { return nil, nil } @@ -150,7 +184,7 @@ func ComsumerMsgHandler(data *msg.Msg) (interface{}, error) { func CenterPlayerMsgHandler(data *msg.Msg) (interface{}, error) { PlayerId := int64(data.To) - messageMgrData := getData() + messageMgrData := getMessageData() // 遍历消息列表,发送消息给在线玩家 messages, ok := messageMgrData.MessageList[int64(PlayerId)] if !ok { @@ -166,10 +200,7 @@ func CenterPlayerMsgHandler(data *msg.Msg) (interface{}, error) { messages.Messages = append(messages.Messages, data) if node, ok := messageMgrData.PlayerList[int64(PlayerId)]; ok { for _, message := range messages.Messages { - err := SendMsgToNode(message, node) - if err != nil { - log.Error("Failed to send message to player %d: %v", PlayerId, err) - } + go SendMsgToNodeAsync(message, node) } } return nil, nil @@ -179,9 +210,6 @@ func PlayerMsgHandler(data *msg.Msg) (interface{}, error) { p := G_GameLogicPtr.GetPlayer(int64(data.To)) // 不在线 不处理 if p == nil || p.stop { - // TODO: 模拟消费 - data.HandleType = msg.HANDLE_MOD_COMSUME_MSG - go SendMsgToCenter(data) return nil, nil } p.lock.Lock() @@ -189,7 +217,7 @@ func PlayerMsgHandler(data *msg.Msg) (interface{}, error) { p.Send(data.Clone()) // 处理完后发送消费消息 data.HandleType = msg.HANDLE_MOD_COMSUME_MSG - go SendMsgToCenter(data) + go SendMsgToCenterAsync(data) return nil, nil } @@ -221,19 +249,6 @@ func (m *MessageMgr) Handle(msg *msg.Msg) (interface{}, error) { return nil, fmt.Errorf("server mod handler err") } -func SendMessage(m1 *msg.Msg) error { - if m1.SendT == 0 { - m1.SendT = GoUtil.Now() - } - m := m1.Clone() - err := SendMsgToCenter(m) - if err != nil { // 区服不在线 - G_GameLogicPtr.FriendMgrSend(m) - return err - } - return nil -} - // 异步处理消息 (多线程版本) func (m *MessageMgr) MessageHandleAsync(message *msg.Msg) error { if fun, ok := m.handler[message.HandleType]; ok { @@ -270,19 +285,6 @@ func (m *MessageMgr) MessageHandleAsync(message *msg.Msg) error { // 兼容旧版本的函数 func MessageHandle(m *msg.Msg) error { log.Debug("RecvMessage m %v", m) - SendMsgToCenter(&msg.Msg{ - From: 10000, - Extra: conf.Server.ServerID, - HandleType: msg.HANDLE_MOD_PLAYER_LOGIN, - }) - time.Sleep(time.Second) - SendMsgToCenter(&msg.Msg{ - From: 10000, - To: 10000, - Type: msg.HANDLE_TYPE_LOGIN, - Extra: conf.Server.ServerID, - HandleType: msg.HANDLE_MOD_PLAYER_MSG, - }) // 这里可以调用 MessageMgr 的处理方法 G_GameLogicPtr.MessageMgr.MessageHandleAsync(m) return nil @@ -461,26 +463,84 @@ func ValidationMiddleware() MessageMiddleware { } } -func SendMsgToCenter(m *msg.Msg) error { - return mergeCluster.SendServerMsg(m, conf.Server.CenterNode) +// ----------------------------------- 发送消息相关函数 --------------------------- +func SendMsgToCenterAsync(m *msg.Msg) { + go sendMessageAsync(m, conf.Server.CenterNode) } -func CallMsgToCenter(m *msg.Msg) (interface{}, error) { - return mergeCluster.CallServerMsg(m, conf.Server.CenterNode) +func SendMsgToCenterSync(m *msg.Msg) (*msg.Msg, error) { + return sendMessageSync(m, conf.Server.CenterNode) } -func SendMsgToNode(m *msg.Msg, node int) error { - return mergeCluster.SendServerMsg(m, node) +func SendMsgToNodeAsync(m *msg.Msg, node int) { + go sendMessageAsync(m, node) } -func SendPlayerMsg(m *msg.Msg) error { +func SendMsgToNodeSync(m *msg.Msg, node int) (*msg.Msg, error) { + return sendMessageSync(m, node) +} + +func SendPlayerMsgAsync(m *msg.Msg) error { + if m.SendT == 0 { + m.SendT = GoUtil.Now() + } clone := m.Clone() clone.HandleType = msg.HANDLE_MOD_PLAYER_MSG - return mergeCluster.SendServerMsg(m, conf.Server.CenterNode) + SendMsgToCenterAsync(clone) + return nil } -func CallPlayerMsg(m *msg.Msg) (interface{}, error) { +func SendPlayerMsgSync(m *msg.Msg) (interface{}, error) { clone := m.Clone() clone.HandleType = msg.HANDLE_MOD_PLAYER_MSG - return mergeCluster.CallServerMsg(m, conf.Server.CenterNode) + return SendMsgToCenterSync(clone) +} + +func FriendMgrSend(m1 *msg.Msg) error { + SendPlayerMsgAsync(m1) + return nil +} + +// 异步发送消息到指定节点 节点不在线则保存消息 +func sendMessageAsync(m *msg.Msg, node int) error { + err := mergeCluster.SendServerMsg(m, node) + if err != nil { + saveMessage(m) + return err + } + return nil +} + +// 同步消息到指定节点 节点不在线则保存消息 +func sendMessageSync(m *msg.Msg, node int) (*msg.Msg, error) { + msg, err := mergeCluster.CallServerMsg(m, node) + if err != nil { + saveMessage(m) + return nil, err + } + return msg, nil +} + +// 保存消息到本地 +func saveMessage(m *msg.Msg) error { + data := getMessageData() + data.mu.Lock() + defer data.mu.Unlock() + if _, ok := data.MessageList[int64(m.To)]; !ok { + data.MessageList[int64(m.To)] = &MessageList{ + Messages: []*msg.Msg{}, + } + } + data.MessageList[int64(m.To)].mu.Lock() + defer data.MessageList[int64(m.To)].mu.Unlock() + data.MessageList[int64(m.To)].Messages = append(data.MessageList[int64(m.To)].Messages, m) + return nil +} + +func GetUserData(PlayerId int64, Key string) (*msg.Msg, error) { + return SendMsgToCenterSync(&msg.Msg{ + From: int(PlayerId), + HandleType: msg.HANDLE_MOD_VAR_GET, + Extra: Key, + }) } diff --git a/src/server/game/mod/msg/Msg.go b/src/server/game/mod/msg/Msg.go index 0e77e043..533172d4 100644 --- a/src/server/game/mod/msg/Msg.go +++ b/src/server/game/mod/msg/Msg.go @@ -16,16 +16,31 @@ type Msg struct { HandleType int //处理类型 } +type VarData struct { + Key string + Value interface{} + SetType int // 操作类型 0 设置 1 增加 2 减少 3 覆盖 +} + +const ( + VAR_OP_ADD = 1 + VAR_OP_SUB = 2 + VAR_OP_SET = 3 +) + var MSG_ZERO_UPDATE = &Msg{Type: SERVER_ZERO_UPDATE} var MSG_NOON_UPDATE = &Msg{Type: SERVER_NOON_UPDATE} const ( - HANDLE_MOD_PLAYER_MSG = 20001 // 玩家消息 - HANDLE_MOD_CLUSTER_MSG = 20002 // 集群消息 - HANDLE_MOD_PLAYER_LOGIN = 20003 // 玩家登录消息 - HANDLE_MOD_COMSUME_MSG = 20004 // 消费消息 - HANDLE_MOD_CLUSTER_SYNC = 20005 // 集群同步消息 - HANDLE_MDO_PLAYER_LOGOUT = 20006 // 玩家登出消息 + HANDLE_MOD_PLAYER_MSG = 20001 // 玩家消息 + HANDLE_MOD_CLUSTER_MSG = 20002 // 集群消息 + HANDLE_MOD_PLAYER_LOGIN = 20003 // 玩家登录消息 + HANDLE_MOD_COMSUME_MSG = 20004 // 消费消息 + HANDLE_MOD_CLUSTER_SYNC = 20005 // 集群同步消息 + HANDLE_MDO_PLAYER_LOGOUT = 20006 // 玩家登出消息 + HANDLE_MOD_VAR_GET = 20007 // 获取变量 + HANDLE_MOD_VAR_SET = 20008 // 设置变量 + HANDLE_MOD_CATNIP_PARTNER = 20009 // 猫薄荷伙伴 ) const ( diff --git a/src/server/game/player_data.go b/src/server/game/player_data.go index 2baf0277..6901c65f 100644 --- a/src/server/game/player_data.go +++ b/src/server/game/player_data.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "math" + "server/conf" activityCfg "server/conf/activity" cardCfg "server/conf/card" chargeCfg "server/conf/charge" @@ -253,7 +254,6 @@ func (p *Player) InitPlayer(UserName string) error { p.NoonUpdate(nil) p.Login() p.OrderShip() - p.SyncFriendMsg() p.UpdateUserInfo() // fix bug ChargeMod := p.PlayMod.getChargeMod() @@ -452,11 +452,16 @@ func (p *Player) ClearData() { log.Debug("ClearData BeginTx failed:", err) return } + Uid := int(p.M_DwUin) p.PlayerBaseMod.ClearData() p.PlayMod.ClearData(p) tx.Commit() p.Stop() G_GameLogicPtr.DelPlayer(p) + SendMsgToCenterAsync(&MsgMod.Msg{ + From: Uid, + HandleType: MsgMod.HANDLE_MDO_PLAYER_LOGOUT, + }) } func (p *Player) AutoSaveData() { @@ -864,6 +869,11 @@ func (p *Player) HandleItem(itemList []*item.Item, Label string) error { // 登录返回数据 func (p *Player) LoginBackData() { + SendMsgToCenterAsync(&MsgMod.Msg{ + From: int(p.M_DwUin), + HandleType: MsgMod.HANDLE_MOD_PLAYER_LOGIN, + Extra: conf.Server.ServerID, + }) p.PushClientRes(p.PlayMod.mod_list.Base.BackData()) p.PushClientRes(p.PlayMod.mod_list.Handbook.BackData()) p.PushClientRes(p.PlayMod.mod_list.Base.BackData()) diff --git a/src/server/game/register_network_func.go b/src/server/game/register_network_func.go index 30b48549..adf30f16 100644 --- a/src/server/game/register_network_func.go +++ b/src/server/game/register_network_func.go @@ -60,6 +60,7 @@ func ReqPlayerBaseInfofunction(player *Player, buf []byte) error { } func ReqPlayerBriefProfileDataFunc(player *Player, buf []byte) error { + return nil detail := &msg.ReqPlayerBriefProfileData{} err := proto.Unmarshal(buf, detail) if err != nil { @@ -1785,15 +1786,14 @@ func ReqLimitSenceReward(player *Player, buf []byte) error { } func ReqGetGoldCard(player *Player, buf []byte) error { - data := G_GameLogicPtr.VarMgr.GetVar(VAR_GOLD_CARD) - if data == nil { + gold := player.GetGoldCard() + if gold == nil { player.SendErrClienRes(&msg.ResGetGoldCard{ Four: 0, Five: 0, }) return fmt.Errorf("not exist") } - gold := data.(*VarGoldCard) player.PushClientRes(&msg.ResGetGoldCard{ Four: int32(gold.Four), Five: int32(gold.Five), @@ -1870,13 +1870,13 @@ func ReqApplyFriend(player *Player, buf []byte) error { }) return fmt.Errorf("already friend") } - if FriendMod.AddSendApply(Uid) { - player.SendErrClienRes(&msg.ResApplyFriend{ - Code: msg.RES_CODE_FAIL, - Msg: "already apply", - }) - return fmt.Errorf("already apply") - } + // if FriendMod.AddSendApply(Uid) { + // player.SendErrClienRes(&msg.ResApplyFriend{ + // Code: msg.RES_CODE_FAIL, + // Msg: "already apply", + // }) + // return fmt.Errorf("already apply") + // } if req.Type == 1 { Items, err := FriendMod.GetSponsorReward() if err != nil { @@ -3943,7 +3943,7 @@ func ReqPlayroomSelectReward(player *Player, buf []byte) error { if LimitedTimeEventMod.CheckExist(limitedTimeEvent.EVENT_TYPE_PET_THIEF) { player.GetPetThiefReward(Target) } - G_GameLogicPtr.SetUserData(Target, VAR_OP_CHIP, 1) + player.AddPlayroomChip(int(req.Id)) player.TeLog("finish_mini_game", map[string]interface{}{ "mini_game_type": PlayroomMod.GetGameId(), "is_chip": true, @@ -4083,8 +4083,9 @@ func ReqPlayroomChip(player *Player, buf []byte) error { player.TeLog("remove_chip", map[string]interface{}{ "remove_chip_number": ChipNum, }) - - G_GameLogicPtr.SetUserData(int(player.M_DwUin), VAR_OP_CHIP_SET, len(PlayroomMod.ChipList)) + for range ChipNum { + player.SubPlayroomChip(int(player.M_DwUin)) + } player.PlayMod.save() player.PlayroomBackData() player.PushClientRes(&msg.ResPlayroomChip{ @@ -4258,8 +4259,8 @@ func ReqPlayroomUpvote(player *Player, buf []byte) error { Type: MsqMod.HANDLE_TYPE_PLAYROOM_KISS, SendT: GoUtil.Now(), }) - G_GameLogicPtr.SetUserData(int(req.Id), VAR_OP_UPVOTE, 1) - G_GameLogicPtr.SetUserData(int(req.Id), VAR_OP_KISS, 1) + player.AddPlayroomUpvote(int(req.Id)) + player.SetPlayroomKiss(int(req.Id)) player.TeLog("visit_like", map[string]interface{}{ "user_id": req.Id, }) @@ -5449,7 +5450,7 @@ func ReqCatnipAgree(player *Player, buf []byte) error { }) return err } - err = G_GameLogicPtr.SetCatnipPartner(int(player.M_DwUin), int(req.Id), int(req.Uid), ActivityInfo.EndT) + err = player.SetCatnipPartner(int(req.Id), int(req.Uid), ActivityInfo.EndT) if err != nil { player.SendErrClienRes(&msg.ResCatnipAgree{ Code: msg.RES_CODE_FAIL, @@ -5769,7 +5770,7 @@ func ReqFriendReplyHandle(player *Player, buf []byte) error { case friend.REPLY_TYPE_CATNIP: // 猫草大作战同意邀请 GameId := GoUtil.Int(ReplyInfo.Param) activityInfo := player.GetActivityInfo(player.GetActivityId(activity.ACT_TYPE_CATNIP)) - err := G_GameLogicPtr.SetCatnipPartner(int(player.M_DwUin), GameId, ReplyInfo.Uid, activityInfo.EndT) + err := player.SetCatnipPartner(GameId, ReplyInfo.Uid, activityInfo.EndT) if err == nil { CatnipMod := player.PlayMod.getCatnipMod() ActivityId := player.GetActivityId(activity.ACT_TYPE_MINING) diff --git a/src/server/game/var.go b/src/server/game/var.go new file mode 100644 index 00000000..13445ef2 --- /dev/null +++ b/src/server/game/var.go @@ -0,0 +1,73 @@ +package game + +import ( + "server/game/mod/msg" + GoUtil "server/game_util" + "server/pkg/github.com/name5566/leaf/log" +) + +const ( + VAR_KEY_FRIEND_MSG = "friend_msg" // 好友消息 + VAR_GOLD_CARD = "gold_card" + VAR_PLAYROOM_UPVOTE = "playroom_upvote" + VAR_PLAYROOM_CHIP = "playroom_chip" + VAR_PLAYROOM_KISS = "playroom_kiss" + VAR_USER_DATA = "user_data" +) + +func (p *Player) GetVarData(key string) interface{} { + data, err := GetUserData(p.M_DwUin, key) + if err != nil { + log.Error("GetVarData err : %s", err) + return nil + } + return data.Extra +} + +func (p *Player) OpVarDataAsync(key string, value interface{}, opType int) { + SendMsgToCenterAsync(&msg.Msg{ + From: int(p.M_DwUin), + HandleType: msg.HANDLE_MOD_VAR_SET, + Extra: &msg.VarData{ + Key: key, + Value: value, + SetType: opType, + }, + }) +} + +func (p *Player) SetVarDataAsync(key string, value interface{}) { + p.OpVarDataAsync(key, value, msg.VAR_OP_SET) +} + +func (p *Player) AddVarDataAsync(key string) { + p.OpVarDataAsync(key, nil, msg.VAR_OP_ADD) +} + +func (p *Player) SubVarDataAsync(key string) { + p.OpVarDataAsync(key, nil, msg.VAR_OP_SUB) +} + +func (p *Player) AddPlayroomUpvote(PlayerId int) { + p.AddVarDataAsync(GoUtil.GetUserVarKey(PlayerId, VAR_PLAYROOM_UPVOTE)) +} + +func (p *Player) AddPlayroomChip(PlayerId int) { + p.AddVarDataAsync(GoUtil.GetUserVarKey(PlayerId, VAR_PLAYROOM_CHIP)) +} + +func (p *Player) SubPlayroomChip(PlayerId int) { + p.SubVarDataAsync(GoUtil.GetUserVarKey(PlayerId, VAR_PLAYROOM_CHIP)) +} + +func (p *Player) SetPlayroomKiss(PlayerId int) { + p.SetVarDataAsync(GoUtil.GetUserVarKey(PlayerId, VAR_PLAYROOM_KISS), 1) +} + +func (p *Player) GetGoldCard() *VarGoldCard { + data := p.GetVarData(VAR_GOLD_CARD) + if data == nil { + return &VarGoldCard{} + } + return data.(*VarGoldCard) +} diff --git a/src/server/game/var_mgr.go b/src/server/game/var_mgr.go index a228b5fd..5d45337e 100644 --- a/src/server/game/var_mgr.go +++ b/src/server/game/var_mgr.go @@ -6,6 +6,8 @@ import ( "server/game/mod/card" "server/game/mod/msg" GoUtil "server/game_util" + "strings" + "sync" "time" ) @@ -14,18 +16,14 @@ type VarMgr struct { } type VarData struct { - Var map[string]interface{} + Var map[string]*VarExpireData VarExpire map[string]*VarExpireData UserVar map[string]*VarUserData ZeroTime int64 + Version int64 + mu sync.Mutex } -const ( - VAR_GOLD_CARD = "gold_card" - VAR_PLAYROOM_UPVOTE = "playroom_upvote" - VAR_USER_DATA = "user_data" -) - const ( VAR_OP_UPVOTE = 1 VAR_OP_CHIP = 2 @@ -38,12 +36,14 @@ func (f *VarMgr) Init() { gob.Register(&VarGoldCard{}) f.key = VAR_MGR_KEY f.data = &VarData{ - Var: map[string]interface{}{}, + Var: map[string]*VarExpireData{}, } // 注册处理函数 f.init() + // 版本更新 重构 + f.version() if f.data.(*VarData).Var == nil { - f.data.(*VarData).Var = make(map[string]interface{}) + f.data.(*VarData).Var = make(map[string]*VarExpireData) } if f.data.(*VarData).UserVar == nil { f.data.(*VarData).UserVar = make(map[string]*VarUserData) @@ -52,23 +52,37 @@ func (f *VarMgr) Init() { f.data.(*VarData).VarExpire = make(map[string]*VarExpireData) } if f.getData().ZeroTime == GoUtil.ZeroTimestamp() { - f.ZeroUpdate(&msg.Msg{}) + f.ZeroUpdate() } - f.RegisterHandler(msg.SERVER_ZERO_UPDATE, f.ZeroUpdate) - f.RegisterHandler(msg.HANDLE_TYPE_SET_CATNIP_PARTNER, f.SetCatnipPartner) f.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() { - f.Send(&msg.Msg{ - Type: msg.SERVER_ZERO_UPDATE, - }) + f.ZeroUpdate() }) } -func (f *VarMgr) SetGlobalData(m *msg.Msg) (interface{}, error) { - return nil, nil +func (f *VarMgr) version() { + switch v := f.getData().Version; v { + case 0: + // future version update + data := f.getData() + data.mu.Lock() + defer data.mu.Unlock() + // set to next version + for k, v := range data.UserVar { + if v != nil { + uidStr := strings.Split(k, "_")[2] + uid := GoUtil.Int(uidStr) + f.SetVar(GoUtil.GetUserVarKey(uid, VAR_PLAYROOM_UPVOTE), v.Upvote) + f.SetVar(GoUtil.GetUserVarKey(uid, VAR_PLAYROOM_CHIP), v.Chip) + f.SetVar(GoUtil.GetUserVarKey(uid, VAR_PLAYROOM_KISS), v.Kiss) + delete(data.UserVar, k) + } + } + f.getData().Version = 1 + } } -func (f *VarMgr) ZeroUpdate(m *msg.Msg) (interface{}, error) { +func (f *VarMgr) ZeroUpdate() { f.getData().ZeroTime = GoUtil.ZeroTimestamp() // 随机生成两个金卡 Card1, Card2 := card.RankGoldCard() @@ -76,53 +90,44 @@ func (f *VarMgr) ZeroUpdate(m *msg.Msg) (interface{}, error) { Four: Card1, Five: Card2, }) - for k, v := range f.getData().VarExpire { + for k, v := range f.getData().Var { if v.T < GoUtil.ZeroTimestamp() { - delete(f.getData().VarExpire, k) + delete(f.getData().Var, k) } } + f.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() { + f.ZeroUpdate() + }) +} + +func (f *VarMgr) HandleCatnipPartner(Uid, Partner, GameId int, EndTime int64) (interface{}, error) { + myKey := fmt.Sprintf("catnip_partner_%d", Uid) + key := fmt.Sprintf("catnip_partner_%d", Partner) + OtherPartnerInfo := f.GetExpireVar(key) + MyPartnerInfo := f.GetExpireVar(myKey) + MyOfPartnerList := GoUtil.IntSlice(MyPartnerInfo.D) + OtherOfPartnerList := GoUtil.IntSlice(OtherPartnerInfo.D) + if len(MyOfPartnerList) > 4 || len(OtherOfPartnerList) > 4 { + return nil, fmt.Errorf("catnip partner already full for uid %d in game %d", Partner, GameId) + } + f.SetVar(key, &VarExpireData{ + D: append(OtherOfPartnerList, Uid), + T: EndTime, + }) + f.SetVar(myKey, &VarExpireData{ + D: append(MyOfPartnerList, Partner), + T: EndTime, + }) return nil, nil } -func (f *VarMgr) SetCatnipPartner(m *msg.Msg) (interface{}, error) { - if Param, ok := m.Extra.(map[string]interface{}); ok { - MyUid := GoUtil.Int(Param["uid"]) - CatnipGameId := GoUtil.Int(Param["game_id"]) - CatnipPartnerId := GoUtil.Int(Param["partner_uid"]) - myKey := fmt.Sprintf("catnip_partner_%d", MyUid) - key := fmt.Sprintf("catnip_partner_%d", CatnipPartnerId) - OtherPartnerInfo := f.GetExpireVar(key) - MyPartnerInfo := f.GetExpireVar(myKey) - MyOfPartnerList := GoUtil.IntSlice(MyPartnerInfo.D) - OtherOfPartnerList := GoUtil.IntSlice(OtherPartnerInfo.D) - if len(MyOfPartnerList) > 4 || len(OtherOfPartnerList) > 4 { - return nil, fmt.Errorf("catnip partner already full for uid %d in game %d", CatnipPartnerId, CatnipGameId) - } - f.SetExpireVar(key, &VarExpireData{ - D: append(OtherOfPartnerList, MyUid), - T: m.End, - }) - f.SetExpireVar(myKey, &VarExpireData{ - D: append(MyOfPartnerList, CatnipPartnerId), - T: m.End, - }) - return nil, nil - } - return nil, fmt.Errorf("invalid parameters for setting catnip partner") -} - func (f *VarMgr) SetVar(key string, value interface{}) { - f.getData().Var[key] = value -} - -func (f *VarMgr) GetVar(key string) interface{} { - return f.getData().Var[key] -} - -func (f *VarMgr) SetExpireVar(key string, value *VarExpireData) { - f.getData().VarExpire[key] = value + f.getData().Var[key] = &VarExpireData{ + D: value, + } } +// TODO: 弃用 func (f *VarMgr) GetExpireVar(key string) *VarExpireData { if v, ok := f.getData().VarExpire[key]; ok { return v @@ -132,10 +137,12 @@ func (f *VarMgr) GetExpireVar(key string) *VarExpireData { return data } +// TODO: 弃用 func (f *VarMgr) SetUserVar(key string, value *VarUserData) { f.getData().UserVar[key] = value } +// TODO: 弃用 func (f *VarMgr) GetUserVar(key string) *VarUserData { if v, ok := f.getData().UserVar[key]; ok { return v @@ -152,3 +159,56 @@ func (f *VarMgr) DelVar(key string) { func (f *VarMgr) getData() *VarData { return f.data.(*VarData) } + +func getVarData() *VarData { + return G_GameLogicPtr.VarMgr.getData() +} + +func SetVarDataHandler(m *msg.Msg) (interface{}, error) { + data := getVarData() + data.mu.Lock() + defer data.mu.Unlock() + if v, ok := m.Extra.(*msg.VarData); ok { + ved, ok := data.Var[v.Key] + if !ok { + ved = &VarExpireData{} + } + switch v.SetType { + case msg.VAR_OP_SET: + ved.D = v.Value + case msg.VAR_OP_ADD: + if num, ok := ved.D.(int); ok { + ved.D = num + 1 + } else { + ved.D = 1 + } + case msg.VAR_OP_SUB: + if num, ok := ved.D.(int); ok { + if num > 0 { + ved.D = num - 1 + } else { + ved.D = 0 + } + } else { + ved.D = 0 + } + } + ved.U = time.Now().Unix() + if m.End > 0 { + ved.T = m.End + } + data.Var[v.Key] = ved + } + return nil, nil +} + +func GetVarDataHandler(m *msg.Msg) (interface{}, error) { + data := getVarData() + if v, ok := m.Extra.(*msg.VarData); ok { + if varData, ok := data.Var[v.Key]; ok { + return varData.D, nil + } + return nil, fmt.Errorf("var data not found for key %s", v.Key) + } + return nil, fmt.Errorf("invalid parameters for getting var data") +} diff --git a/src/server/game_util/GoUtil.go b/src/server/game_util/GoUtil.go index b5ca11dd..197f81e1 100644 --- a/src/server/game_util/GoUtil.go +++ b/src/server/game_util/GoUtil.go @@ -304,6 +304,10 @@ func GetUserKey(Uid int64) string { return fmt.Sprintf("user_data_%d", Uid) } +func GetUserVarKey(Uid int, key string) string { + return fmt.Sprintf("%s_%d", key, Uid) +} + func GetCatnipLockKey(Uid, GameId int) string { return fmt.Sprintf("catnip_lock_%d_%d", Uid, GameId) }