From 44bcd51874e364012946b5f34dd7bb166d86edfb Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期六, 31 八月 2024 00:16:46 +0800 Subject: [PATCH] 10130 【后端】福地争夺资源功能(剩余时间为0报错防范;) --- ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py | 430 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 363 insertions(+), 67 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py index 711cc8a..5fb24a9 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py @@ -28,8 +28,6 @@ import operator import time -Def_CrossBillboard_MaxDataCount = 100 # 跨服榜单数据最大条数暂固定最大为100条,如有需要调整需针对实际情况进行评估(如数据同步、同步封包等) - class CrossBillboardManager(object): ## 跨服排行榜管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效 @@ -60,6 +58,13 @@ billboardObj = CrossBillboard(billboardType, groupValue1, groupValue2) self.__billboardDict[key] = billboardObj return billboardObj + + def RemoveBillboard(self, billboardType): + ## 移除某个类型的榜单所有数据 + for key in self.__billboardDict.keys(): + if key[0] == billboardType: + self.__billboardDict.pop(key) + return # 保存数据 存数据库和realtimebackup def GetSaveData(self): @@ -105,10 +110,14 @@ self.__billboardType = billboardType self.__groupValue1 = groupValue1 self.__groupValue2 = groupValue2 + self.__maxCount = ShareDefine.CrossBillboard_MaxDataCount.get(billboardType, 100) self.__crossServerDataVer = 0 # 主服榜单数据版本 self.__clientServerDataVer = 0 # 子服榜单数据版本 self.__billboardList = [] # [tagDBCrossBillboard, ...] + self.__idIndexDict = {} # {id:index, ...} self.__idOrderDict = {} # {id:名次, ...} + self.__orderRuleList = None + self.__sortDelay = False # 是否需要延迟排序 return def GetBillboardType(self): return self.__billboardType @@ -116,20 +125,40 @@ def GetGroupValue2(self): return self.__groupValue2 def ClearData(self): - GameWorld.Log("CrossBillboard ClearData billboardType=%s,groupValue1=%s,groupValue2=%s" - % (self.__billboardType, self.__groupValue1, self.__groupValue2)) + GameWorld.Log("CrossBillboard ClearData billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s" + % (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList))) if GameWorld.IsCrossServer(): - self.SaveDRData() + self.SaveDRData("Clear") self.__billboardList = [] # [tagDBCrossBillboard, ...] self.__idOrderDict = {} # {id:名次, ...} + self.__idIndexDict = {} self.UpdCrossServerDataVer(0) return def SortData(self): + GameWorld.DebugLog("跨服榜单排序: billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s" + % (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList))) self.__billboardList.sort(key=operator.attrgetter("CmpValue", "CmpValue2", "CmpValue3"), reverse=True) self.__idOrderDict = {} # 排序后重置,下次查询时更新并缓存 + self.__idIndexDict = {} + self.__sortDelay = False self.UpdCrossServerDataVer() + return + + def SetDelaySort(self): + ## 设置延迟排序 + GameWorld.DebugLog("跨服榜单设置延迟排序: billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s" + % (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList))) + self.__sortDelay = True + self.UpdCrossServerDataVer() + return + + def DoDelaySort(self): + ## 延迟排序 + if not self.__sortDelay: + return + self.SortData() return def AddBillboardData(self, billboardData): @@ -146,43 +175,103 @@ @param findID: 查找的ID @return: None or PyGameDataStruct.tagDBCrossBillboard() ''' - idOrderDict = self.GetIDOrderDict() - if findID not in idOrderDict: + self.GetIDOrderDict() + if findID not in self.__idIndexDict: return None - order = idOrderDict[findID] - return self.__billboardList[order - 1] + idIndex = self.__idIndexDict[findID] + if idIndex >= len(self.__billboardList): + return None + return self.__billboardList[idIndex] - def SaveDRData(self): + def IndexOfByID(self, findID): + ''' 根据ID查询所在榜单索引 + @param findID: 查找的ID + @return: -1 or >=0 + ''' + self.GetIDOrderDict() + if findID not in self.__idIndexDict: + return -1 + idIndex = self.__idIndexDict[findID] + return idIndex + + def SaveDRData(self, eventName="", addDataDict={}): ## 记录流向数据 - eventTypeName = "CrossBillboard_%s" % (self.__billboardType) - drDict = {"BillboardType":self.__billboardType, "GroupValue1":self.__groupValue1, "GroupValue2":self.__groupValue2, - "DataCount":len(self.__billboardList)} - DataRecordPack.SendEventPack(eventTypeName, drDict) - for billboardData in self.__billboardList: - dataDict = {"BillboardType":billboardData.BillboardType, "GroupValue1":billboardData.GroupValue1, - "GroupValue2":billboardData.GroupValue2, "Type2":billboardData.Type2, - "ID":billboardData.ID, "ID2":billboardData.ID2, + + self.DoDelaySort() + dataCount = len(self.__billboardList) + if not dataCount: + return + + idOrderDict = self.GetIDOrderDict() + serverTime = GameWorld.GetServerTime() + timeStr = "%02d%02d%02d%s" % (serverTime.hour, serverTime.minute, serverTime.second, str(serverTime.microsecond)[:3]) + eventTypeStr = "Billboard_%s_%s_%s_%s_%s" % (self.__billboardType, self.__groupValue1, self.__groupValue2, eventName, timeStr) + + dataDict = {"BillboardType":self.__billboardType, "DataCount":dataCount, "addDataDict":addDataDict, + "GroupValue1":self.__groupValue1, "GroupValue2":self.__groupValue2} + DataRecordPack.SendEventPack(eventTypeStr, dataDict) + + for index, billboardData in enumerate(self.__billboardList): + rank = idOrderDict.get(billboardData.ID, index + 1) + dataDict = {"Type2":billboardData.Type2, "Rank":rank, "Index":index, + "ID":billboardData.ID, "ID2":billboardData.ID2, "Name1":billboardData.Name1, "Name2":billboardData.Name2, "Value1":billboardData.Value1, "Value2":billboardData.Value2, + "Value3":billboardData.Value3, "Value4":billboardData.Value4, + "Value5":billboardData.Value5, "Value6":billboardData.Value6, + "Value7":billboardData.Value7, "Value8":billboardData.Value8, "CmpValue":billboardData.CmpValue, "CmpValue2":billboardData.CmpValue2, - "CmpValue3":billboardData.CmpValue3} - DataRecordPack.SendEventPack(eventTypeName, dataDict) + "CmpValue3":billboardData.CmpValue3, "UserData":billboardData.UserData} + DataRecordPack.SendEventPack(eventTypeStr, dataDict) return def GetBillboardDataList(self): return self.__billboardList def GetIDOrderDict(self): ## 获取ID对应名次字典 # @return: {ID:名次, ...} 名次从1开始 - if not self.__idOrderDict: - for order, billboardData in enumerate(self.__billboardList, 1): - self.__idOrderDict[billboardData.ID] = order + if not self.__idOrderDict or not self.__idIndexDict: + self.__idOrderDict = {} + self.__idIndexDict = {} + if self.__orderRuleList: + billboardDataCount = self.GetCount() + rankPre = 0 + billboardIndex = 0 + for rank, needCmpValue in self.__orderRuleList: + orderCountTotal = rank - rankPre # 奖励名次数量 + rankPre = rank + for index in xrange(billboardIndex, billboardDataCount): + if orderCountTotal <= 0: + break + billboardData = self.At(index) + if billboardData.CmpValue < needCmpValue: + break + orderReal = rank - orderCountTotal + 1 + self.__idOrderDict[billboardData.ID] = orderReal + orderCountTotal -= 1 + billboardIndex += 1 + for order, billboardData in enumerate(self.__billboardList, 1): + self.__idIndexDict[billboardData.ID] = order - 1 + else: + for order, billboardData in enumerate(self.__billboardList, 1): + self.__idOrderDict[billboardData.ID] = order + self.__idIndexDict[billboardData.ID] = order - 1 return self.__idOrderDict + def SetOrderRuleList(self, orderRuleList): + ## 排名所需值规则列表 + # @param orderRuleList: 排名所需值规则列表 [[order, needCmpValue], ...] + self.__orderRuleList = orderRuleList + self.__idOrderDict = {} # 设置后需重置,可能配置规则变化了导致实际排名可能变化 + self.__idIndexDict = {} + GameWorld.Log("设置排名所需值规则列表: billboardType=%s,groupValue1=%s,groupValue2=%s, %s" + % (self.__billboardType, self.__groupValue1, self.__groupValue2, orderRuleList)) + return + def GetCount(self): return len(self.__billboardList) - def GetMaxCount(self): return Def_CrossBillboard_MaxDataCount + def GetMaxCount(self): return self.__maxCount def At(self, i): return self.__billboardList[i] - def IsFull(self): return len(self.__billboardList) >= Def_CrossBillboard_MaxDataCount + def IsFull(self): return len(self.__billboardList) >= self.__maxCount def UpdCrossServerDataVer(self, version=None): ## 更新跨服榜单数据版本号,用于跨服主服、子服验证数据版本,同步榜单数据用 @@ -191,7 +280,7 @@ if version == None: version = int(time.time()) self.__crossServerDataVer = version - SyncCrossBillboardToClientServer(self.__billboardType, self.__groupValue1, self.__groupValue2) + #SyncCrossBillboardToClientServer(self.__billboardType, self.__groupValue1, self.__groupValue2) return def GetCrossServerDataVer(self): return self.__crossServerDataVer @@ -213,8 +302,9 @@ if syncBillboardList != None: self.__billboardList = self.__billboardList[:len(syncBillboardList)] # 直接用本服以后的排行数据实例clear后覆盖更新,不足的创建新实例 self.__idOrderDict = {} + self.__idIndexDict = {} for i, syncData in enumerate(syncBillboardList): - ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3 = syncData + ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3, Value3, Value4, Value5, Value6, Value7, Value8, UserData = syncData if i < len(self.__billboardList): billboardData = self.__billboardList[i] billboardData.clear() @@ -232,11 +322,20 @@ billboardData.Type2 = Type2 billboardData.Value1 = Value1 billboardData.Value2 = Value2 + billboardData.Value3 = Value3 + billboardData.Value4 = Value4 + billboardData.Value5 = Value5 + billboardData.Value6 = Value6 + billboardData.Value7 = Value7 + billboardData.Value8 = Value8 + billboardData.UserData = UserData + billboardData.DataLen = len(billboardData.UserData) billboardData.CmpValue = CmpValue billboardData.CmpValue2 = CmpValue2 billboardData.CmpValue3 = CmpValue3 self.__idOrderDict[ID] = i + 1 + self.__idIndexDict[ID] = i self.__clientServerDataVer = crossServerDataVer @@ -245,10 +344,96 @@ def CopyBillboardOnDay(): billboardMgr = PyDataManager.GetCrossBillboardManager() for billboardType in ShareDefine.CrossBillboardTypeList: + if billboardType in [ShareDefine.Def_CBT_BossTrialSubmitBak, ShareDefine.Def_CBT_BossTrialSubmitFamilyBak]: + continue groupList = billboardMgr.GetBillboardGroupList(billboardType) for billboardType, groupValue1, groupValue2 in groupList: billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) - billboardObj.SaveDRData() + billboardObj.SaveDRData("OnDay") + return + +def OnMinuteProcess(): + billboardMgr = PyDataManager.GetCrossBillboardManager() + for billboardType in ShareDefine.CrossBillboardTypeList: + groupList = billboardMgr.GetBillboardGroupList(billboardType) + for billboardType, groupValue1, groupValue2 in groupList: + billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) + billboardObj.DoDelaySort() + return + +def CopyBillboard(fromBillboardType, toBillboardType): + ## 将某个类型的榜单完全拷贝到其他榜单 - 一般用于备份、转移数据 + + billboardMgr = PyDataManager.GetCrossBillboardManager() + billboardMgr.RemoveBillboard(toBillboardType) # 默认清空目标榜单 + + groupList = billboardMgr.GetBillboardGroupList(fromBillboardType) + for billboardType, groupValue1, groupValue2 in groupList: + frbillboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) + toBillboardObj = billboardMgr.GetCrossBillboard(toBillboardType, groupValue1, groupValue2) + GameWorld.Log("CopyCrossBillboard: billboardType=%s,toBillboardType=%s,groupValue1=%s,groupValue2=%s" + % (billboardType, toBillboardType, groupValue1, groupValue2)) + for frbillboardData in frbillboardObj.GetBillboardDataList(): + tobillboardData = PyGameDataStruct.tagDBCrossBillboard() + tobillboardData.GroupValue1 = groupValue1 + tobillboardData.GroupValue2 = groupValue2 + tobillboardData.BillboardType = toBillboardType + tobillboardData.ID = frbillboardData.ID + tobillboardData.ID2 = frbillboardData.ID2 + tobillboardData.Name1 = frbillboardData.Name1 + tobillboardData.Name2 = frbillboardData.Name2 + tobillboardData.Type2 = frbillboardData.Type2 + tobillboardData.Value1 = frbillboardData.Value1 + tobillboardData.Value2 = frbillboardData.Value2 + tobillboardData.Value3 = frbillboardData.Value3 + tobillboardData.Value4 = frbillboardData.Value4 + tobillboardData.Value5 = frbillboardData.Value5 + tobillboardData.Value6 = frbillboardData.Value6 + tobillboardData.Value7 = frbillboardData.Value7 + tobillboardData.Value8 = frbillboardData.Value8 + tobillboardData.UserData = frbillboardData.UserData + tobillboardData.DataLen = len(tobillboardData.UserData) + tobillboardData.CmpValue = frbillboardData.CmpValue + tobillboardData.CmpValue2 = frbillboardData.CmpValue2 + tobillboardData.CmpValue3 = frbillboardData.CmpValue3 + toBillboardObj.AddBillboardData(tobillboardData) + + return + +def CopyBillboardEx(fromBillboardType, toBillboardType, groupValue1, groupValue2=0): + ## 将某个类型的榜单完全拷贝到其他榜单 - 一般用于备份、转移数据 + + billboardMgr = PyDataManager.GetCrossBillboardManager() + frbillboardObj = billboardMgr.GetCrossBillboard(fromBillboardType, groupValue1, groupValue2) + toBillboardObj = billboardMgr.GetCrossBillboard(toBillboardType, groupValue1, groupValue2) + toBillboardObj.ClearData() + GameWorld.Log("CopyBillboardEx: fromBillboardType=%s,toBillboardType=%s,groupValue1=%s,groupValue2=%s" + % (fromBillboardType, toBillboardType, groupValue1, groupValue2)) + for frbillboardData in frbillboardObj.GetBillboardDataList(): + tobillboardData = PyGameDataStruct.tagDBCrossBillboard() + tobillboardData.GroupValue1 = groupValue1 + tobillboardData.GroupValue2 = groupValue2 + tobillboardData.BillboardType = toBillboardType + tobillboardData.ID = frbillboardData.ID + tobillboardData.ID2 = frbillboardData.ID2 + tobillboardData.Name1 = frbillboardData.Name1 + tobillboardData.Name2 = frbillboardData.Name2 + tobillboardData.Type2 = frbillboardData.Type2 + tobillboardData.Value1 = frbillboardData.Value1 + tobillboardData.Value2 = frbillboardData.Value2 + tobillboardData.Value3 = frbillboardData.Value3 + tobillboardData.Value4 = frbillboardData.Value4 + tobillboardData.Value5 = frbillboardData.Value5 + tobillboardData.Value6 = frbillboardData.Value6 + tobillboardData.Value7 = frbillboardData.Value7 + tobillboardData.Value8 = frbillboardData.Value8 + tobillboardData.UserData = frbillboardData.UserData + tobillboardData.DataLen = len(tobillboardData.UserData) + tobillboardData.CmpValue = frbillboardData.CmpValue + tobillboardData.CmpValue2 = frbillboardData.CmpValue2 + tobillboardData.CmpValue3 = frbillboardData.CmpValue3 + toBillboardObj.AddBillboardData(tobillboardData) + return #// C0 04 查看跨服排行榜 #tagCGViewCrossBillboard @@ -259,6 +444,9 @@ # BYTE Type; //榜单类型 # BYTE GroupValue1; // 分组值1 # BYTE GroupValue2; // 分组值2,与分组值1组合归为同组榜单数据 +# DWORD StartIndex; //查看的起始名次索引, 默认0 +# BYTE WatchCnt; //查看条数,默认20,最大不超过100 +# DWORD WatchID; //查看指定ID名次前后,如玩家ID、家族ID等 #}; def OnViewCrossBillboard(index, clientData, tick): curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) @@ -266,21 +454,20 @@ return playerID = curPlayer.GetPlayerID() billboardType, groupValue1, groupValue2 = clientData.Type, clientData.GroupValue1, clientData.GroupValue2 + startIndex = clientData.StartIndex + watchCnt = clientData.WatchCnt + watchID = clientData.WatchID if billboardType not in ShareDefine.CrossBillboardTypeList: return - billboardMgr = PyDataManager.GetCrossBillboardManager() - billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) + # 支持分页查询,改为直接查跨服服务器 GameWorld.DebugLog("玩家请求查看跨服排行榜: billboardType=%s,groupValue1=%s,groupValue2=%s" % (billboardType, groupValue1, groupValue2)) - if not billboardObj.CheckClientServerDataVer(): - SyncCrossBillboardToPlayer(curPlayer, billboardType, groupValue1, groupValue2, billboardObj.GetBillboardDataList()) - return # 请求查询跨服服务器 dataMsg = {"BillboardType":billboardType, "GroupValue1":groupValue1, "GroupValue2":groupValue2, - "QueryData":{"EventName":"View", "PlayerID":playerID}} + "QueryData":{"EventName":"View", "PlayerID":playerID, "StartIndex":startIndex, "WatchCnt":watchCnt, "WatchID":watchID}} CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_QueryBillboard, dataMsg) return @@ -303,15 +490,47 @@ queryData = {} billboardMgr = PyDataManager.GetCrossBillboardManager() billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) + billboardObj.DoDelaySort() + idOrderDict = billboardObj.GetIDOrderDict() crossServerDataVer = billboardObj.GetCrossServerDataVer() msgData = {"BillboardType":billboardType, "GroupValue1":groupValue1, "GroupValue2":groupValue2, "QueryData":queryData, "CrossServerDataVer":crossServerDataVer} # 有查询数据时才同步榜单数据列表,否则只同步数据版本号 if queryData: + #playerID = queryData.get("PlayerID", 0) + startIndex = queryData.get("StartIndex", 0) + watchCnt = queryData.get("WatchCnt", 0) + watchID = queryData.get("WatchID", 0) + + count = billboardObj.GetCount() + endIndex = 0 + # 查看自己前后名次 + if watchID: + playerIndex = billboardObj.IndexOfByID(watchID) + if playerIndex != -1: + # 前5后4,首尾补足10条记录 + endIndex = min(playerIndex + 5, count) + startIndex = max(0, endIndex - 10) + endIndex = min(endIndex + (10 - (endIndex - startIndex)), count) + else: + startIndex = 0 + + # 指定索引分页查看 + else: + startIndex = max(startIndex, 0) + startIndex = min(startIndex, count) + watchCnt = 20 if not watchCnt else min(watchCnt, 100) # 默认20,最多100 + endIndex = min(startIndex + watchCnt, count) + syncBillboardList = [] - billboardList = billboardObj.GetBillboardDataList() - for billboardData in billboardList: + for index in xrange(startIndex, endIndex): + + if startIndex < 0 or index >= count: + break + + billboardData = billboardObj.At(index) + ID = billboardData.ID ID2 = billboardData.ID2 Name1 = billboardData.Name1 @@ -319,10 +538,18 @@ Type2 = billboardData.Type2 Value1 = billboardData.Value1 Value2 = billboardData.Value2 + Value3 = billboardData.Value3 + Value4 = billboardData.Value4 + Value5 = billboardData.Value5 + Value6 = billboardData.Value6 + Value7 = billboardData.Value7 + Value8 = billboardData.Value8 + UserData = billboardData.UserData CmpValue = billboardData.CmpValue CmpValue2 = billboardData.CmpValue2 CmpValue3 = billboardData.CmpValue3 - syncBillboardList.append([ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3]) + orderIndex = idOrderDict.get(ID, index + 1) - 1 + syncBillboardList.append([orderIndex, ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3, Value3, Value4, Value5, Value6, Value7, Value8, UserData]) msgData["BillboardDataList"] = syncBillboardList CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_SyncBillboard, msgData, serverGroupIDList) @@ -338,16 +565,16 @@ GameWorld.DebugLog("收到跨服服务器同步的排行榜信息: billboardType=%s,groupValue1=%s,groupValue2=%s,crossServerDataVer=%s" % (billboardType, groupValue1, groupValue2, crossServerDataVer)) - billboardMgr = PyDataManager.GetCrossBillboardManager() - billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) - billboardObj.UpdClientServerBillboard(crossServerDataVer, syncBillboardList) + #billboardMgr = PyDataManager.GetCrossBillboardManager() + #billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) + #billboardObj.UpdClientServerBillboard(crossServerDataVer, syncBillboardList) queryData = msgData.get("QueryData") if not queryData: return eventName = queryData.get("EventName") - eventData = queryData.get("EventData") + #eventData = queryData.get("EventData") queryPlayerID = queryData.get("PlayerID", 0) if not eventName or not queryPlayerID: return @@ -357,33 +584,46 @@ return if eventName == "View": - SyncCrossBillboardToPlayer(queryPlayer, billboardType, groupValue1, groupValue2, billboardObj.GetBillboardDataList()) - else: - idOrderDict = billboardObj.GetIDOrderDict() - order = idOrderDict.get(queryPlayerID, 0) - sysMsg = str([billboardType, groupValue1, groupValue2, eventName, eventData, order]) - queryPlayer.MapServer_QueryPlayerResult(0, 0, "CrossBillboardOrder", sysMsg, len(sysMsg)) + watchID = queryData.get("WatchID", 0) + SyncCrossBillboardToPlayer(queryPlayer, billboardType, groupValue1, groupValue2, syncBillboardList, watchID) + #else: + # idOrderDict = billboardObj.GetIDOrderDict() + # order = idOrderDict.get(queryPlayerID, 0) + # sysMsg = str([billboardType, groupValue1, groupValue2, eventName, eventData, order]) + # queryPlayer.MapServer_QueryPlayerResult(0, 0, "CrossBillboardOrder", sysMsg, len(sysMsg)) return -def SyncCrossBillboardToPlayer(curPlayer, billboardType, groupValue1, groupValue2, billboardList): +def SyncCrossBillboardToPlayer(curPlayer, billboardType, groupValue1, groupValue2, billboardList, watchID): ## 同步给玩家跨服榜单 billboardInfo = ChPyNetSendPack.tagGCCrossBillboardInfo() billboardInfo.Type = billboardType billboardInfo.GroupValue1 = groupValue1 billboardInfo.GroupValue2 = groupValue2 + billboardInfo.WatchID = watchID billboardInfo.CrossBillboardDataList = [] - for billboardData in billboardList: + for dataInfo in billboardList: + orderIndex, ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3, Value3, Value4, Value5, Value6, Value7, Value8, UserData = dataInfo billboardInfoData = ChPyNetSendPack.tagGCCrossBillboardData() - billboardInfoData.ID = billboardData.ID - billboardInfoData.Name1 = billboardData.Name1 - billboardInfoData.Name2 = billboardData.Name2 - billboardInfoData.Type2 = billboardData.Type2 - billboardInfoData.Value1 = billboardData.Value1 - billboardInfoData.Value2 = billboardData.Value2 - billboardInfoData.CmpValue = billboardData.CmpValue - billboardInfoData.CmpValue2 = billboardData.CmpValue2 - billboardInfoData.CmpValue3 = billboardData.CmpValue3 + billboardInfoData.OrderIndex = orderIndex + billboardInfoData.ID = ID + billboardInfoData.ID2 = ID2 + billboardInfoData.Name1 = Name1 + billboardInfoData.Name2 = Name2 + billboardInfoData.Type2 = Type2 + billboardInfoData.Value1 = Value1 + billboardInfoData.Value2 = Value2 + billboardInfoData.Value3 = Value3 + billboardInfoData.Value4 = Value4 + billboardInfoData.Value5 = Value5 + billboardInfoData.Value6 = Value6 + billboardInfoData.Value7 = Value7 + billboardInfoData.Value8 = Value8 + billboardInfoData.CmpValue = CmpValue + billboardInfoData.CmpValue2 = CmpValue2 + billboardInfoData.CmpValue3 = CmpValue3 + billboardInfoData.UserData = UserData + billboardInfoData.DataLen = len(billboardInfoData.UserData) billboardInfo.CrossBillboardDataList.append(billboardInfoData) billboardInfo.BillboardCount = len(billboardInfo.CrossBillboardDataList) NetPackCommon.SendFakePack(curPlayer, billboardInfo) @@ -416,9 +656,16 @@ name2 = billInfoDict["Name2"] value1 = billInfoDict["Value1"] value2 = billInfoDict["Value2"] + value3 = billInfoDict.get("Value3", 0) + value4 = billInfoDict.get("Value4", 0) + value5 = billInfoDict.get("Value5", 0) + value6 = billInfoDict.get("Value6", 0) + value7 = billInfoDict.get("Value7", 0) + value8 = billInfoDict.get("Value8", 0) cmpValue = billInfoDict["CmpValue"] cmpValue2 = billInfoDict["CmpValue2"] cmpValue3 = billInfoDict["CmpValue3"] + userData = billInfoDict.get("UserData", "") billboardMgr = PyDataManager.GetCrossBillboardManager() billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) @@ -427,8 +674,11 @@ if cmpValue == billboardData.CmpValue and cmpValue2 == billboardData.CmpValue2 \ and (not cmpValue3 or cmpValue3 == billboardData.CmpValue3) \ and value1 == billboardData.Value1 and value2 == billboardData.Value2 \ + and value3 == billboardData.Value3 and value4 == billboardData.Value4 \ + and value5 == billboardData.Value5 and value6 == billboardData.Value6 \ + and value7 == billboardData.Value7 and value8 == billboardData.Value8 \ and name1 == billboardData.Name1 and name2 == billboardData.Name2 \ - and type2 == billboardData.Type2 and id2 == billboardData.ID2: + and type2 == billboardData.Type2 and id2 == billboardData.ID2 and userData == billboardData.UserData: GameWorld.DebugLog(" 榜单值相同,不同步跨服服务器! ") return @@ -461,16 +711,46 @@ name2 = billInfoDict["Name2"] value1 = billInfoDict["Value1"] value2 = billInfoDict["Value2"] + value3 = billInfoDict.get("Value3", 0) + value4 = billInfoDict.get("Value4", 0) + value5 = billInfoDict.get("Value5", 0) + value6 = billInfoDict.get("Value6", 0) + value7 = billInfoDict.get("Value7", 0) + value8 = billInfoDict.get("Value8", 0) cmpValue = billInfoDict["CmpValue"] cmpValue2 = billInfoDict["CmpValue2"] cmpValue3 = billInfoDict["CmpValue3"] + userData = billInfoDict.get("UserData", "") + kwargs = {"value3":value3, "value4":value4, "value5":value5, "value6":value6, "value7":value7, "value8":value8, "userData":userData} UpdCrossBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, - cmpValue, cmpValue2, cmpValue3, groupValue2, id2) + cmpValue, cmpValue2, cmpValue3, groupValue2, id2, **kwargs) + return + +def UpdCrossBillboardFamily(bType, groupValue1, familyBillInfo, cmpValue, cmpValue2=0, autoSort=True): + ## 更新跨服仙盟榜单 + if not familyBillInfo: + return + if "id" not in familyBillInfo: + return + familyID = familyBillInfo["id"] + familyName = familyBillInfo["name"] + id2 = familyBillInfo["id2"] + name2 = familyBillInfo["name2"] + value1 = familyBillInfo["value1"] + value2 = familyBillInfo["value2"] + value3 = familyBillInfo["value3"] + value4 = familyBillInfo["value4"] + value5 = familyBillInfo["value5"] + type2 = 0 + + UpdCrossBillboard(bType, groupValue1, familyID, familyName, name2, type2, value1, value2, cmpValue, cmpValue2, + id2=id2, autoSort=autoSort, value3=value3, value4=value4, value5=value5) return def UpdCrossBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue, - cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0, autoSort=True): + cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0, autoSort=True, noSortAndSync=False, + **kwargs): ''' 更新跨服排行榜 @param billboardType: 排行榜索引类型,同个榜单类型可以有多个分组榜单数据,独立排序 @param groupValue1: 榜单分组1 @@ -486,6 +766,7 @@ @param groupValue1: 榜单分组2 @param id2: 扩展数据ID2 @param autoSort: 是否排序,默认True + @param noSortAndSync: 不排序及同步子服,默认False; 一般用于批量更新数据时设置为True,减少排序及同步频率,但是一定要在设置完数据或最后一条数据后手动调用一次排序SortData @return: 是否上榜更新榜单 ''' if not GameWorld.IsCrossServer(): @@ -512,17 +793,16 @@ if not billboardObj.AddBillboardData(billboardData): return + cmpValueChange = isNewData or billboardData.CmpValue != cmpValue or billboardData.CmpValue2 != cmpValue2 or (cmpValue3 and billboardData.CmpValue3 != cmpValue3) # 没设置值默认为时间time,先上榜的排前面 if cmpValue3 == 0: # 时间权值仅在比较值变更的情况下才更新, 防止其他附属值更新时导致比较值相同的玩家名次间会变动的问题 - if isNewData or billboardData.CmpValue != cmpValue or billboardData.CmpValue2 != cmpValue2: + if cmpValueChange: calcTime = GameWorld.ChangeTimeStrToNum("2090-01-01 00:00:00") cmpValue3 = max(0, calcTime - int(time.time())) # 比较值3如果没指定值则默认存当前更新的time else: cmpValue3 = billboardData.CmpValue3 - cmpValueChange = billboardData.CmpValue != cmpValue or billboardData.CmpValue2 != cmpValue2 or billboardData.CmpValue3 != cmpValue3 - # 更新所有值 billboardData.GroupValue1 = groupValue1 billboardData.GroupValue2 = groupValue2 @@ -534,16 +814,32 @@ billboardData.Type2 = type2 billboardData.Value1 = value1 billboardData.Value2 = value2 + billboardData.Value3 = kwargs.get("value3", 0) + billboardData.Value4 = kwargs.get("value4", 0) + billboardData.Value5 = kwargs.get("value5", 0) + billboardData.Value6 = kwargs.get("value6", 0) + billboardData.Value7 = kwargs.get("value7", 0) + billboardData.Value8 = kwargs.get("value8", 0) + billboardData.UserData = kwargs.get("userData", "") + billboardData.DataLen = len(billboardData.UserData) billboardData.CmpValue = cmpValue billboardData.CmpValue2 = cmpValue2 billboardData.CmpValue3 = cmpValue3 - GameWorld.DebugLog("更新跨服排行榜值: billboardType=%s,groupValue1=%s,groupValue2=%s,dataID=%s,isNewData=%s,cmpValueChange=%s,type2=%s,value1=%s,value2=%s,cmpValue=%s,cmpValue2=%s,cmpValue3=%s" + GameWorld.DebugLog("更新跨服排行榜值: billboardType=%s,groupValue1=%s,groupValue2=%s,dataID=%s,isNewData=%s,cmpValueChange=%s,type2=%s,value1=%s,value2=%s,cmpValue=%s,cmpValue2=%s,cmpValue3=%s,%s" % (billboardType, groupValue1, groupValue2, dataID, isNewData, cmpValueChange, - type2, value1, value2, cmpValue, cmpValue2, cmpValue3), dataID) + type2, value1, value2, cmpValue, cmpValue2, cmpValue3, kwargs), dataID) + if noSortAndSync: + return True - if autoSort and cmpValueChange: + # 新数据可能导致榜单ID增减,强制排序一次 + if isNewData: billboardObj.SortData() + elif cmpValueChange: + if autoSort: + billboardObj.SortData() + else: + billboardObj.SetDelaySort() else: billboardObj.UpdCrossServerDataVer() return True -- Gitblit v1.8.0