This commit is contained in:
hahwu 2025-12-22 16:10:03 +08:00
parent d16e2b3e25
commit 408bd4df5b
13 changed files with 397 additions and 284 deletions

View File

@ -52,6 +52,7 @@ func HandShakeRecv(a *Agent, m *msg.Msg) error {
syncMsg := &msg.Msg{ syncMsg := &msg.Msg{
Type: msg.CLUSTER_FRIEND_SYNC, Type: msg.CLUSTER_FRIEND_SYNC,
To: ServerId, To: ServerId,
HandleType: msg.HANDLE_MOD_CLUSTER_SYNC,
} }
sendGameMsg(syncMsg) sendGameMsg(syncMsg)
} }
@ -96,7 +97,7 @@ func connectRemote(RemoteAddr string, ConnType int, ConnLabel string) error {
client.NewAgent = newAgent client.NewAgent = newAgent
client.ConnType = ConnType client.ConnType = ConnType
client.ConnLabel = ConnLabel client.ConnLabel = ConnLabel
client.ConnectInterval = time.Duration(time.Minute * 5) client.ConnectInterval = time.Duration(time.Minute * 1)
if ConnType == ClusterCenterId { // 中心服断开重连 if ConnType == ClusterCenterId { // 中心服断开重连
client.AutoReconnect = true client.AutoReconnect = true
} }
@ -126,23 +127,21 @@ func CallServerMsg(m *msg.Msg, serverId int) (*msg.Msg, error) {
if m.UniKey == "" { if m.UniKey == "" {
m.UniKey = GoUtil.UniKey(fmt.Sprintf("%v,Cluster Msg", m)) 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) newChan := make(chan *msg.Msg, 1)
registerChanel(m.UniKey, newChan) registerChanel(m.UniKey, newChan)
defer unregisterChanel(m.UniKey) defer unregisterChanel(m.UniKey)
// 之后再发送消息
if v, ok := serverAgent.Load(serverId); ok {
data, err := GoUtil.GobMarshal(m) data, err := GoUtil.GobMarshal(m)
if err != nil { if err != nil {
log.Debug("CallServerMsg GobMarshal err %v", err) log.Debug("CallServerMsg GobMarshal err %v", err)
return nil, err return nil, err
} }
v.(network.Agent).WriteMsg(data) v.(network.Agent).WriteMsg(data)
} else {
return nil, fmt.Errorf("server %d not online", serverId)
}
// 等待返回(直接接收一次) // 等待返回(直接接收一次)
timeout := time.After(15 * time.Second) timeout := time.After(15 * time.Second)
select { select {

View File

@ -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 { func (ad *GameLogic) GetUserData(Uid int) *VarUserData {
result, err := ad.FriendMgr.Call(&MsgMod.Msg{ result, err := ad.FriendMgr.Call(&MsgMod.Msg{
From: Uid, From: Uid,
@ -665,7 +638,6 @@ func (ad *GameLogic) ReplaceExistPlayerAndAgent(a gate.Agent, player *Player) er
if ok { if ok {
Timer.Stop() Timer.Stop()
} }
player.SyncFriendMsg()
log.Debug("player %d 重连", player.M_DwUin) log.Debug("player %d 重连", player.M_DwUin)
return nil return nil
} }

View File

@ -417,14 +417,3 @@ func (p *Player) CatnipBackData() {
} }
p.PushClientRes(res) 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), // 锁
})
}

View File

@ -45,7 +45,6 @@ func (f *FriendMgr) Init() {
f.RegisterHandler(msg.HANDLE_TYPE_APPLY, f.sendToPlayer) f.RegisterHandler(msg.HANDLE_TYPE_APPLY, f.sendToPlayer)
f.RegisterHandler(msg.HADNLE_TYPE_AGREE, f.sendToPlayer) f.RegisterHandler(msg.HADNLE_TYPE_AGREE, f.sendToPlayer)
f.RegisterHandler(msg.HANDLE_TYPE_DEL, 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_REFUSE, f.sendToPlayer)
f.RegisterHandler(msg.HANDLE_TYPE_INVITE_ADD_FRIEND, f.sendToPlayer) f.RegisterHandler(msg.HANDLE_TYPE_INVITE_ADD_FRIEND, f.sendToPlayer)
f.RegisterHandler(msg.HANDLE_TYPE_INVITE_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_GET, f.GetVarUserData)
f.RegisterHandler(msg.HANDLE_TYPE_VAR_USER_SET, f.SetVarUserData) 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_LOGIN, f.SendMsgToCenter)
f.RegisterHandler(msg.HANDLE_TYPE_CHAMPSHIP_INRANK, 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 }, 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 { func sendToPlayer(m *msg.Msg) error {
p := G_GameLogicPtr.GetPlayer(int64(m.To)) p := G_GameLogicPtr.GetPlayer(int64(m.To))
@ -222,24 +191,6 @@ func sendToPlayerOnline(m *msg.Msg) error {
return nil 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 { func ClusterFriendSync(m *msg.Msg) error {
if v, ok := G_GameLogicPtr.FriendMgr.getData().ClusterMsg[m.To]; ok { 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) { func (f *FriendMgr) CallMsgToCenter(m *msg.Msg) (interface{}, error) {
return mergeCluster.CallServerMsg(m, conf.Server.CenterNode) 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())
}

View File

@ -55,7 +55,16 @@ type VarUserData struct {
type VarExpireData struct { type VarExpireData struct {
D interface{} D interface{}
T int64 T int64 // 过期时间戳
U int64 // 最后更新时间
mu sync.Mutex
}
type CatnipPartner struct {
Uid int
Partner int
GameId int
EndTime int64
} }
const ( const (

View File

@ -509,38 +509,6 @@ func (p *Player) handle(m *msg.Msg) error {
return nil 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) { func SyncMailMsg(p *Player) {
ServerMailList := G_GameLogicPtr.MailMgr.Sync(int(p.M_DwUin), p.GetPlayerBaseMod().GetRegisterTime()) ServerMailList := G_GameLogicPtr.MailMgr.Sync(int(p.M_DwUin), p.GetPlayerBaseMod().GetRegisterTime())
MailMod := p.PlayMod.getMailMod() MailMod := p.PlayMod.getMailMod()
@ -1302,3 +1270,18 @@ func (player *Player) IsWeeklyDiscount() bool {
LimitEventMod := player.PlayMod.getLimitedTimeEventMod() LimitEventMod := player.PlayMod.getLimitedTimeEventMod()
return ChargeMod.IsWeeklyDiscountDay() || LimitEventMod.CheckExist(limitedTimeEvent.EVENT_TYPE_CAT_DAY_SALE) 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
}

View File

@ -78,8 +78,10 @@ func (m *MessageMgr) MessageMgrInit() {
m.RegisterHandler(msg.HANDLE_MDO_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_PLAYER_MSG, MessageHandlerFunc(CenterPlayerMsgHandler))
m.RegisterHandler(msg.HANDLE_MOD_COMSUME_MSG, MessageHandlerFunc(ComsumerMsgHandler)) m.RegisterHandler(msg.HANDLE_MOD_COMSUME_MSG, MessageHandlerFunc(ComsumerMsgHandler))
m.RegisterHandler(msg.HANDLE_MOD_VAR_SET, MessageHandlerFunc(SetVarDataHandler))
} else { } else {
m.RegisterHandler(msg.HANDLE_MOD_PLAYER_MSG, MessageHandlerFunc(PlayerMsgHandler)) 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 s.handler[HandlerType] = fun
} }
func getData() *MessageData { func getMessageData() *MessageData {
return G_GameLogicPtr.MessageMgr.data.(*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) { func PlayerLoginHandler(data *msg.Msg) (interface{}, error) {
// 关闭 Worker Pool // 关闭 Worker Pool
messageMgrData := getData() messageMgrData := getMessageData()
messageMgrData.mu.Lock() messageMgrData.mu.Lock()
defer messageMgrData.mu.Unlock() defer messageMgrData.mu.Unlock()
messageMgrData.PlayerList[int64(data.From)] = data.Extra.(int) messageMgrData.PlayerList[int64(data.From)] = data.Extra.(int)
@ -112,16 +149,13 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) {
messages.mu.Lock() messages.mu.Lock()
defer messages.mu.Unlock() defer messages.mu.Unlock()
for _, message := range messages.Messages { for _, message := range messages.Messages {
err := SendMsgToNode(message, node) go sendMessageAsync(message, node)
if err != nil {
log.Error("Failed to send message to player %d: %v", data.From, err)
}
} }
return nil, nil return nil, nil
} }
func PlayerLogoutHandler(data *msg.Msg) (interface{}, error) { func PlayerLogoutHandler(data *msg.Msg) (interface{}, error) {
messageMgrData := getData() messageMgrData := getMessageData()
messageMgrData.mu.Lock() messageMgrData.mu.Lock()
defer messageMgrData.mu.Unlock() defer messageMgrData.mu.Unlock()
delete(messageMgrData.PlayerList, int64(data.From)) delete(messageMgrData.PlayerList, int64(data.From))
@ -130,8 +164,8 @@ func PlayerLogoutHandler(data *msg.Msg) (interface{}, error) {
} }
func ComsumerMsgHandler(data *msg.Msg) (interface{}, error) { func ComsumerMsgHandler(data *msg.Msg) (interface{}, error) {
messageMgrData := getData() messageMgrData := getMessageData()
Message, ok := messageMgrData.MessageList[int64(data.To)] Message, ok := messageMgrData.MessageList[int64(data.From)]
if !ok { if !ok {
return nil, nil return nil, nil
} }
@ -150,7 +184,7 @@ func ComsumerMsgHandler(data *msg.Msg) (interface{}, error) {
func CenterPlayerMsgHandler(data *msg.Msg) (interface{}, error) { func CenterPlayerMsgHandler(data *msg.Msg) (interface{}, error) {
PlayerId := int64(data.To) PlayerId := int64(data.To)
messageMgrData := getData() messageMgrData := getMessageData()
// 遍历消息列表,发送消息给在线玩家 // 遍历消息列表,发送消息给在线玩家
messages, ok := messageMgrData.MessageList[int64(PlayerId)] messages, ok := messageMgrData.MessageList[int64(PlayerId)]
if !ok { if !ok {
@ -166,10 +200,7 @@ func CenterPlayerMsgHandler(data *msg.Msg) (interface{}, error) {
messages.Messages = append(messages.Messages, data) messages.Messages = append(messages.Messages, data)
if node, ok := messageMgrData.PlayerList[int64(PlayerId)]; ok { if node, ok := messageMgrData.PlayerList[int64(PlayerId)]; ok {
for _, message := range messages.Messages { for _, message := range messages.Messages {
err := SendMsgToNode(message, node) go SendMsgToNodeAsync(message, node)
if err != nil {
log.Error("Failed to send message to player %d: %v", PlayerId, err)
}
} }
} }
return nil, nil return nil, nil
@ -179,9 +210,6 @@ func PlayerMsgHandler(data *msg.Msg) (interface{}, error) {
p := G_GameLogicPtr.GetPlayer(int64(data.To)) p := G_GameLogicPtr.GetPlayer(int64(data.To))
// 不在线 不处理 // 不在线 不处理
if p == nil || p.stop { if p == nil || p.stop {
// TODO: 模拟消费
data.HandleType = msg.HANDLE_MOD_COMSUME_MSG
go SendMsgToCenter(data)
return nil, nil return nil, nil
} }
p.lock.Lock() p.lock.Lock()
@ -189,7 +217,7 @@ func PlayerMsgHandler(data *msg.Msg) (interface{}, error) {
p.Send(data.Clone()) p.Send(data.Clone())
// 处理完后发送消费消息 // 处理完后发送消费消息
data.HandleType = msg.HANDLE_MOD_COMSUME_MSG data.HandleType = msg.HANDLE_MOD_COMSUME_MSG
go SendMsgToCenter(data) go SendMsgToCenterAsync(data)
return nil, nil return nil, nil
} }
@ -221,19 +249,6 @@ func (m *MessageMgr) Handle(msg *msg.Msg) (interface{}, error) {
return nil, fmt.Errorf("server mod handler err") 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 { func (m *MessageMgr) MessageHandleAsync(message *msg.Msg) error {
if fun, ok := m.handler[message.HandleType]; ok { 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 { func MessageHandle(m *msg.Msg) error {
log.Debug("RecvMessage m %v", m) 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 的处理方法 // 这里可以调用 MessageMgr 的处理方法
G_GameLogicPtr.MessageMgr.MessageHandleAsync(m) G_GameLogicPtr.MessageMgr.MessageHandleAsync(m)
return nil 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) { func SendMsgToCenterSync(m *msg.Msg) (*msg.Msg, error) {
return mergeCluster.CallServerMsg(m, conf.Server.CenterNode) return sendMessageSync(m, conf.Server.CenterNode)
} }
func SendMsgToNode(m *msg.Msg, node int) error { func SendMsgToNodeAsync(m *msg.Msg, node int) {
return mergeCluster.SendServerMsg(m, node) 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 := m.Clone()
clone.HandleType = msg.HANDLE_MOD_PLAYER_MSG 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 := m.Clone()
clone.HandleType = msg.HANDLE_MOD_PLAYER_MSG 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,
})
} }

View File

@ -16,6 +16,18 @@ type Msg struct {
HandleType int //处理类型 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_ZERO_UPDATE = &Msg{Type: SERVER_ZERO_UPDATE}
var MSG_NOON_UPDATE = &Msg{Type: SERVER_NOON_UPDATE} var MSG_NOON_UPDATE = &Msg{Type: SERVER_NOON_UPDATE}
@ -26,6 +38,9 @@ const (
HANDLE_MOD_COMSUME_MSG = 20004 // 消费消息 HANDLE_MOD_COMSUME_MSG = 20004 // 消费消息
HANDLE_MOD_CLUSTER_SYNC = 20005 // 集群同步消息 HANDLE_MOD_CLUSTER_SYNC = 20005 // 集群同步消息
HANDLE_MDO_PLAYER_LOGOUT = 20006 // 玩家登出消息 HANDLE_MDO_PLAYER_LOGOUT = 20006 // 玩家登出消息
HANDLE_MOD_VAR_GET = 20007 // 获取变量
HANDLE_MOD_VAR_SET = 20008 // 设置变量
HANDLE_MOD_CATNIP_PARTNER = 20009 // 猫薄荷伙伴
) )
const ( const (

View File

@ -6,6 +6,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"math" "math"
"server/conf"
activityCfg "server/conf/activity" activityCfg "server/conf/activity"
cardCfg "server/conf/card" cardCfg "server/conf/card"
chargeCfg "server/conf/charge" chargeCfg "server/conf/charge"
@ -253,7 +254,6 @@ func (p *Player) InitPlayer(UserName string) error {
p.NoonUpdate(nil) p.NoonUpdate(nil)
p.Login() p.Login()
p.OrderShip() p.OrderShip()
p.SyncFriendMsg()
p.UpdateUserInfo() p.UpdateUserInfo()
// fix bug // fix bug
ChargeMod := p.PlayMod.getChargeMod() ChargeMod := p.PlayMod.getChargeMod()
@ -452,11 +452,16 @@ func (p *Player) ClearData() {
log.Debug("ClearData BeginTx failed:", err) log.Debug("ClearData BeginTx failed:", err)
return return
} }
Uid := int(p.M_DwUin)
p.PlayerBaseMod.ClearData() p.PlayerBaseMod.ClearData()
p.PlayMod.ClearData(p) p.PlayMod.ClearData(p)
tx.Commit() tx.Commit()
p.Stop() p.Stop()
G_GameLogicPtr.DelPlayer(p) G_GameLogicPtr.DelPlayer(p)
SendMsgToCenterAsync(&MsgMod.Msg{
From: Uid,
HandleType: MsgMod.HANDLE_MDO_PLAYER_LOGOUT,
})
} }
func (p *Player) AutoSaveData() { func (p *Player) AutoSaveData() {
@ -864,6 +869,11 @@ func (p *Player) HandleItem(itemList []*item.Item, Label string) error {
// 登录返回数据 // 登录返回数据
func (p *Player) LoginBackData() { 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.Base.BackData())
p.PushClientRes(p.PlayMod.mod_list.Handbook.BackData()) p.PushClientRes(p.PlayMod.mod_list.Handbook.BackData())
p.PushClientRes(p.PlayMod.mod_list.Base.BackData()) p.PushClientRes(p.PlayMod.mod_list.Base.BackData())

View File

@ -60,6 +60,7 @@ func ReqPlayerBaseInfofunction(player *Player, buf []byte) error {
} }
func ReqPlayerBriefProfileDataFunc(player *Player, buf []byte) error { func ReqPlayerBriefProfileDataFunc(player *Player, buf []byte) error {
return nil
detail := &msg.ReqPlayerBriefProfileData{} detail := &msg.ReqPlayerBriefProfileData{}
err := proto.Unmarshal(buf, detail) err := proto.Unmarshal(buf, detail)
if err != nil { if err != nil {
@ -1785,15 +1786,14 @@ func ReqLimitSenceReward(player *Player, buf []byte) error {
} }
func ReqGetGoldCard(player *Player, buf []byte) error { func ReqGetGoldCard(player *Player, buf []byte) error {
data := G_GameLogicPtr.VarMgr.GetVar(VAR_GOLD_CARD) gold := player.GetGoldCard()
if data == nil { if gold == nil {
player.SendErrClienRes(&msg.ResGetGoldCard{ player.SendErrClienRes(&msg.ResGetGoldCard{
Four: 0, Four: 0,
Five: 0, Five: 0,
}) })
return fmt.Errorf("not exist") return fmt.Errorf("not exist")
} }
gold := data.(*VarGoldCard)
player.PushClientRes(&msg.ResGetGoldCard{ player.PushClientRes(&msg.ResGetGoldCard{
Four: int32(gold.Four), Four: int32(gold.Four),
Five: int32(gold.Five), Five: int32(gold.Five),
@ -1870,13 +1870,13 @@ func ReqApplyFriend(player *Player, buf []byte) error {
}) })
return fmt.Errorf("already friend") return fmt.Errorf("already friend")
} }
if FriendMod.AddSendApply(Uid) { // if FriendMod.AddSendApply(Uid) {
player.SendErrClienRes(&msg.ResApplyFriend{ // player.SendErrClienRes(&msg.ResApplyFriend{
Code: msg.RES_CODE_FAIL, // Code: msg.RES_CODE_FAIL,
Msg: "already apply", // Msg: "already apply",
}) // })
return fmt.Errorf("already apply") // return fmt.Errorf("already apply")
} // }
if req.Type == 1 { if req.Type == 1 {
Items, err := FriendMod.GetSponsorReward() Items, err := FriendMod.GetSponsorReward()
if err != nil { if err != nil {
@ -3943,7 +3943,7 @@ func ReqPlayroomSelectReward(player *Player, buf []byte) error {
if LimitedTimeEventMod.CheckExist(limitedTimeEvent.EVENT_TYPE_PET_THIEF) { if LimitedTimeEventMod.CheckExist(limitedTimeEvent.EVENT_TYPE_PET_THIEF) {
player.GetPetThiefReward(Target) player.GetPetThiefReward(Target)
} }
G_GameLogicPtr.SetUserData(Target, VAR_OP_CHIP, 1) player.AddPlayroomChip(int(req.Id))
player.TeLog("finish_mini_game", map[string]interface{}{ player.TeLog("finish_mini_game", map[string]interface{}{
"mini_game_type": PlayroomMod.GetGameId(), "mini_game_type": PlayroomMod.GetGameId(),
"is_chip": true, "is_chip": true,
@ -4083,8 +4083,9 @@ func ReqPlayroomChip(player *Player, buf []byte) error {
player.TeLog("remove_chip", map[string]interface{}{ player.TeLog("remove_chip", map[string]interface{}{
"remove_chip_number": ChipNum, "remove_chip_number": ChipNum,
}) })
for range ChipNum {
G_GameLogicPtr.SetUserData(int(player.M_DwUin), VAR_OP_CHIP_SET, len(PlayroomMod.ChipList)) player.SubPlayroomChip(int(player.M_DwUin))
}
player.PlayMod.save() player.PlayMod.save()
player.PlayroomBackData() player.PlayroomBackData()
player.PushClientRes(&msg.ResPlayroomChip{ player.PushClientRes(&msg.ResPlayroomChip{
@ -4258,8 +4259,8 @@ func ReqPlayroomUpvote(player *Player, buf []byte) error {
Type: MsqMod.HANDLE_TYPE_PLAYROOM_KISS, Type: MsqMod.HANDLE_TYPE_PLAYROOM_KISS,
SendT: GoUtil.Now(), SendT: GoUtil.Now(),
}) })
G_GameLogicPtr.SetUserData(int(req.Id), VAR_OP_UPVOTE, 1) player.AddPlayroomUpvote(int(req.Id))
G_GameLogicPtr.SetUserData(int(req.Id), VAR_OP_KISS, 1) player.SetPlayroomKiss(int(req.Id))
player.TeLog("visit_like", map[string]interface{}{ player.TeLog("visit_like", map[string]interface{}{
"user_id": req.Id, "user_id": req.Id,
}) })
@ -5449,7 +5450,7 @@ func ReqCatnipAgree(player *Player, buf []byte) error {
}) })
return err 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 { if err != nil {
player.SendErrClienRes(&msg.ResCatnipAgree{ player.SendErrClienRes(&msg.ResCatnipAgree{
Code: msg.RES_CODE_FAIL, Code: msg.RES_CODE_FAIL,
@ -5769,7 +5770,7 @@ func ReqFriendReplyHandle(player *Player, buf []byte) error {
case friend.REPLY_TYPE_CATNIP: // 猫草大作战同意邀请 case friend.REPLY_TYPE_CATNIP: // 猫草大作战同意邀请
GameId := GoUtil.Int(ReplyInfo.Param) GameId := GoUtil.Int(ReplyInfo.Param)
activityInfo := player.GetActivityInfo(player.GetActivityId(activity.ACT_TYPE_CATNIP)) 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 { if err == nil {
CatnipMod := player.PlayMod.getCatnipMod() CatnipMod := player.PlayMod.getCatnipMod()
ActivityId := player.GetActivityId(activity.ACT_TYPE_MINING) ActivityId := player.GetActivityId(activity.ACT_TYPE_MINING)

73
src/server/game/var.go Normal file
View File

@ -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)
}

View File

@ -6,6 +6,8 @@ import (
"server/game/mod/card" "server/game/mod/card"
"server/game/mod/msg" "server/game/mod/msg"
GoUtil "server/game_util" GoUtil "server/game_util"
"strings"
"sync"
"time" "time"
) )
@ -14,18 +16,14 @@ type VarMgr struct {
} }
type VarData struct { type VarData struct {
Var map[string]interface{} Var map[string]*VarExpireData
VarExpire map[string]*VarExpireData VarExpire map[string]*VarExpireData
UserVar map[string]*VarUserData UserVar map[string]*VarUserData
ZeroTime int64 ZeroTime int64
Version int64
mu sync.Mutex
} }
const (
VAR_GOLD_CARD = "gold_card"
VAR_PLAYROOM_UPVOTE = "playroom_upvote"
VAR_USER_DATA = "user_data"
)
const ( const (
VAR_OP_UPVOTE = 1 VAR_OP_UPVOTE = 1
VAR_OP_CHIP = 2 VAR_OP_CHIP = 2
@ -38,12 +36,14 @@ func (f *VarMgr) Init() {
gob.Register(&VarGoldCard{}) gob.Register(&VarGoldCard{})
f.key = VAR_MGR_KEY f.key = VAR_MGR_KEY
f.data = &VarData{ f.data = &VarData{
Var: map[string]interface{}{}, Var: map[string]*VarExpireData{},
} }
// 注册处理函数 // 注册处理函数
f.init() f.init()
// 版本更新 重构
f.version()
if f.data.(*VarData).Var == nil { 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 { if f.data.(*VarData).UserVar == nil {
f.data.(*VarData).UserVar = make(map[string]*VarUserData) f.data.(*VarData).UserVar = make(map[string]*VarUserData)
@ -52,23 +52,37 @@ func (f *VarMgr) Init() {
f.data.(*VarData).VarExpire = make(map[string]*VarExpireData) f.data.(*VarData).VarExpire = make(map[string]*VarExpireData)
} }
if f.getData().ZeroTime == GoUtil.ZeroTimestamp() { 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.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() {
f.Send(&msg.Msg{ f.ZeroUpdate()
Type: msg.SERVER_ZERO_UPDATE,
})
}) })
} }
func (f *VarMgr) SetGlobalData(m *msg.Msg) (interface{}, error) { func (f *VarMgr) version() {
return nil, nil 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() f.getData().ZeroTime = GoUtil.ZeroTimestamp()
// 随机生成两个金卡 // 随机生成两个金卡
Card1, Card2 := card.RankGoldCard() Card1, Card2 := card.RankGoldCard()
@ -76,53 +90,44 @@ func (f *VarMgr) ZeroUpdate(m *msg.Msg) (interface{}, error) {
Four: Card1, Four: Card1,
Five: Card2, Five: Card2,
}) })
for k, v := range f.getData().VarExpire { for k, v := range f.getData().Var {
if v.T < GoUtil.ZeroTimestamp() { if v.T < GoUtil.ZeroTimestamp() {
delete(f.getData().VarExpire, k) delete(f.getData().Var, k)
} }
} }
return nil, nil f.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() {
f.ZeroUpdate()
})
} }
func (f *VarMgr) SetCatnipPartner(m *msg.Msg) (interface{}, error) { func (f *VarMgr) HandleCatnipPartner(Uid, Partner, GameId int, EndTime int64) (interface{}, error) {
if Param, ok := m.Extra.(map[string]interface{}); ok { myKey := fmt.Sprintf("catnip_partner_%d", Uid)
MyUid := GoUtil.Int(Param["uid"]) key := fmt.Sprintf("catnip_partner_%d", Partner)
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) OtherPartnerInfo := f.GetExpireVar(key)
MyPartnerInfo := f.GetExpireVar(myKey) MyPartnerInfo := f.GetExpireVar(myKey)
MyOfPartnerList := GoUtil.IntSlice(MyPartnerInfo.D) MyOfPartnerList := GoUtil.IntSlice(MyPartnerInfo.D)
OtherOfPartnerList := GoUtil.IntSlice(OtherPartnerInfo.D) OtherOfPartnerList := GoUtil.IntSlice(OtherPartnerInfo.D)
if len(MyOfPartnerList) > 4 || len(OtherOfPartnerList) > 4 { if len(MyOfPartnerList) > 4 || len(OtherOfPartnerList) > 4 {
return nil, fmt.Errorf("catnip partner already full for uid %d in game %d", CatnipPartnerId, CatnipGameId) return nil, fmt.Errorf("catnip partner already full for uid %d in game %d", Partner, GameId)
} }
f.SetExpireVar(key, &VarExpireData{ f.SetVar(key, &VarExpireData{
D: append(OtherOfPartnerList, MyUid), D: append(OtherOfPartnerList, Uid),
T: m.End, T: EndTime,
}) })
f.SetExpireVar(myKey, &VarExpireData{ f.SetVar(myKey, &VarExpireData{
D: append(MyOfPartnerList, CatnipPartnerId), D: append(MyOfPartnerList, Partner),
T: m.End, T: EndTime,
}) })
return nil, nil return nil, nil
} }
return nil, fmt.Errorf("invalid parameters for setting catnip partner")
}
func (f *VarMgr) SetVar(key string, value interface{}) { func (f *VarMgr) SetVar(key string, value interface{}) {
f.getData().Var[key] = value f.getData().Var[key] = &VarExpireData{
} D: 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
} }
// TODO: 弃用
func (f *VarMgr) GetExpireVar(key string) *VarExpireData { func (f *VarMgr) GetExpireVar(key string) *VarExpireData {
if v, ok := f.getData().VarExpire[key]; ok { if v, ok := f.getData().VarExpire[key]; ok {
return v return v
@ -132,10 +137,12 @@ func (f *VarMgr) GetExpireVar(key string) *VarExpireData {
return data return data
} }
// TODO: 弃用
func (f *VarMgr) SetUserVar(key string, value *VarUserData) { func (f *VarMgr) SetUserVar(key string, value *VarUserData) {
f.getData().UserVar[key] = value f.getData().UserVar[key] = value
} }
// TODO: 弃用
func (f *VarMgr) GetUserVar(key string) *VarUserData { func (f *VarMgr) GetUserVar(key string) *VarUserData {
if v, ok := f.getData().UserVar[key]; ok { if v, ok := f.getData().UserVar[key]; ok {
return v return v
@ -152,3 +159,56 @@ func (f *VarMgr) DelVar(key string) {
func (f *VarMgr) getData() *VarData { func (f *VarMgr) getData() *VarData {
return f.data.(*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")
}

View File

@ -304,6 +304,10 @@ func GetUserKey(Uid int64) string {
return fmt.Sprintf("user_data_%d", Uid) 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 { func GetCatnipLockKey(Uid, GameId int) string {
return fmt.Sprintf("catnip_lock_%d_%d", Uid, GameId) return fmt.Sprintf("catnip_lock_%d_%d", Uid, GameId)
} }