package main import ( "strconv" "time" "mongo.games.com/goserver/core/basic" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/module" "mongo.games.com/goserver/core/task" "mongo.games.com/game/common" "mongo.games.com/game/model" "mongo.games.com/game/worldsrv/internal" ) /* 玩家信息加载,缓存,持久化,缓存释放 */ func init() { internal.RegisterPlayerLoad(PlayerInfoMgrSingle) module.RegisteModule(PlayerInfoMgrSingle, time.Hour, 0) } var PlayerInfoMgrSingle = &PlayerInfoMgr{ Players: make(map[int32]*PlayerInfo), PlayerPlatform: make(map[int32]string), } type AllPlayerInfo struct { GameData []*model.PlayerGameData Lottery []*model.Lottery } // PlayerInfo 玩家信息 type PlayerInfo struct { GameData map[string]*model.PlayerGameData // 游戏数据 Lottery map[int64]*model.Lottery // 抽奖数据 key:抽奖配置id } type PlayerInfoMgr struct { Players map[int32]*PlayerInfo PlayerPlatform map[int32]string } func (p *PlayerInfoMgr) ModuleName() string { return "PlayerInfoMgr" } func (p *PlayerInfoMgr) Init() { } func (p *PlayerInfoMgr) Update() { for k, v := range p.PlayerPlatform { if PlayerMgrSington.GetPlayerBySnId(k) == nil { p.Save(v, k, true, true) p.Release(v, k) } } } func (p *PlayerInfoMgr) Shutdown() { for k, v := range p.Players { if v == nil { continue } p.Save(p.PlayerPlatform[k], k, true, true) p.Release(p.PlayerPlatform[k], k) } module.UnregisteModule(p) } func (p *PlayerInfoMgr) Load(platform string, snid int32, data any) *internal.PlayerLoadReplay { if platform != "" && snid > 0 { p.PlayerPlatform[snid] = platform } var err error allPlayerInfo := &AllPlayerInfo{ GameData: make([]*model.PlayerGameData, 0), Lottery: make([]*model.Lottery, 0), } // 游戏数据 allPlayerInfo.GameData, err = model.GetPlayerGameData(platform, snid) if err != nil { logger.Logger.Errorf("GetPlayerGameData snid:%v error: %v", snid, err) goto here } // 抽奖数据 allPlayerInfo.Lottery, err = model.GetLottery(platform, snid, 0, common.GetDayStartTs(time.Now().Unix())) if err != nil { logger.Logger.Errorf("GetLottery snid:%v error: %v", snid, err) goto here } // ... here: return &internal.PlayerLoadReplay{ Platform: platform, Snid: snid, Err: err, Data: allPlayerInfo, } } func (p *PlayerInfoMgr) Callback(data any, ret *internal.PlayerLoadReplay) { if ret.Err != nil { return } playerInfo, ok := ret.Data.(*AllPlayerInfo) if !ok { return } info := &PlayerInfo{ GameData: make(map[string]*model.PlayerGameData), Lottery: make(map[int64]*model.Lottery), } // 游戏数据 for _, v := range playerInfo.GameData { info.GameData[v.Id] = v } // 抽奖数据 for _, v := range playerInfo.Lottery { info.Lottery[v.CId] = v } // ... p.Players[ret.Snid] = info } func (p *PlayerInfoMgr) LoadAfter(platform string, snid int32) *internal.PlayerLoadReplay { if platform != "" && snid > 0 { p.PlayerPlatform[snid] = platform } return nil } func (p *PlayerInfoMgr) CallbackAfter(ret *internal.PlayerLoadReplay) {} func (p *PlayerInfoMgr) Save(platform string, snid int32, isSync, force bool) { var err error f := func() { data, ok := p.Players[snid] if !ok { return } // 游戏数据 err = model.SavePlayerGameData(platform, common.GetMapValues(data.GameData)) if err != nil { logger.Logger.Errorf("SavePlayerGameData snid:%v error: %v", snid, err) } // 抽奖数据 err = model.UpsertLottery(platform, common.GetMapValues(data.Lottery)...) if err != nil { logger.Logger.Errorf("UpsertLottery snid:%v error: %v", snid, err) } // ... } cf := func() { } if isSync { f() cf() return } task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { f() return nil }), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) { cf() }), "SavePlayerInfo").StartByFixExecutor("SnId:" + strconv.Itoa(int(snid))) } func (p *PlayerInfoMgr) Release(platform string, snid int32) { delete(p.Players, snid) delete(p.PlayerPlatform, snid) }