| | |
| | | import DBComm
|
| | | import DBStruct
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import DBDataMgr
|
| | | import CommFunc
|
| | | import ChConfig
|
| | | import GameObj
|
| | |
|
| | | import random
|
| | | import time
|
| | |
|
| | | Key_UpdViewCacheTick = "UpdViewCacheTick"
|
| | |
|
| | | class PlayerViewCache():
|
| | |
|
| | |
| | |
|
| | | def __init__(self):
|
| | | self.__viewCacheList = [] # [PlayerViewCache, ...]
|
| | | self.__idIndexDict = {} # {playerID:index, ...}
|
| | | self.__viewCacheDict = {} # {playerID:PlayerViewCache, ...}
|
| | | self.__needSort = False
|
| | | self.__serverIDRangePlayerIDDict = {} # {serverIDRangeTuple:[playerID, ...], ....}
|
| | | return
|
| | |
|
| | | def InitViewCacheInstance(self, dbData):
|
| | | def __InitViewCacheInstance(self, dbData):
|
| | | '''初始化功能数据实例,创建或加载数据时通用,功能一般不调用
|
| | | @param dbData: 实例对应绑定的dbData
|
| | | @return: 成功返回实例对象,失败返回None
|
| | | '''
|
| | | playerID = dbData.PlayerID
|
| | | self.__refreshIDIndex()
|
| | | if playerID in self.__idIndexDict:
|
| | | if playerID in self.__viewCacheDict:
|
| | | return
|
| | | viewCache = PlayerViewCache(dbData)
|
| | | self.__viewCacheList.append(viewCache)
|
| | | self.__idIndexDict[playerID] = len(self.__viewCacheList) - 1
|
| | | self.__viewCacheDict[playerID] = viewCache
|
| | | self.__needSort = True
|
| | | return viewCache
|
| | |
|
| | | def CheckUpdViewCache(self, playerID):
|
| | | if playerID <= ShareDefine.FackPlayerIDMax:
|
| | | return
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | lastUpdTick = curPlayer.GetDictByKey(Key_UpdViewCacheTick)
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | if lastUpdTick and tick - lastUpdTick < 60000:
|
| | | GameWorld.DebugLog("1分钟内只更新一次玩家缓存", playerID)
|
| | | return
|
| | | curPlayer.SetDict(Key_UpdViewCacheTick, tick)
|
| | | return UpdPlayerViewCache(curPlayer)
|
| | | |
| | | def FindViewCache(self, playerID, isAdd=False):
|
| | | '''查找玩家缓存,如果不存在,则会有额外逻辑,如从redis、db直接找,
|
| | | 跨服玩家从跨服取,可能延迟获得
|
| | | '''
|
| | | curCache = self.GetPlayerViewCache(playerID)
|
| | | if curCache:
|
| | | updCache = self.CheckUpdViewCache(playerID)
|
| | | if updCache:
|
| | | curCache = updCache
|
| | | |
| | | # 真实玩家
|
| | | elif playerID > ShareDefine.FackPlayerIDMax:
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | # 本服在线玩家,直接生成新数据
|
| | | if curPlayer:
|
| | | def AddPlayerViewCache(self, playerID):
|
| | | dbData = DBStruct.tagDBPlayerViewCache()
|
| | | dbData.PlayerID = playerID
|
| | | self.InitViewCacheInstance(dbData)
|
| | | UpdPlayerViewCache(curPlayer)
|
| | | |
| | | # 离线玩家
|
| | | else:
|
| | | pass
|
| | | # 本服玩家,从redis或db读取重新加载读取,换句话说,本服玩家只要获取一定有查看缓存数据
|
| | | # 跨服玩家,去子服拉取数据,理论上也一定有,但是如果需要拉数据,有一定延迟
|
| | | # 逻辑待扩展
|
| | | |
| | | # 假玩家,默认添加
|
| | | elif ShareDefine.FackPlayerIDStart <= playerID <= ShareDefine.FackPlayerIDMax:
|
| | | serverID = playerID % 100 + 1 # 1 ~ 100 服
|
| | | accID = "fake%s@test@s%s" % (playerID, serverID)
|
| | | fightPower = random.randint(1000000, 100000000) # 先随机,外层有需要的话再自己设置
|
| | | |
| | | dbData = DBStruct.tagDBPlayerViewCache()
|
| | | dbData.PlayerID = playerID
|
| | | dbData.PlayerName = "%s%s" % (GameWorld.GbkToCode("神秘道友"), playerID)
|
| | | dbData.AccID = accID
|
| | | dbData.LV = random.randint(100, 200)
|
| | | dbData.Job = random.randint(1, 2)
|
| | | dbData.RealmLV = random.randint(5, 15)
|
| | | dbData.FightPower = fightPower % ChConfig.Def_PerPointValue
|
| | | dbData.FightPowerEx = fightPower / ChConfig.Def_PerPointValue
|
| | | dbData.ServerID = serverID
|
| | | dbData.OffTime = int(time.time()) - random.randint(1, 3600 * 24 * 10) # 随机离线 0~10天
|
| | | curCache = self.InitViewCacheInstance(dbData)
|
| | | |
| | | return curCache
|
| | | return self.__InitViewCacheInstance(dbData)
|
| | |
|
| | | def GetPlayerViewCache(self, playerID):
|
| | | ## 获取玩家查看缓存,仅内存中数据,无额外逻辑
|
| | | self.__refreshIDIndex()
|
| | | viewCache = None
|
| | | if playerID in self.__idIndexDict:
|
| | | index = self.__idIndexDict[playerID]
|
| | | if index < len(self.__viewCacheList):
|
| | | viewCache = self.__viewCacheList[index]
|
| | | if playerID in self.__viewCacheDict:
|
| | | viewCache = self.__viewCacheDict[playerID]
|
| | |
|
| | | if not viewCache and False:
|
| | | viewCache = PlayerViewCache()
|
| | |
| | | self.__serverIDRangePlayerIDDict[key] = playerIDList
|
| | | return self.__serverIDRangePlayerIDDict[key]
|
| | |
|
| | | def IsPlayerIn(self, playerID):
|
| | | self.__refreshIDIndex()
|
| | | return playerID in self.__idIndexDict
|
| | | |
| | | def __refreshIDIndex(self):
|
| | | if not self.__idIndexDict:
|
| | | self.__idIndexDict = {}
|
| | | for index, viewCache in enumerate(self.__viewCacheList):
|
| | | self.__idIndexDict[viewCache.GetPlayerID()] = index
|
| | | return self.__idIndexDict
|
| | | |
| | | def DelPlayerViewCache(self, playerID):
|
| | | self.__refreshIDIndex()
|
| | | index = self.__idIndexDict.pop(playerID, -1)
|
| | | if index >= 0 and index < len(self.__viewCacheList):
|
| | | self.__viewCacheList.pop(index)
|
| | | viewCache = self.__viewCacheDict.pop(playerID, None)
|
| | | if viewCache in self.__viewCacheList:
|
| | | self.__viewCacheList.remove(viewCache)
|
| | | for playerIDList in self.__serverIDRangePlayerIDDict.values():
|
| | | if playerID in playerIDList:
|
| | | playerIDList.remove(playerID)
|
| | | self.__idIndexDict = {}
|
| | | self.__serverIDRangePlayerIDDict = {}
|
| | | return
|
| | |
|
| | | def DelAllCache(self):
|
| | | self.__viewCacheList = []
|
| | | self.__idIndexDict = {}
|
| | | self.__viewCacheDict = {}
|
| | | self.__needSort = False
|
| | | self.__serverIDRangePlayerIDDict = {}
|
| | | return
|
| | |
| | | return
|
| | | self.__needSort = False
|
| | | self.__viewCacheList.sort(key=lambda v: (v.GetFightPowerTotal(), v.GetLV()), reverse=True)
|
| | | self.__idIndexDict = {}
|
| | | self.__serverIDRangePlayerIDDict = {}
|
| | | self.__refreshIDIndex()
|
| | | return
|
| | |
|
| | | # 保存数据 存数据库和realtimebackup
|
| | |
| | | for _ in xrange(cnt):
|
| | | dbData = DBStruct.tagDBPlayerViewCache()
|
| | | pos += dbData.readData(datas, pos, dataslen)
|
| | | self.InitViewCacheInstance(dbData)
|
| | | self.__InitViewCacheInstance(dbData)
|
| | |
|
| | | self.Sort()
|
| | | return pos
|
| | | |
| | | def OnPlayerLogout(curPlayer):
|
| | | if curPlayer.GetLV() >= 10:
|
| | | UpdPlayerViewCache(curPlayer)
|
| | | |
| | | return
|
| | |
|
| | | def UpdPlayerViewCache(curPlayer, isOffline=False):
|
| | | '''更新玩家查看缓存数据,更新时机由外层自己判断,这里只做更新逻辑
|
| | | 1. 下线时强制更新一次,上线暂不更新,上线时由各功能如果有需要用到触发更新
|
| | | 2. 有需要用到缓存数据时,如果玩家在线,1分钟内多次获取时最多更新一次,没有获取缓存数据则不更新
|
| | | '''
|
| | | if not curPlayer:
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | curCache = DBDataMgr.GetPlayerViewCacheMgr().GetPlayerViewCache(playerID)
|
| | | if not curCache:
|
| | | return
|
| | | |
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | curPlayer.SetDict(Key_UpdViewCacheTick, tick)
|
| | | GameWorld.DebugLog("更新玩家查看缓存数据! isOffline=%s" % isOffline, playerID)
|
| | | curCache.SetAccID(curPlayer.GetAccID())
|
| | | curCache.SetPlayerName(curPlayer.GetPlayerName())
|
| | | curCache.SetLV(curPlayer.GetLV())
|
| | | curCache.SetJob(curPlayer.GetJob())
|
| | | curCache.SetRealmLV(curPlayer.GetOfficialRank())
|
| | | curCache.SetFace(curPlayer.GetFace())
|
| | | curCache.SetFacePic(curPlayer.GetFacePic())
|
| | | curCache.SetFamilyID(curPlayer.GetFamilyID())
|
| | | curCache.SetFamilyName(curPlayer.GetFamilyName())
|
| | | curCache.SetFamilyEmblemID(PlayerControl.GetFamilyEmblemID(curPlayer))
|
| | | curCache.SetTitleID(PlayerControl.GetTitleID(curPlayer))
|
| | | curCache.SetFightPowerTotal(PlayerControl.GetFightPower(curPlayer))
|
| | | curCache.SetServerID(GameWorld.GetPlayerServerID(curPlayer))
|
| | | if isOffline:
|
| | | curCache.SetOffTime(int(time.time()))
|
| | | |
| | | plusDict = curCache.GetPlusDict()
|
| | | |
| | | #战斗属性
|
| | | plusDict.update({
|
| | | "MinAtk":curPlayer.GetMinAtk(),
|
| | | "MaxAtk":curPlayer.GetMaxAtk(),
|
| | | "Def":curPlayer.GetDef(),
|
| | | "MaxHP":GameObj.GetMaxHP(curPlayer),
|
| | | "Hit":curPlayer.GetHit(),
|
| | | "Miss":curPlayer.GetMiss(),
|
| | | "SuperHitRate":curPlayer.GetSuperHitRate(), # 暴击率
|
| | | })
|
| | | |
| | | # 功能数据
|
| | | |
| | | # 其他
|
| | | |
| | | return curCache
|
| | |
|
| | | |