From 22c964784d465c77365c2495f6d43117618d8482 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期四, 26 十二月 2024 16:52:25 +0800 Subject: [PATCH] 10350 【后端】【越南】【英文】【BT】【砍树】跨服竞技场优化 --- ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py | 213 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 186 insertions(+), 27 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py index 8ec303d..56ab2e5 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py @@ -33,6 +33,7 @@ import PyDataManager import PlayerViewCache import PyGameDataStruct +import CrossChampionship import CrossRealmMsg import PlayerControl import ShareDefine @@ -40,7 +41,68 @@ import ChConfig import time +import base64 +TempDBPlayer = PyGameDataStruct.tagDBPlayer() + +def GetDBPlayerByPackData(packData): + ## 根据 curPlayer.GetPackData() 打包返回的数据获取DBPlayer数据 + TempDBPlayer.clear() + if packData: + TempDBPlayer.readData(base64.b64decode(packData)) + return TempDBPlayer + +class PlayerPackDataObj(): + + def __init__(self): + self.dbPlayerPackData = None + self.playerID = 0 + self.playerName = "" + self.accID = "" + self.lv = 0 + self.job = 0 + self.realmLV = 0 + self.face = 0 + self.facePic = 0 + self.fightPower = 0 + self.serverID = 0 + return + + def GetBaseDict(self): + return {"playerID":self.playerID, "playerName":self.playerName, "lv":self.lv, "job":self.job, + "realmLV":self.realmLV, "face":self.face, "facePic":self.facePic, "fightPower":self.fightPower} + + def UpdPackData(self, packData): + if not packData: + return + if not self.dbPlayerPackData: + self.dbPlayerPackData = PyGameDataStruct.tagDBPlayerPackData() + self.dbPlayerPackData.PlayerID = self.playerID + self.dbPlayerPackData.PackData = packData + self.dbPlayerPackData.PackDataSize = len(self.dbPlayerPackData.PackData) + self.dbPlayerPackData.UpdTime = int(time.time()) + self.Unpack() + return + + def Unpack(self): + if not self.dbPlayerPackData: + return + dbPlayer = GetDBPlayerByPackData(self.dbPlayerPackData.PackData) + self.playerID = dbPlayer.PlayerID + self.accID = dbPlayer.AccID + self.playerName = dbPlayer.PlayerName + self.lv = dbPlayer.LV + self.job = dbPlayer.Job + self.realmLV = dbPlayer.OfficialRank + self.face = dbPlayer.Face + self.facePic = dbPlayer.FacePic + self.fightPower = dbPlayer.FightPowerEx * ChConfig.Def_PerPointValue + dbPlayer.FightPower + self.serverID = GameWorld.GetAccIDServerID(self.accID) + return + + def GetPackData(self): return self.dbPlayerPackData.PackData if self.dbPlayerPackData else "" + def GetUpdTime(self): return self.dbPlayerPackData.UpdTime if self.dbPlayerPackData else 0 + class DBPlayerPackDataManager(): ## 玩家打包数据管理 @@ -49,26 +111,92 @@ return def Clear(self): - self.playerPackDataDict = {} # {playerID:tagDBPlayerPackData, ...} + self.__packDataList = [] # [PlayerPackDataObj, ...] + self.__idIndexDict = {} # {playerID:index, ...} + self.__needSort = False + self.__serverIDRangePlayerIDDict = {} # {serverIDRangeTuple:[playerID, ...], ....} return def GetPlayerPackObj(self, playerID, isAddNew=False): packDataObj = None - if playerID in self.playerPackDataDict: - packDataObj = self.playerPackDataDict[playerID] - elif isAddNew: - packDataObj = PyGameDataStruct.tagDBPlayerPackData() - packDataObj.PlayerID = playerID - self.playerPackDataDict[playerID] = packDataObj + self.__refreshIDIndex() + if playerID in self.__idIndexDict: + index = self.__idIndexDict[playerID] + if index < len(self.__packDataList): + packDataObj = self.__packDataList[index] + + if not packDataObj and isAddNew: + packDataObj = PlayerPackDataObj() + packDataObj.playerID = playerID + self.__packDataList.append(packDataObj) + self.__idIndexDict[playerID] = len(self.__packDataList) - 1 + self.__needSort = True + return packDataObj + + def GetPlayerIDListByServerIDInfo(self, serverIDList): + ## 根据服务器ID列表信息获取对应服务器ID范围的玩家ID战力排序列表 + self.Sort() + key = tuple(serverIDList) + if key not in self.__serverIDRangePlayerIDDict: + playerIDList = [] + for dataObj in self.__packDataList: + playerID = dataObj.playerID + serverID = dataObj.serverID + 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, dataObj in enumerate(self.__packDataList): + self.__idIndexDict[dataObj.playerID] = index + return self.__idIndexDict def UpdPlayerPackData(self, playerID, packData): if not packData: return packObj = self.GetPlayerPackObj(playerID, True) - packObj.UpdTime = int(time.time()) - packObj.PackData = packData - packObj.PackDataSize = len(packObj.PackData) + packObj.UpdPackData(packData) + self.__needSort = True + return packObj + + def DelPlayerPackData(self, playerID): + self.__refreshIDIndex() + index = self.__idIndexDict.pop(playerID, -1) + if index >= 0 and index < len(self.__packDataList): + self.__packDataList.pop(index) + for playerIDList in self.__serverIDRangePlayerIDDict.values(): + if playerID in playerIDList: + playerIDList.remove(playerID) + return + + def GetCount(self): return len(self.__packDataList) + def At(self, index): + dataObj = self.__packDataList[index] + if not dataObj and False: + dataObj = PlayerPackDataObj() # 不会执行到,只为了.出代码提示 + return dataObj + + def Sort(self): + ## 默认按战力倒序排 + if not self.__needSort: + return + self.__needSort = False + self.__packDataList.sort(key=lambda d: (d.fightPower), reverse=True) + self.__idIndexDict = {} + self.__serverIDRangePlayerIDDict = {} + self.__refreshIDIndex() return # 保存数据 存数据库和realtimebackup @@ -77,9 +205,12 @@ cntData = "" cnt = 0 - for dbData in self.playerPackDataDict.values(): + for index in xrange(self.GetCount()): + dataObj = self.At(index) + if not dataObj.dbPlayerPackData: + continue cnt += 1 - savaData += dbData.getBuffer() + savaData += dataObj.dbPlayerPackData.getBuffer() GameWorld.Log("Save DBPlayerPackData count :%s len=%s" % (cnt, len(savaData))) return CommFunc.WriteDWORD(cntData, cnt) + savaData @@ -94,9 +225,13 @@ for _ in xrange(cnt): dbData = PyGameDataStruct.tagDBPlayerPackData() pos += dbData.readData(datas, pos, dataslen) + playerID = dbData.PlayerID - self.playerPackDataDict[dbData.PlayerID] = dbData + packObj = self.GetPlayerPackObj(playerID, True) + packObj.dbPlayerPackData = dbData + packObj.Unpack() + self.Sort() return pos def IsSaveDB(packDataObj): @@ -104,13 +239,39 @@ if not packDataObj: return False - # 功能固定需要的 - # ... + playerID = packDataObj.playerID + + if CrossChampionship.IsChampionshipPlayer(playerID): + return True + + #跨服榜单上的默认保留 + if GameWorld.IsCrossServer(): + billboardMgr = PyDataManager.GetCrossBillboardManager() + for billboardType in ShareDefine.CrossBillboardTypeList: + groupList = billboardMgr.GetBillboardGroupList(billboardType) + for billboardType, groupValue1, groupValue2 in groupList: + billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) + if billboardObj.FindByID(playerID): + return True + + else: + pass +# NeedCheckBillBoardType = IpyGameDataPY.GetFuncEvalCfg("PlayerViewCache", 2) +# #校验玩家是否上排行榜 +# billboardMgr = GameWorld.GetBillboard() +# for BillBoardType in NeedCheckBillBoardType: +# curBillboard = billboardMgr.FindBillboard(BillBoardType) +# if not curBillboard: +# continue +# if curBillboard.FindByID(playerID): +# return True + + # 以上是相关功能需要用到的数据,必定不能删除的 maxDays = 7 # 默认7天 MaxTime = maxDays * 3600 * 24 curTime = int(time.time()) - passTime = curTime - packDataObj.UpdTime + passTime = curTime - packDataObj.GetUpdTime() if passTime < MaxTime: return True @@ -120,22 +281,22 @@ ## 删除过期 packDataMgr = PyDataManager.GetDBPlayerPackDataManager() - playerPackDataDict = packDataMgr.playerPackDataDict - for playerID, packDataObj in playerPackDataDict.items(): + for index in range(packDataMgr.GetCount())[::-1]: # 可能删数据,倒序遍历 + packDataObj = packDataMgr.At(index) if IsSaveDB(packDataObj): continue - playerPackDataDict.pop(playerID) + packDataMgr.DelPlayerPackData(packDataObj.playerID) return def IsPackDataPlayer(playerID): - return playerID in PyDataManager.GetDBPlayerPackDataManager().playerPackDataDict + return PyDataManager.GetDBPlayerPackDataManager().IsPlayerIn(playerID) def OnPlayerLogin(curPlayer): ## 本服登录逻辑 playerID = curPlayer.GetPlayerID() packDataMgr = PyDataManager.GetDBPlayerPackDataManager() - if playerID in packDataMgr.playerPackDataDict: + if packDataMgr.IsPlayerIn(playerID): QueryPlayerResult_PlayerMirror(curPlayer, "PackDataSyncState", {"PackData":1}) return @@ -148,7 +309,7 @@ pullPlayerIDList = [] packDataMgr = PyDataManager.GetDBPlayerPackDataManager() for playerID in playerIDList: - if playerID in packDataMgr.playerPackDataDict: + if packDataMgr.IsPlayerIn(playerID): continue pullPlayerIDList.append(playerID) @@ -303,15 +464,13 @@ pullPlayerIDList = msgData["pullPlayerIDList"] otherServerPlayerIDList = [] - packDataDict = {} packDataMgr = PyDataManager.GetDBPlayerPackDataManager() for playerID in pullPlayerIDList: packObj = packDataMgr.GetPlayerPackObj(playerID) # 已经有的数据先推送回去 if packObj: GameWorld.DebugLog("跨服有缓存玩家打包数据,直接推给子服! playerID=%s" % playerID) - packDataDict[playerID] = packObj.PackData - dataMsg = {"playerID":playerID, "packData":packObj.PackData, "msgInfo":msgInfo} + dataMsg = {"playerID":playerID, "packData":packObj.GetPackData(), "msgInfo":msgInfo} CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PushPlayerPackData, dataMsg, [serverGroupID]) else: otherServerPlayerIDList.append(playerID) @@ -345,7 +504,7 @@ packObj = packDataMgr.GetPlayerPackObj(playerID) if packObj: GameWorld.DebugLog("本服有缓存玩家打包数据,直接推给跨服! playerID=%s" % playerID) - dataMsg = {"playerID":playerID, "packData":packObj.PackData, "msgInfo":msgInfo} + dataMsg = {"playerID":playerID, "packData":packObj.GetPackData(), "msgInfo":msgInfo} CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PlayerPackData, dataMsg) else: DoPullPlayerPackData(playerID, msgInfo) @@ -421,7 +580,7 @@ for mirrorID in mirrorIDList: packObj = packDataMgr.GetPlayerPackObj(mirrorID) if packObj: - packDataDict[mirrorID] = packObj.PackData + packDataDict[mirrorID] = packObj.GetPackData() continue pullPlayerIDList.append(mirrorID) -- Gitblit v1.8.0