| | |
| | | import PyDataManager
|
| | | import PlayerViewCache
|
| | | import PyGameDataStruct
|
| | | import CrossChampionship
|
| | | import CrossRealmMsg
|
| | | import PlayerControl
|
| | | import ShareDefine
|
| | |
| | | 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():
|
| | | ## 玩家打包数据管理
|
| | |
|
| | |
| | | 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
|
| | |
| | | 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
|
| | |
| | | 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):
|
| | |
| | | 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
|
| | |
|
| | |
| | | ## 删除过期
|
| | |
|
| | | 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
|
| | |
|
| | |
| | | pullPlayerIDList = []
|
| | | packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
|
| | | for playerID in playerIDList:
|
| | | if playerID in packDataMgr.playerPackDataDict:
|
| | | if packDataMgr.IsPlayerIn(playerID):
|
| | | continue
|
| | | pullPlayerIDList.append(playerID)
|
| | |
|
| | |
| | | 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)
|
| | |
| | | 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)
|
| | |
| | | for mirrorID in mirrorIDList:
|
| | | packObj = packDataMgr.GetPlayerPackObj(mirrorID)
|
| | | if packObj:
|
| | | packDataDict[mirrorID] = packObj.PackData
|
| | | packDataDict[mirrorID] = packObj.GetPackData()
|
| | | continue
|
| | | pullPlayerIDList.append(mirrorID)
|
| | |
|