#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package Script.DB.StructData.DBPlayerViewCache # # @todo:DBÍæ¼Ò²é¿´»º´æ # @author hxp # @date 2025-05-09 # @version 1.0 # # ÏêϸÃèÊö: DBÍæ¼Ò²é¿´»º´æ # #------------------------------------------------------------------------------- #"""Version = 2025-05-09 12:20""" #------------------------------------------------------------------------------- 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, dbData=None): self.__dbData = DBStruct.tagDBPlayerViewCache() if not dbData else dbData self.__plusDict = DBComm.UserDataDict(self.__dbData, "PlusData", "PlusDataSize", True) return def GetPlayerID(self): return self.__dbData.PlayerID def SetPlayerID(self, playerID): self.__dbData.PlayerID = playerID def GetAccID(self): return self.__dbData.AccID def SetAccID(self, accID): self.__dbData.AccID = accID def GetPlayerName(self): return self.__dbData.PlayerName def SetPlayerName(self, playerName): self.__dbData.PlayerName = playerName def GetLV(self): return self.__dbData.LV def SetLV(self, lv): self.__dbData.LV = lv def GetJob(self): return self.__dbData.Job def SetJob(self, job): self.__dbData.Job = job def GetRealmLV(self): return self.__dbData.RealmLV def SetRealmLV(self, realmLV): self.__dbData.RealmLV = realmLV def GetFace(self): return self.__dbData.Face def SetFace(self, face): self.__dbData.Face = face def GetFacePic(self): return self.__dbData.FacePic def SetFacePic(self, facePic): self.__dbData.FacePic = facePic def GetFamilyID(self): return self.__dbData.FamilyID def SetFamilyID(self, familyID): self.__dbData.FamilyID = familyID def GetFamilyName(self): return self.__dbData.FamilyName def SetFamilyName(self, familyName): self.__dbData.FamilyName = familyName def GetFamilyEmblemID(self): return self.__dbData.FamilyEmblemID def SetFamilyEmblemID(self, familyEmblemID): self.__dbData.FamilyEmblemID = familyEmblemID def GetTitleID(self): return self.__dbData.TitleID def SetTitleID(self, titleID): self.__dbData.TitleID = titleID def GetFightPower(self): return self.__dbData.FightPower def GetFightPowerEx(self): return self.__dbData.FightPowerEx def GetFightPowerTotal(self): return self.__dbData.FightPowerEx * ChConfig.Def_PerPointValue + self.__dbData.FightPower def SetFightPowerTotal(self, fightPowerTotal): self.__dbData.FightPower = fightPowerTotal % ChConfig.Def_PerPointValue self.__dbData.FightPowerEx = fightPowerTotal / ChConfig.Def_PerPointValue return def GetServerID(self): return self.__dbData.ServerID def SetServerID(self, serverID): self.__dbData.ServerID = serverID def GetOffTime(self): return self.__dbData.OffTime def SetOffTime(self, offTime): self.__dbData.OffTime = offTime def GetPlusDict(self): return self.__plusDict.GetData() def GetPlusData(self): return self.__plusDict.ToString() def GetBuffer(self): self.__plusDict.ToString() return self.__dbData.getBuffer() ## ----------------------------------------------------------------------- class PlayerViewCacheMgr(): def __init__(self): self.__viewCacheList = [] # [PlayerViewCache, ...] self.__idIndexDict = {} # {playerID:index, ...} self.__needSort = False self.__serverIDRangePlayerIDDict = {} # {serverIDRangeTuple:[playerID, ...], ....} return def InitViewCacheInstance(self, dbData): '''³õʼ»¯¹¦ÄÜÊý¾ÝʵÀý£¬´´½¨»ò¼ÓÔØÊý¾ÝʱͨÓ㬹¦ÄÜÒ»°ã²»µ÷Óà @param dbData: ʵÀý¶ÔÓ¦°ó¶¨µÄdbData @return: ³É¹¦·µ»ØÊµÀý¶ÔÏó£¬Ê§°Ü·µ»ØNone ''' playerID = dbData.PlayerID self.__refreshIDIndex() if playerID in self.__idIndexDict: return viewCache = PlayerViewCache(dbData) self.__viewCacheList.append(viewCache) self.__idIndexDict[playerID] = len(self.__viewCacheList) - 1 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: 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 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 not viewCache and False: viewCache = PlayerViewCache() return viewCache def GetPlayerIDListByServerIDInfo(self, serverIDList): ## ¸ù¾Ý·þÎñÆ÷IDÁбíÐÅÏ¢»ñÈ¡¶ÔÓ¦·þÎñÆ÷ID·¶Î§µÄÍæ¼ÒIDÕ½Á¦ÅÅÐòÁбí if serverIDList == None: return [] self.Sort() key = tuple(serverIDList) if key not in self.__serverIDRangePlayerIDDict: playerIDList = [] for viewCache in self.__viewCacheList: playerID = viewCache.GetPlayerID() serverID = viewCache.GetServerID() for idInfo in serverIDList: if (isinstance(idInfo, int) and serverID == idInfo) \ or ((isinstance(idInfo, tuple) or isinstance(idInfo, list)) \ and len(idInfo) == 2 and idInfo[0] <= serverID <= idInfo[1]): playerIDList.append(playerID) GameWorld.DebugLog("ÖØÐ¼ÓÔØÇø·þÍæ¼Ò²é¿´»º´æIDÁбí: %s, %s, %s" % (key, len(playerIDList), playerIDList)) 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) for playerIDList in self.__serverIDRangePlayerIDDict.values(): if playerID in playerIDList: playerIDList.remove(playerID) self.__idIndexDict = {} self.__serverIDRangePlayerIDDict = {} return def GetCount(self): return len(self.__viewCacheList) def At(self, index): viewCache = self.__viewCacheList[index] if not viewCache and False: viewCache = PlayerViewCache() # ²»»áÖ´Ðе½£¬Ö»ÎªÁË.³ö´úÂëÌáʾ return viewCache def Sort(self): ## ĬÈϰ´Õ½Á¦µ¹ÐòÅÅ if not self.__needSort: return self.__needSort = False self.__viewCacheList.sort(key=lambda v: (v.GetFightPowerTotal(), v.GetLV()), reverse=True) self.__idIndexDict = {} self.__serverIDRangePlayerIDDict = {} self.__refreshIDIndex() return # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup def GetSaveData(self): savaData = "" cntData = "" cnt = 0 for dbData in self.__viewCacheList: cnt += 1 savaData += dbData.GetBuffer() GameWorld.Log("Save DBPlayerViewCache count :%s len=%s" % (cnt, len(savaData))) return CommFunc.WriteDWORD(cntData, cnt) + savaData # ´ÓÊý¾Ý¿âÔØÈëÊý¾Ý def LoadPyGameData(self, datas, pos, dataslen): cnt, pos = CommFunc.ReadDWORD(datas, pos) GameWorld.Log("Load DBPlayerViewCache count :%s" % cnt) for _ in xrange(cnt): dbData = DBStruct.tagDBPlayerViewCache() pos += dbData.readData(datas, pos, dataslen) 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