Merge branch 'develop' into sdk

This commit is contained in:
hahwu 2026-01-13 14:12:55 +08:00
commit 76be08fe85
5 changed files with 107 additions and 27 deletions

View File

@ -1,8 +1,6 @@
package ga
import (
"fmt"
galog "github.com/tuyou/galog"
)
@ -24,7 +22,14 @@ func init() {
func GAlogEvent(event string, userID string, deviceID string, properties map[string]interface{}) {
newProperties := make(map[string]interface{})
for k, v := range properties {
newProperties["proj_"+k] = fmt.Sprintf("%v", v)
// // JSON encode the value
// jsonBytes, err := json.Marshal(v)
// if err != nil {
// newProperties["proj_"+k] = fmt.Sprintf("%v", v) // 无法解析直接转为字符串
// continue
// }
// newProperties["proj_"+k] = string(jsonBytes)
newProperties["proj_"+k] = v
}
properties = newProperties
glogger.

View File

@ -150,6 +150,7 @@ func HandleClientReq(args []interface{}) {
detail := &msg.ReqLogin{}
proto.Unmarshal(buf, detail)
accountInfo := db.GetAccountInfoFromDb(detail.UserName)
log.Debug("player %s start login", detail.UserName)
defer func() {
if r := recover(); r != nil {
GoUtil.SendFeishuFatal(0, m.GetFunc(), fmt.Sprintf("username: %s, fatal: %s", detail.UserName, r))
@ -177,6 +178,7 @@ func HandleClientReq(args []interface{}) {
db.UpdateAccountInfoDeviceToDb(accountInfo)
p, _ := internal.Agents.Load(a)
if p != nil {
log.Debug("player %s login success", detail.UserName)
p.(*Player).PlayMod.getBaseMod().DiviceId = detail.Device //加锁
p.(*Player).PushClientRes(ResLogin)
p.(*Player).LoginBackData()

View File

@ -7,8 +7,13 @@ import (
"runtime/debug"
mergeCluster "server/cluster"
"server/conf"
"server/game/mod/card"
"server/game/mod/friend"
"server/game/mod/item"
limitedTimeEvent "server/game/mod/limited_time_event"
"server/game/mod/msg"
GoUtil "server/game_util"
proto "server/msg"
"server/pkg/github.com/name5566/leaf/log"
"sync"
"time"
@ -78,8 +83,24 @@ func (m *MessageMgr) MessageMgrInit() {
MessageList: make(map[int64]*MessageList),
PlayerList: make(map[int64]int),
}
gob.Register(msg.VarData{})
gob.Register(GameResult{})
// 注册所有可能在消息中使用的类型
gob.Register(&limitedTimeEvent.MoneyCat{})
gob.Register(&limitedTimeEvent.LuckyCat{})
gob.Register(&msg.HandbookMsg{})
gob.Register(&limitedTimeEvent.CatTrick{})
gob.Register(&VarOpration{})
gob.Register(&VarUserData{})
gob.Register(&ActivityInfo{})
gob.Register(&ChargeExtra{})
gob.Register(CatnipMsg{})
gob.Register(&CatnipLock{})
gob.Register(CRank{})
gob.Register(&proto.ResChampshipRank{})
gob.Register(&proto.ResChampshipPreRank{})
gob.Register(card.CardInfo{})
gob.Register(item.Item{})
gob.Register([]*item.Item{}) // 注册 []*item.Item 类型
gob.Register(friend.ReplyInfo{})
// 注册处理函数
m.init()
m.handler = make(map[int]MessageHandlerFunc)
@ -154,7 +175,16 @@ func ChampshipRankInfoHandler(data *msg.Msg) (interface{}, error) {
func NotifyAllPlayerMsg(m *msg.Msg) {
messageMgrData := getMessageData()
for PlayerId, node := range messageMgrData.PlayerList {
// 先复制 PlayerList避免长时间持有锁
messageMgrData.mu.Lock()
playerListCopy := make(map[int64]int, len(messageMgrData.PlayerList))
for k, v := range messageMgrData.PlayerList {
playerListCopy[k] = v
}
messageMgrData.mu.Unlock()
// 在锁外发送消息
for PlayerId, node := range playerListCopy {
m.To = int(PlayerId)
SendMsgToNodeAsync(m, node)
}
@ -176,7 +206,11 @@ func CatnipPartnerHandler(data *msg.Msg) (interface{}, error) {
func ReplyPlayerMsgASync(m *msg.Msg, reply interface{}) (interface{}, error) {
clone := m.Reply(reply)
messageMgrData := getMessageData()
if node, ok := messageMgrData.PlayerList[int64(m.From)]; ok {
messageMgrData.mu.Lock()
node, ok := messageMgrData.PlayerList[int64(m.From)]
messageMgrData.mu.Unlock()
if ok {
SendMsgToNodeAsync(clone, node)
}
return nil, nil
@ -193,12 +227,13 @@ func ClusterSyncHandler(data *msg.Msg) (interface{}, error) {
})
return true
})
// 发送暂存区消息
// 发送暂存区消息(先复制再释放锁,避免长时间持有锁)
messageMgrData := getMessageData()
messageMgrData.mu.Lock()
TempMessageList := messageMgrData.MessageList
messageMgrData.MessageList = make(map[int64]*MessageList)
defer messageMgrData.mu.Unlock()
messageMgrData.mu.Unlock() // 立即释放锁,在锁外发送消息
log.Debug("[Middleware] Cluster sync send temp message len: %d", len(TempMessageList))
for _, Message := range TempMessageList {
for _, msgItem := range Message.Messages {
@ -212,25 +247,34 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) {
// 关闭 Worker Pool
node := data.Extra.(int)
messageMgrData := getMessageData()
// 先更新 PlayerList需要加锁
messageMgrData.mu.Lock()
messageMgrData.PlayerList[int64(data.From)] = node
messageMgrData.mu.Unlock()
log.Debug("[Middleware] Player login success player id: %v, node: %v", data.From, data.Extra.(int))
// 对玩家消息列表加锁
messages := getMessge(int64(data.From))
messages.mu.Lock()
defer messages.mu.Unlock()
// 发送离线消息
len := len(messages.Messages)
for _, message := range messages.Messages {
// 复制消息列表,避免在锁内发送消息
messagesToSend := make([]*msg.Msg, len(messages.Messages))
copy(messagesToSend, messages.Messages)
messages.mu.Unlock()
// 在锁外发送离线消息
for _, message := range messagesToSend {
SendMsgToNodeAsync(message, node)
}
log.Debug("[Middleware] Player sync logout message player id: %v, len: %d", data.From, len)
log.Debug("[Middleware] Player sync logout message player id: %v, len: %d", data.From, len(messagesToSend))
ReplyPlayerMsgASync(data, nil)
return nil, nil
}
func PlayerLogoutHandler(data *msg.Msg) (interface{}, error) {
messageMgrData := getMessageData()
messageMgrData.mu.Lock()
delete(messageMgrData.PlayerList, int64(data.From))
messageMgrData.mu.Unlock()
log.Debug("[Middleware] Player logout success player id: %v", data.From)
return nil, nil
}
@ -256,9 +300,15 @@ func CenterPlayerMsgHandler(data *msg.Msg) (interface{}, error) {
// 遍历消息列表,发送消息给在线玩家
messages := getMessge(PlayerId)
messages.mu.Lock()
defer messages.mu.Unlock()
messages.Messages = append(messages.Messages, data)
if node, ok := messageMgrData.PlayerList[int64(PlayerId)]; ok {
messages.mu.Unlock()
// 检查玩家是否在线(需要加锁)
messageMgrData.mu.Lock()
node, ok := messageMgrData.PlayerList[int64(PlayerId)]
messageMgrData.mu.Unlock()
if ok {
SendMsgToNodeAsync(data, node)
}
return nil, nil
@ -742,7 +792,8 @@ func saveMessage(m *msg.Msg) error {
data := getMessageData()
data.mu.Lock()
defer data.mu.Unlock()
messages := getMessge(int64(m.To))
// 使用不加锁的内部方法,避免死锁
messages := getMessgeUnsafe(int64(m.To))
messages.mu.Lock()
defer messages.mu.Unlock()
messages.Messages = append(messages.Messages, m)
@ -757,10 +808,9 @@ func GetUserData(PlayerId int64, Key string) (*msg.Msg, error) {
})
}
func getMessge(PlayerId int64) *MessageList {
// getMessgeUnsafe 获取消息列表(不加锁,调用者需要持有锁)
func getMessgeUnsafe(PlayerId int64) *MessageList {
messageMgrData := getMessageData()
messageMgrData.mu.Lock()
defer messageMgrData.mu.Unlock()
if _, ok := messageMgrData.MessageList[int64(PlayerId)]; !ok {
messageMgrData.MessageList[int64(PlayerId)] = &MessageList{
Messages: []*msg.Msg{},
@ -769,17 +819,40 @@ func getMessge(PlayerId int64) *MessageList {
return messageMgrData.MessageList[int64(PlayerId)]
}
// getMessge 获取消息列表(加锁版本)
func getMessge(PlayerId int64) *MessageList {
messageMgrData := getMessageData()
messageMgrData.mu.Lock()
defer messageMgrData.mu.Unlock()
return getMessgeUnsafe(PlayerId)
}
func deleteMessage(m *msg.Msg) error {
if m == nil {
return nil
}
messages := getMessge(int64(m.To))
messages.mu.Lock()
defer messages.mu.Unlock()
// 使用更安全的方式删除元素找到索引后再删除避免在range中修改切片
foundIndex := -1
for i, msgItem := range messages.Messages {
if msgItem == nil {
continue
}
if msgItem.UniKey == m.UniKey {
// 删除消息
messages.Messages = append(messages.Messages[:i], messages.Messages[i+1:]...)
foundIndex = i
log.Debug("[Middleware] send message success; message: %v, player id: %v", msgItem, msgItem.From)
break
}
}
if foundIndex >= 0 {
// 删除消息:将后面的元素前移,避免内存泄漏
copy(messages.Messages[foundIndex:], messages.Messages[foundIndex+1:])
messages.Messages[len(messages.Messages)-1] = nil // 清除最后一个元素的引用
messages.Messages = messages.Messages[:len(messages.Messages)-1]
}
return nil
}

View File

@ -27,7 +27,6 @@ import (
"server/game/mod/quest"
GoUtil "server/game_util"
"server/msg"
telog "server/thinkdata"
"strconv"
"sync"
"time"
@ -1056,9 +1055,10 @@ func (p *Player) TeLog(Type string, Param map[string]interface{}) {
if agent != nil {
Param["Ip"] = agent.RemoteAddr().String()
}
go telog.Te.Track(p.GetPlayerBaseMod().GetName(), p.GetPlayerBaseMod().GetName(), Type, Param)
//Param["#zone_offset"] = -5
// 游戏内TE日志
//go telog.Te.Track(p.GetPlayerBaseMod().GetName(), p.GetPlayerBaseMod().GetName(), Type, Param)
BaseMod := p.PlayMod.getBaseMod()
//途游GA
go ga.GAlogEvent(Type, BaseMod.Account, "", Param)
}

View File

@ -166,7 +166,7 @@ func (s *ServerMod) LoadData() {
DbData.UpdataTime = GoUtil.Now()
err = db.InsertServerData(&DbData)
if err != nil {
log.Debug("LoadData sql exec ,Mod Key: %s err:%v", s.key, err)
log.Error("LoadData sql exec ,Mod Key: %s err:%v", s.key, err)
}
return
}
@ -175,7 +175,7 @@ func (s *ServerMod) LoadData() {
}
err = GoUtil.GobUnmarshal(DbData.ModData, s.data)
if err != nil {
log.Debug("LoadData Unmarshal failed,Mod Key: %s err:%v", s.key, err)
log.Error("LoadData Unmarshal failed,Mod Key: %s err:%v", s.key, err)
return
}
}