缓存优化

This commit is contained in:
sk 2024-11-12 10:51:04 +08:00
parent 8aaf1b40f3
commit d1afed32c2
12 changed files with 364 additions and 1056 deletions

View File

@ -6,7 +6,7 @@ import (
"time"
)
//牌序- 2, A, K, Q, J, 10, 9, 8, 7, 6, 5, 4, 3
//牌序- 2, A, K, Q, J,10, 9, 8, 7, 6, 5, 4, 3
//红桃- 51,50,49,48,47,46,45,44,43,42,41,40,39
//方片- 38,37,36,35,34,33,32,31,30,29,28,27,26
//梅花- 25,24,23,22,21,20,19,18,17,16,15,14,13

View File

@ -18,13 +18,11 @@ func SessionLogout(sid int64, drop bool) bool {
ls.state = LoginStateLogout
p := PlayerMgrSington.GetOnlinePlayer(sid)
if p != nil {
p.ThirdGameLogout()
if drop {
p.DropLine()
internal.FirePlayerDropLine(p)
internal.FirePlayerDropLine[*Player, *Scene](p)
} else {
p.Logout()
internal.FirePlayerLogouted(p)
}
} else {
logger.Logger.Trace("SessionLogout p == nil")

View File

@ -29,6 +29,7 @@ import (
player_proto "mongo.games.com/game/protocol/player"
webapi_proto "mongo.games.com/game/protocol/webapi"
"mongo.games.com/game/webapi"
"mongo.games.com/game/worldsrv/internal"
)
var reTelRule, _ = regexp.Compile(`^(1[3|4|5|6|7|8|9][0-9]\d{4,8})$`)
@ -2004,7 +2005,7 @@ func CSPlayerData(s *netlib.Session, packetid int, data interface{}, sid int64)
if player.IsOnLine() {
if player.sid != 0 && player.sid != sid {
//Kick the exist player disconnect
player.Kickout(common.KickReason_OtherLogin)
player.Kick(common.KickReason_OtherLogin)
}
}
@ -2022,7 +2023,7 @@ func CSPlayerData(s *netlib.Session, packetid int, data interface{}, sid int64)
proto.SetDefaults(scPlayerData)
player.SendRawToClientIncOffLine(sid, s, int(player_proto.PlayerPacketID_PACKET_SC_PLAYERDATA), scPlayerData)
//Kick the exist player disconnect
player.Kickout(common.KickReason_Freeze)
player.Kick(common.KickReason_Freeze)
return nil
}
@ -2036,7 +2037,7 @@ func CSPlayerData(s *netlib.Session, packetid int, data interface{}, sid int64)
proto.SetDefaults(scPlayerData)
player.SendRawToClientIncOffLine(sid, s, int(player_proto.PlayerPacketID_PACKET_SC_PLAYERDATA), scPlayerData)
//Kick the exist player disconnect
player.Kickout(common.KickReason_Freeze)
player.Kick(common.KickReason_Freeze)
return nil
}
@ -2056,7 +2057,7 @@ func CSPlayerData(s *netlib.Session, packetid int, data interface{}, sid int64)
proto.SetDefaults(scPlayerData)
player.SendRawToClientIncOffLine(sid, s, int(player_proto.PlayerPacketID_PACKET_SC_PLAYERDATA), scPlayerData)
//Kick the exist player disconnect
player.Kickout(common.KickReason_Freeze)
player.Kick(common.KickReason_Freeze)
return nil
}
@ -2068,40 +2069,18 @@ func CSPlayerData(s *netlib.Session, packetid int, data interface{}, sid int64)
proto.SetDefaults(scPlayerData)
player.SendRawToClientIncOffLine(sid, s, int(player_proto.PlayerPacketID_PACKET_SC_PLAYERDATA), scPlayerData)
//Kick the exist player disconnect
player.Kickout(common.KickReason_Freeze)
player.Kick(common.KickReason_Freeze)
return nil
}
}
if !player.IsRob {
if _, ok := BlackListMgrSington.CheckLogin(player.PlayerData); !ok {
//var msg string
//if bi != nil {
// msg = i18n.Tr("languages", "BlackListLimit2Args", player.SnId, bi.Id, player.SnId, bi.Id, player.SnId, bi.Id, player.SnId, bi.Id)
//} else {
// msg = i18n.Tr("languages", "BlackListLimit1Args", player.SnId, player.SnId, player.SnId, player.SnId)
//}
//common.SendSrvMsg(player, common.SRVMSG_CODE_DEFAULT, msg)
//scPlayerData := &player_proto.SCPlayerData{
// OpRetCode: player_proto.OpResultCode_OPRC_InBlackList,
//}
//proto.SetDefaults(scPlayerData)
//player.SendToClient(int(player_proto.PlayerPacketID_PACKET_SC_PLAYERDATA), scPlayerData)
//Kick the exist player disconnect
player.Kickout(common.KickReason_Freeze)
player.Kick(common.KickReason_Freeze)
return nil
}
}
// 给玩家发送三方余额状态
//statePack := &gamehall_proto.SCThridGameBalanceUpdateState{}
//if player.thridBalanceReqIsSucces {
// statePack.OpRetCode = gamehall_proto.OpResultCode_Game_OPRC_Sucess_Game
//} else {
// statePack.OpRetCode = gamehall_proto.OpResultCode_Game_OPRC_Error_Game
//}
//player.SendRawToClientIncOffLine(sid, s, int(gamehall_proto.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATESTATE), statePack)
//抽奖次数兼容老玩家
if !player.IsRob && !player.InitLotteryStatus && WelfareMgrSington.GetPhoneLotteryStatus(player.Platform) == model.WelfareOpen {
player.addLotteryCount(20)
@ -2114,6 +2093,7 @@ func CSPlayerData(s *netlib.Session, packetid int, data interface{}, sid int64)
playerFunc(player, cspl)
PlayerMgrSington.ReholdPlayer(player, sid, s)
player.OnRehold()
internal.FirePlayerRehold[*Player, *Scene](player)
player.SendPlayerInfo()
return nil
}
@ -2147,52 +2127,20 @@ func CSPlayerData(s *netlib.Session, packetid int, data interface{}, sid int64)
return
}
// 检查禁止登录
if !player.IsRob {
if _, ok := BlackListMgrSington.CheckLogin(pd.PlayerData); !ok {
//黑名单用户也需要调用一下onlogin,否则会导致数据无法刷新
player.OnLogined()
player.Kickout(common.KickReason_Freeze)
internal.FirePlayerLogined[*Player, *Scene](player)
player.Kick(common.KickReason_Freeze)
return
}
}
var temp []byte
var ee error
di := cspl.GetDeviceInfo()
if di != "" {
var e common.Encryptor
e.Init(common.GetAppId(), player.PackageID, int32(cspl.GetTimeStamp()))
temp, ee = base64.StdEncoding.DecodeString(di)
if ee == nil {
e.Encrypt(temp, len(temp))
}
}
if isnew { //新用户赠送金币
//首次创建账号事件
//isBind := 0
//if pd.Tel != "" {
// isBind = 1
//}
//LogChannelSingleton.WriteMQData(model.GeneratePlayerEvent(model.WEBEVENT_LOGIN, pd.Platform, pd.PackageID, pd.SnId, pd.Channel, pd.BeUnderAgentCode, pd.PromoterTree, 1, 1, isBind, common.GetAppId()))
//newbieCoin := player.GetRegisterPrize()
//if newbieCoin > 0 {
// player.AddCoin(int64(newbieCoin), common.GainWay_NewPlayer, "system", "")
// //增加泥码
// player.AddDirtyCoin(0, int64(newbieCoin))
// player.ReportSystemGiveEvent(newbieCoin, common.GainWay_NewPlayer, true)
// player.AddPayCoinLog(int64(newbieCoin), model.PayCoinLogType_Coin, "NewPlayer")
// LogChannelSingleton.WriteMQData(model.GenerateSystemFreeGive(pd.SnId, pd.Name, pd.Platform, model.SystemFreeGive_GiveType_NewPlayer, model.SystemFreeGive_CoinType_Coin, int64(newbieCoin)))
//}
//if player.InviterId > 0 {
// //actRandCoinMgr.OnPlayerInvite(player.Platform, player.InviterId)
//}
}
//测试代码
playerFunc(player, cspl)
player.OnLogined()
internal.FirePlayerLogined[*Player, *Scene](player)
player.SendPlayerInfo()
}, true)

View File

@ -9,7 +9,7 @@ import (
)
var DbSaveInst = &DbSaver{
GroupNumber: 5,
GroupNumber: 600,
}
type DbSaver struct {

View File

@ -420,7 +420,7 @@ func handlerEvent(ctx context.Context, completeKey string, isInit bool, event *c
}
for _, p := range targetPlayer {
if p.sid != 0 {
p.Kickout(int32(loginproto.SSDisconnectTypeCode_SSDTC_BlackList))
p.Kick(int32(loginproto.SSDisconnectTypeCode_SSDTC_BlackList))
} else {
LoginStateMgrSington.LogoutByAccount(p.AccountId)
}

View File

@ -1,12 +1,10 @@
package internal
type Player any
import "mongo.games.com/game/common"
type Scene any
var _playerListeners []interface{}
var _playerListeners []PlayerListener
func RegisterPlayerListener(l PlayerListener) {
func RegisterPlayerListener[Player, Scene any](l PlayerListener[Player, Scene]) {
for _, ll := range _playerListeners {
if ll == l {
return
@ -15,144 +13,192 @@ func RegisterPlayerListener(l PlayerListener) {
_playerListeners = append(_playerListeners, l)
}
type PlayerListener interface {
type PlayerListener[Player, Scene any] interface {
common.ClockSinker
// 登出相关
OnPlayerLogined(p Player) // 玩家登录时触发
OnPlayerLogouted(p Player) // 玩家登出时触发
OnPlayerDropLine(p Player) // 玩家掉线时触发
OnPlayerRehold(p Player) // 玩家重新连接时触发
// 时间相关
OnPlayerSecTimer(p Player) // 每秒触发
OnPlayerMiniTimer(p Player) // 每分钟触发
OnPlayerHourTimer(p Player) // 每小时触发
OnPlayerDayTimer(p Player, login, continuous bool) // 每天触发login表示是否登录continuous表示是否连续登录
OnPlayerWeekTimer(p Player) // 每周触发
OnPlayerMonthTimer(p Player) // 每月触发
// 业务相关
OnPlayerEnterScene(p Player, s Scene) // 玩家进入场景时触发
OnPlayerLeaveScene(p Player, s Scene) // 玩家离开场景时触发
OnPlayerReturnScene(p Player, s Scene) // 玩家返回房间时触发
OnPlayerEnterSceneBefore(p Player, s Scene) // 玩家进入场景前触发
OnPlayerEnterSceneAfter(p Player, s Scene) // 玩家进入场景后触发
OnPlayerLeaveSceneBefore(p Player, s Scene) // 玩家离开场景前触发
OnPlayerLeaveSceneAfter(p Player, s Scene) // 玩家离开场景后触发
OnPlayerReturnSceneBefore(p Player, s Scene) // 玩家返回房间前触发
OnPlayerReturnSceneAfter(p Player, s Scene) // 玩家返回房间后触发
}
func FirePlayerLogined(p Player) {
func FirePlayerLogined[Player, Scene any](p Player) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerLogined(p)
l.(PlayerListener[Player, Scene]).OnPlayerLogined(p)
}
}
}
func FirePlayerLogouted(p Player) {
func FirePlayerLogouted[Player, Scene any](p Player) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerLogouted(p)
l.(PlayerListener[Player, Scene]).OnPlayerLogouted(p)
}
}
}
func FirePlayerDropLine(p Player) {
func FirePlayerDropLine[Player, Scene any](p Player) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerDropLine(p)
l.(PlayerListener[Player, Scene]).OnPlayerDropLine(p)
}
}
}
func FirePlayerRehold(p Player) {
func FirePlayerRehold[Player, Scene any](p Player) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerRehold(p)
l.(PlayerListener[Player, Scene]).OnPlayerRehold(p)
}
}
}
func FirePlayerSecTimer(p Player) {
func FirePlayerEnterSceneBefore[Player, Scene any](p Player, s Scene) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerSecTimer(p)
l.(PlayerListener[Player, Scene]).OnPlayerEnterSceneBefore(p, s)
}
}
}
func FirePlayerMiniTimer(p Player) {
func FirePlayerEnterSceneAfter[Player, Scene any](p Player, s Scene) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerMiniTimer(p)
l.(PlayerListener[Player, Scene]).OnPlayerEnterSceneAfter(p, s)
}
}
}
func FirePlayerHourTimer(p Player) {
func FirePlayerLeaveSceneBefore[Player, Scene any](p Player, s Scene) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerHourTimer(p)
l.(PlayerListener[Player, Scene]).OnPlayerLeaveSceneBefore(p, s)
}
}
}
func FirePlayerDayTimer(p Player, login, continuous bool) {
func FirePlayerLeaveSceneAfter[Player, Scene any](p Player, s Scene) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerDayTimer(p, login, continuous)
l.(PlayerListener[Player, Scene]).OnPlayerLeaveSceneAfter(p, s)
}
}
}
func FirePlayerWeekTimer(p Player) {
func FirePlayerReturnSceneBefore[Player, Scene any](p Player, s Scene) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerWeekTimer(p)
l.(PlayerListener[Player, Scene]).OnPlayerReturnSceneBefore(p, s)
}
}
}
func FirePlayerMonthTimer(p Player) {
func FirePlayerReturnSceneAfter[Player, Scene any](p Player, s Scene) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerMonthTimer(p)
l.(PlayerListener[Player, Scene]).OnPlayerReturnSceneAfter(p, s)
}
}
}
func FirePlayerEnterScene(p Player, s Scene) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerEnterScene(p, s)
}
type BasePlayerListener[Player, Scene any] struct {
common.ClockFunc
}
func (l *BasePlayerListener[Player, Scene]) OnPlayerLogined(p Player) {}
func (l *BasePlayerListener[Player, Scene]) OnPlayerLogouted(p Player) {}
func (l *BasePlayerListener[Player, Scene]) OnPlayerDropLine(p Player) {}
func (l *BasePlayerListener[Player, Scene]) OnPlayerRehold(p Player) {}
func (l *BasePlayerListener[Player, Scene]) OnPlayerEnterSceneBefore(p Player, s Scene) {}
func (l *BasePlayerListener[Player, Scene]) OnPlayerEnterSceneAfter(p Player, s Scene) {}
func (l *BasePlayerListener[Player, Scene]) OnPlayerLeaveSceneBefore(p Player, s Scene) {}
func (l *BasePlayerListener[Player, Scene]) OnPlayerLeaveSceneAfter(p Player, s Scene) {}
func (l *BasePlayerListener[Player, Scene]) OnPlayerReturnSceneBefore(p Player, s Scene) {}
func (l *BasePlayerListener[Player, Scene]) OnPlayerReturnSceneAfter(p Player, s Scene) {}
type PlayerListenerFunc[Player, Scene any] struct {
common.ClockFunc
OnPlayerLoginedFunc func(p Player)
OnPlayerLogoutedFunc func(p Player)
OnPlayerDropLineFunc func(p Player)
OnPlayerReholdFunc func(p Player)
OnPlayerEnterSceneBeforeFunc func(p Player, s Scene)
OnPlayerEnterSceneAfterFunc func(p Player, s Scene)
OnPlayerLeaveSceneBeforeFunc func(p Player, s Scene)
OnPlayerLeaveSceneAfterFunc func(p Player, s Scene)
OnPlayerReturnSceneBeforeFunc func(p Player, s Scene)
OnPlayerReturnSceneAfterFunc func(p Player, s Scene)
}
func (l *PlayerListenerFunc[Player, Scene]) OnPlayerLogined(p Player) {
if l.OnPlayerLoginedFunc != nil {
l.OnPlayerLoginedFunc(p)
}
}
func FirePlayerLeaveScene(p Player, s Scene) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerLeaveScene(p, s)
}
func (l *PlayerListenerFunc[Player, Scene]) OnPlayerLogouted(p Player) {
if l.OnPlayerLogoutedFunc != nil {
l.OnPlayerLogoutedFunc(p)
}
}
func FirePlayerReturnScene(p Player, s Scene) {
for _, l := range _playerListeners {
if l != nil {
l.OnPlayerReturnScene(p, s)
}
func (l *PlayerListenerFunc[Player, Scene]) OnPlayerDropLine(p Player) {
if l.OnPlayerDropLineFunc != nil {
l.OnPlayerDropLineFunc(p)
}
}
type BasePlayerListener struct {
func (l *PlayerListenerFunc[Player, Scene]) OnPlayerRehold(p Player) {
if l.OnPlayerReholdFunc != nil {
l.OnPlayerReholdFunc(p)
}
}
func (l *BasePlayerListener) OnPlayerLogined(p Player) {}
func (l *BasePlayerListener) OnPlayerLogouted(p Player) {}
func (l *BasePlayerListener) OnPlayerDropLine(p Player) {}
func (l *BasePlayerListener) OnPlayerRehold(p Player) {}
func (l *BasePlayerListener) OnPlayerSecTimer(p Player) {}
func (l *BasePlayerListener) OnPlayerMiniTimer(p Player) {}
func (l *BasePlayerListener) OnPlayerHourTimer(p Player) {}
func (l *BasePlayerListener) OnPlayerDayTimer(p Player, login, continuous bool) {}
func (l *BasePlayerListener) OnPlayerWeekTimer(p Player) {}
func (l *BasePlayerListener) OnPlayerMonthTimer(p Player) {}
func (l *BasePlayerListener) OnPlayerEnterScene(p Player, s Scene) {}
func (l *BasePlayerListener) OnPlayerLeaveScene(p Player, s Scene) {}
func (l *BasePlayerListener) OnPlayerReturnScene(p Player, s Scene) {}
func (l *PlayerListenerFunc[Player, Scene]) OnPlayerEnterSceneBefore(p Player, s Scene) {
if l.OnPlayerEnterSceneBeforeFunc != nil {
l.OnPlayerEnterSceneBeforeFunc(p, s)
}
}
func (l *PlayerListenerFunc[Player, Scene]) OnPlayerEnterSceneAfter(p Player, s Scene) {
if l.OnPlayerEnterSceneAfterFunc != nil {
l.OnPlayerEnterSceneAfterFunc(p, s)
}
}
func (l *PlayerListenerFunc[Player, Scene]) OnPlayerLeaveSceneBefore(p Player, s Scene) {
if l.OnPlayerLeaveSceneBeforeFunc != nil {
l.OnPlayerLeaveSceneBeforeFunc(p, s)
}
}
func (l *PlayerListenerFunc[Player, Scene]) OnPlayerLeaveSceneAfter(p Player, s Scene) {
if l.OnPlayerLeaveSceneAfterFunc != nil {
l.OnPlayerLeaveSceneAfterFunc(p, s)
}
}
func (l *PlayerListenerFunc[Player, Scene]) OnPlayerReturnSceneBefore(p Player, s Scene) {
if l.OnPlayerReturnSceneBeforeFunc != nil {
l.OnPlayerReturnSceneBeforeFunc(p, s)
}
}
func (l *PlayerListenerFunc[Player, Scene]) OnPlayerReturnSceneAfter(p Player, s Scene) {
if l.OnPlayerReturnSceneAfterFunc != nil {
l.OnPlayerReturnSceneAfterFunc(p, s)
}
}
func RegisterPlayerListenerFunc[P, S any](l *PlayerListenerFunc[P, S]) {
common.RegisterClockFunc(&l.ClockFunc)
RegisterPlayerListener(l)
}

View File

@ -759,6 +759,7 @@ func (l *LotteryMgr) AddCostRoomCard(plt string, snid int32, n int64) {
logger.Logger.Errorf("AddCostRoomCard snid:%v not found", snid)
return
}
PlayerMgrSington.AddPlayer(0, item.PlayerData, nil)
f()
}, false)
return

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,6 @@ import (
"mongo.games.com/goserver/core"
"mongo.games.com/goserver/core/basic"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/module"
"mongo.games.com/goserver/core/task"
@ -193,49 +192,6 @@ func (c *PlayerCacheMgr) UnCacheInvalidPlayerId(snid int32) {
delete(c.playerInvalidIds, snid)
}
// 保存没有登录缓存的玩家数据
func (c *PlayerCacheMgr) saveCache(p *PlayerCacheItem, isSync bool) {
if p == nil {
return
}
saveFunc := func(v internal.PlayerLoader) {
if v == nil {
return
}
v.Save(p.Platform, p.SnId, true, true)
logger.Logger.Infof("PlayerCacheMgr SaveCache snid:%v", p.SnId)
}
releaseFunc := func(v internal.PlayerLoader) {
if v == nil {
return
}
if PlayerMgrSington.GetPlayerBySnId(p.SnId) == nil {
v.Release(p.Platform, p.SnId)
logger.Logger.Infof("PlayerCacheMgr SaveCache Release snid:%v", p.SnId)
}
}
if PlayerMgrSington.GetPlayerBySnId(p.SnId) == nil {
if isSync {
for _, v := range internal.GetPlayerLoads() {
saveFunc(v)
releaseFunc(v)
}
} else {
for i := 0; i < len(internal.GetPlayerLoads()); i++ {
v := internal.GetPlayerLoads()[i]
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
saveFunc(v)
return nil
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
releaseFunc(v)
})).StartByExecutor(fmt.Sprintf("Player%v", p.SnId))
}
}
}
}
func (c *PlayerCacheMgr) ModuleName() string {
return "PlayerCacheMgr"
}
@ -249,16 +205,10 @@ func (c *PlayerCacheMgr) Update() {
for _, p := range c.playerWaitClr {
delete(c.playerMap, p.SnId)
c.Pop(p)
// 更新玩家数据
c.saveCache(p, false)
}
c.playerWaitClr = c.playerWaitClr[0:0]
}
func (c *PlayerCacheMgr) Shutdown() {
for _, v := range c.playerMap {
c.saveCache(v, true)
}
module.UnregisteModule(c)
}

View File

@ -1,7 +1,9 @@
package main
import (
"fmt"
"math/rand"
"os"
"time"
"mongo.games.com/goserver/core/basic"
@ -48,7 +50,7 @@ type PlayerMgr struct {
// 平台id:snid:真实玩家
playerOfPlatform map[string]map[int32]*Player
loading map[string]*PlayerPendingData // accountid,控制访问频率
loading map[string]*PlayerPendingData // accountid,控制访问频率;登录状态标记
}
// PlayerStatics 在线统计
@ -135,20 +137,76 @@ func (this *PlayerMgr) AddPlayer(sid int64, playerInfo *model.PlayerData, s *net
this.playerOfPlatform[player.Platform] = pp
}
logger.Logger.Tracef("###%v mount to DBSaver[AddPlayer]", player.Name)
logger.Logger.Tracef("###%v mount to DBSaver[AddPlayer]", player.SnId)
if old != nil { //删除旧的玩家
DbSaveInst.UnregisterDbSaveTask(old)
}
DbSaveInst.RegisterDbSaverTask(player)
}
internal.FirePlayerLogined(player)
return true
}
func (this *PlayerMgr) SavePlayer(p *Player, isCopy, force bool) {
if p == nil || p.isDelete {
return
}
if p.IsRob {
return
}
if !p.dirty && !force {
return
}
var pd *model.PlayerData
if isCopy {
pd = model.ClonePlayerData(p.PlayerData)
} else {
pd = p.PlayerData
}
if pd == nil {
logger.Logger.Errorf("Player Time2Save() %v pd is nil", p.SnId)
return
}
t1 := time.Now()
p.dirty = true
// 跨天任务依赖LastLogoutTime的准确性跨天任务是定时器common.ClockMgrSington触发的所以这里要用定时器的触发时间
p.LastLogoutTime = common.ClockMgrSingleton.LastTickTime
pd.LastLogoutTime = common.ClockMgrSingleton.LastTickTime
ok := true
t := task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
if !model.SavePlayerData(pd) {
// save 失败先写到json里面
model.BackupPlayerData(pd)
ok = false
}
for _, v := range internal.GetPlayerLoads() {
v.Save(pd.Platform, pd.SnId, true, force)
}
return ok
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
if saved, ok := i.(bool); ok && saved {
p.dirty = false
bak := fmt.Sprintf("%v.json", pd.AccountId)
if exist, _ := common.PathExists(bak); exist {
os.Remove(bak)
}
}
logger.Logger.Infof("Player Time2Save() %v take:%v isSuccess:%v", p.SnId, time.Now().Sub(t1), p.dirty == false)
}), "SavePlayerTask")
if b := t.StartByExecutor(fmt.Sprintf("Player%v", p.SnId)); b {
p.lastSaved = time.Now()
}
}
// DelPlayer 清除玩家缓存数据
// 一般真人是数据持久化后删除或数据没有修改,机器人不用持久化(机器人数据没有主动删除)
// 真人数据持久化后删除,机器人不用持久化(机器人数据没有主动删除)
// needSave 是否需要保存数据; 自动删除玩家机制已经保存过数据,不需要再保存;手动删除玩家需要保存数据
func (this *PlayerMgr) DelPlayer(snid int32) bool {
player, ok := this.snidMap[snid]
if !ok || player == nil {
@ -178,14 +236,18 @@ func (this *PlayerMgr) DelPlayer(snid int32) bool {
}
}
if !player.IsCacheState() {
player.OnLogoutFinish()
internal.FirePlayerLogouted[*Player, *Scene](player)
}
DbSaveInst.UnregisterDbSaveTask(player)
// 再保存一次,防止数据丢失,可能脏标记没有设置
this.SavePlayer(player, true, true)
for _, v := range internal.GetPlayerLoads() {
v.Release(player.Platform, player.SnId)
}
player.OnLogouted()
DbSaveInst.UnregisterDbSaveTask(player)
player.Save(true)
return true
}
@ -194,6 +256,9 @@ func (this *PlayerMgr) DelPlayer(snid int32) bool {
// 2.玩家网络断开
// 3.被踢掉线
func (this *PlayerMgr) DropPlayer(p *Player) {
p.SetOffline()
p.sid = 0
p.gateSess = nil
delete(this.sidMap, p.sid)
}
@ -208,12 +273,20 @@ func (this *PlayerMgr) ReholdPlayer(p *Player, newSid int64, newSess *netlib.Ses
logger.Logger.Errorf("(this *PlayerMgr) ReholdPlayer(snid=%v, new=%v)", p.SnId, newSid)
}
p.SetOnline()
p.sid = newSid
p.gateSess = newSess
p.SetOnline()
this.sidMap[newSid] = p
}
func (this *PlayerMgr) KickByPlatform(name string) {
for _, p := range this.players {
if name == "" || p.Platform == name {
p.Kick(common.KickReason_Disconnection)
}
}
}
// GetOnlinePlayer 获取玩家数据(玩家在线)
func (this *PlayerMgr) GetOnlinePlayer(id int64) *Player {
if pi, ok := this.sidMap[id]; ok {
@ -398,98 +471,29 @@ func (this *PlayerMgr) BroadcastMessageToTarget(snIds []int32, packetid int, raw
}
}
// 感兴趣所有clock event
func (this *PlayerMgr) InterestClockEvent() int {
return (1 << common.ClockEventMax) - 1
}
func (this *PlayerMgr) OnSecTimer() {
for _, player := range this.players {
utils.CatchPanic(func() {
player.OnSecTimer()
})
}
}
func (this *PlayerMgr) OnMiniTimer() {
for _, player := range this.players {
utils.CatchPanic(func() {
player.OnMiniTimer()
})
}
}
func (this *PlayerMgr) OnHourTimer() {
for _, player := range this.players {
utils.CatchPanic(func() {
player.OnHourTimer()
})
}
}
func (this *PlayerMgr) OnDayTimer() {
for _, player := range this.players {
utils.CatchPanic(func() {
player.OnDayTimer(false, true, 1)
})
}
}
func (this *PlayerMgr) OnMonthTimer() {
for _, player := range this.players {
utils.CatchPanic(func() {
player.OnMonthTimer()
})
}
}
func (this *PlayerMgr) OnWeekTimer() {
for _, player := range this.players {
utils.CatchPanic(func() {
player.OnWeekTimer()
})
}
}
func (this *PlayerMgr) OnShutdown() {
this.SaveAll()
}
// SaveAll 保存所有数据dirty=true
func (this *PlayerMgr) SaveAll() {
count := len(this.players)
start := time.Now()
saveCnt := 0
failCnt := 0
nochangeCnt := 0
logger.Logger.Info("===@PlayerMgr.SaveAll BEG@=== TotalCount:", count)
logger.Logger.Info("===@SaveAllPlayerBEGIN@=== TotalCount:", count)
for i, p := range this.players {
idx := i + 1
if p.dirty {
if model.SavePlayerData(p.PlayerData) {
logger.Logger.Infof("===@SavePlayerData %v/%v snid:%v coin:%v safebox:%v coinpayts:%v safeboxts:%v gamets:%v save [ok] @=", idx, count, p.SnId, p.Coin, p.SafeBoxCoin, p.CoinPayTs, p.SafeBoxCoinTs, p.GameCoinTs)
saveCnt++
} else {
logger.Logger.Warnf("===@SavePlayerData %v/%v snid:%v coin:%v safebox:%v coinpayts:%v safeboxts:%v gamets:%v save [error]@=", idx, count, p.SnId, p.Coin, p.SafeBoxCoin, p.CoinPayTs, p.SafeBoxCoinTs, p.GameCoinTs)
failCnt++
if model.SavePlayerData(p.PlayerData) {
logger.Logger.Infof("===@SavePlayerData %v/%v snid:%v coin:%v safebox:%v coinpayts:%v safeboxts:%v gamets:%v save [ok] @=",
idx, count, p.SnId, p.Coin, p.SafeBoxCoin, p.CoinPayTs, p.SafeBoxCoinTs, p.GameCoinTs)
for _, v := range internal.GetPlayerLoads() {
v.Save(p.Platform, p.SnId, true, true)
}
saveCnt++
} else {
logger.Logger.Infof("nochange===@SavePlayerData %v/%v snid:%v coin:%v safebox:%v coinpayts:%v safeboxts:%v gamets:%v nochange [ok]@=", idx, count, p.SnId, p.Coin, p.SafeBoxCoin, p.CoinPayTs, p.SafeBoxCoinTs, p.GameCoinTs)
nochangeCnt++
}
for _, v := range internal.GetPlayerLoads() {
v.Save(p.Platform, p.SnId, true, true)
}
}
logger.Logger.Infof("===@PlayerMgr.SaveAll END@===, total:%v saveCnt:%v failCnt:%v nochangeCnt:%v take:%v", count, saveCnt, failCnt, nochangeCnt, time.Now().Sub(start))
}
func (this *PlayerMgr) KickByPlatform(name string) {
for _, p := range this.players {
if name == "" || p.Platform == name {
p.Kickout(common.KickReason_Disconnection)
logger.Logger.Warnf("===@SavePlayerData %v/%v snid:%v coin:%v safebox:%v coinpayts:%v safeboxts:%v gamets:%v save [error]@=",
idx, count, p.SnId, p.Coin, p.SafeBoxCoin, p.CoinPayTs, p.SafeBoxCoinTs, p.GameCoinTs)
failCnt++
}
}
logger.Logger.Infof("===@SaveAllPlayerEND@===, total:%v saveCnt:%v failCnt:%v take:%v", count, saveCnt, failCnt, time.Now().Sub(start))
}
// LoadRobots 预加载机器人数据
@ -726,7 +730,6 @@ func (this *PlayerMgr) RecommendFriendRule(platform string, snid int32) []Recomm
}
func init() {
//BlackListMgrSington.RegisterObserver(PlayerMgrSington)
PlayerSubjectSign.AttachName(PlayerMgrSington)
PlayerSubjectSign.AttachHead(PlayerMgrSington)
PlayerSubjectSign.AttachHeadOutline(PlayerMgrSington)
@ -736,5 +739,51 @@ func init() {
PlayerSubjectSign.AttachHead(FriendMgrSington)
// 定时器
common.ClockMgrSingleton.RegisterSinker(PlayerMgrSington)
common.RegisterClockFunc(&common.ClockFunc{
OnSecTimerFunc: func() {
for _, player := range PlayerMgrSington.players {
utils.CatchPanic(func() {
player.OnSecTimer()
})
}
},
OnMiniTimerFunc: func() {
for _, player := range PlayerMgrSington.players {
utils.CatchPanic(func() {
player.OnMiniTimer()
})
}
},
OnHourTimerFunc: func() {
for _, player := range PlayerMgrSington.players {
utils.CatchPanic(func() {
player.OnHourTimer()
})
}
},
OnDayTimerFunc: func() {
for _, player := range PlayerMgrSington.players {
utils.CatchPanic(func() {
player.OnDayTimer(false, true, 1)
})
}
},
OnWeekTimerFunc: func() {
for _, player := range PlayerMgrSington.players {
utils.CatchPanic(func() {
player.OnWeekTimer()
})
}
},
OnMonthTimerFunc: func() {
for _, player := range PlayerMgrSington.players {
utils.CatchPanic(func() {
player.OnMonthTimer()
})
}
},
OnShutdownFunc: func() {
PlayerMgrSington.SaveAll()
},
})
}

View File

@ -14,6 +14,14 @@ const (
PROMOTER_TYPE_PROMOTE = 3 //推广员
)
type ErrorString struct {
code string
}
func (e *ErrorString) Error() string {
return e.code
}
var PromoterMgrSington = &PromoterMgr{
PromoterConfigMap: make(map[string]*PromoterConfig),
LastTicket: 0,

View File

@ -1036,7 +1036,7 @@ func init() {
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
return model.FreezeAccount(msg.Platform, player.AccountId, int(msg.Minute))
}), nil, "FreezeAccount").Start()
player.Kickout(common.KickReason_Freeze)
player.Kick(common.KickReason_Freeze)
pack.Tag = webapiproto.TagCode_SUCCESS
pack.Msg = "success"
} else {
@ -1714,7 +1714,7 @@ func init() {
//在线需要踢掉玩家
if uint(msg.BlacklistType)&BlackState_Login != 0 {
logger.Logger.Infof("found platform:%v player:%d snid in blacklist", msg.Platform, player.SnId)
player.Kickout(int32(loginproto.SSDisconnectTypeCode_SSDTC_BlackList))
player.Kick(int32(loginproto.SSDisconnectTypeCode_SSDTC_BlackList))
}
return common.ResponseTag_Ok, pack
} else {
@ -2427,7 +2427,7 @@ func init() {
}
}
p.Kickout(common.KickReason_Freeze)
p.Kick(common.KickReason_Freeze)
PlayerMgrSington.DelPlayer(p.SnId)
LoginStateMgrSington.DelAccountByAccid(p.AccountId)
}