hxp
2025-05-23 fdebf36f0d9201c6a6949a08cdfeebb718c25ce2
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBPlayerViewCache.py
@@ -18,17 +18,8 @@
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():
    
@@ -84,96 +75,35 @@
    
    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()
@@ -200,32 +130,19 @@
            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
@@ -243,9 +160,7 @@
            return
        self.__needSort = False
        self.__viewCacheList.sort(key=lambda v: (v.GetFightPowerTotal(), v.GetLV()), reverse=True)
        self.__idIndexDict = {}
        self.__serverIDRangePlayerIDDict = {}
        self.__refreshIDIndex()
        return
    
    # 保存数据 存数据库和realtimebackup
@@ -269,66 +184,7 @@
        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