From 9d9430082ec01ad0c0dcad5b4c062525c4053548 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 07 一月 2025 19:00:09 +0800
Subject: [PATCH] 10289 【越南】【英语】【砍树】【BT】运势-服务端(寻宝设定表增加配置不同的寻宝广播key)
---
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py | 242 +++++++++++++++++++++++++++++++++++++++---------
1 files changed, 195 insertions(+), 47 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py
index ce8f7c9..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,32 +281,23 @@
## 删除过期
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:
- isCross, isNeed = 0, 1
- QueryPlayerResult_PlayerMirror(curPlayer, "PackDataSyncState", [isCross, isNeed])
- return
-
-def OnPlayerLogin_CrossLogic(serverGroupID, serverID, playerID):
- ## 跨服登录逻辑
- packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
- if playerID in packDataMgr.playerPackDataDict:
- dataMsg = {"playerID":playerID}
- CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PlayerPackDataState, dataMsg, [serverGroupID])
+ if packDataMgr.IsPlayerIn(playerID):
+ QueryPlayerResult_PlayerMirror(curPlayer, "PackDataSyncState", {"PackData":1})
return
def SetNeedPackData(playerIDList):
@@ -157,7 +309,7 @@
pullPlayerIDList = []
packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
for playerID in playerIDList:
- if playerID in packDataMgr.playerPackDataDict:
+ if packDataMgr.IsPlayerIn(playerID):
continue
pullPlayerIDList.append(playerID)
@@ -312,14 +464,13 @@
pullPlayerIDList = msgData["pullPlayerIDList"]
otherServerPlayerIDList = []
- packDataDict = {}
packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
for playerID in pullPlayerIDList:
packObj = packDataMgr.GetPlayerPackObj(playerID)
# 已经有的数据先推送回去
if packObj:
- packDataDict[playerID] = packObj.PackData
- dataMsg = {"playerID":playerID, "packData":packObj.PackData, "msgInfo":msgInfo}
+ GameWorld.DebugLog("跨服有缓存玩家打包数据,直接推给子服! playerID=%s" % playerID)
+ dataMsg = {"playerID":playerID, "packData":packObj.GetPackData(), "msgInfo":msgInfo}
CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PushPlayerPackData, dataMsg, [serverGroupID])
else:
otherServerPlayerIDList.append(playerID)
@@ -339,8 +490,7 @@
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
if not curPlayer:
return
- isCross, isNeed = 1, 1
- QueryPlayerResult_PlayerMirror(curPlayer, "PackDataSyncState", [isCross, isNeed])
+ QueryPlayerResult_PlayerMirror(curPlayer, "PackDataSyncState", msgData)
return
def CrossServerMsg_PullPlayerPackData(msgData):
@@ -349,18 +499,16 @@
msgInfo = msgData["msgInfo"]
pullPlayerIDList = msgData["pullPlayerIDList"]
- needPullPlayerIDList = []
packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
for playerID in pullPlayerIDList:
packObj = packDataMgr.GetPlayerPackObj(playerID)
if packObj:
- # 本服有数据,直接推给跨服
- dataMsg = {"playerID":playerID, "packData":packObj.PackData, "msgInfo":msgInfo}
+ GameWorld.DebugLog("本服有缓存玩家打包数据,直接推给跨服! playerID=%s" % playerID)
+ dataMsg = {"playerID":playerID, "packData":packObj.GetPackData(), "msgInfo":msgInfo}
CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PlayerPackData, dataMsg)
else:
- needPullPlayerIDList.append(playerID)
+ DoPullPlayerPackData(playerID, msgInfo)
- DoPullPlayerPackData(needPullPlayerIDList, msgInfo)
return
def CrossServerMsg_PushPlayerPackData(msgData):
@@ -376,7 +524,7 @@
curPlayer.MapServer_QueryPlayerResult(0, 0, "PlayerMirror", sysMsg, len(sysMsg))
return
-def OnMGUpdatePlayerPackData(curPlayer, curPackData):
+def OnMGUpdatePlayerPackData(curPlayer, curPackData, msgInfo):
## 地图同步更新的玩家打包数据
if GameWorld.IsCrossServer():
return
@@ -385,14 +533,13 @@
packData = curPackData.PackData
if not packDataSyncState or not packData:
return
- msgInfo = eval(curPackData.PackMsg) if curPackData.PackMsg else {} # 打包数据附带的信息
# 本服需要,先更新数据
- if packDataSyncState % 10:
+ if packDataSyncState&pow(2, 0):
PyDataManager.GetDBPlayerPackDataManager().UpdPlayerPackData(playerID, packData)
# 跨服需要,同步给跨服,由跨服服务器再进一步处理
- if packDataSyncState / 10:
+ if packDataSyncState&pow(2, 1):
cacheBase = PlayerViewCache.GetSyncCrossCacheBase(curPlayer) if curPlayer else {}
dataMsg = {"playerID":playerID, "packData":packData, "cacheBase":cacheBase, "msgInfo":msgInfo}
CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PlayerPackData, dataMsg)
@@ -415,6 +562,7 @@
CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PlayerPackData, dataMsg)
return
+ PyDataManager.GetDBPlayerPackDataManager().UpdPlayerPackData(playerID, packData)
# 本服需要,汇总结果
ReuestPlayerPackDataRet(msgInfo, playerID, packData)
return
@@ -432,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