#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package CrossBillboard # # @todo:¿ç·þÅÅÐаñ # @author hxp # @date 2020-01-13 # @version 1.0 # # ÏêϸÃèÊö: ¿ç·þÅÅÐаñ # #------------------------------------------------------------------------------- #"""Version = 2020-01-13 17:00""" #------------------------------------------------------------------------------- import CommFunc import ShareDefine import IpyGameDataPY import CrossRealmMsg import PlayerViewCache import PyGameDataStruct import ChPyNetSendPack import DataRecordPack import NetPackCommon import PyDataManager import CrossRealmPK import GameWorld import operator import time import json class CrossBillboardManager(object): ## ¿ç·þÅÅÐаñ¹ÜÀí£¬×¢Òâ¸ÃÀàÖ»´¦ÀíÊý¾ÝÂß¼­£¬¹¦ÄÜÏà¹ØÂß¼­²»ÒªÐ´ÔÚ¸ÃÀ࣬²»È»ÖضÁ½Å±¾²»»áÉúЧ def __init__(self): self.__billboardDict = {} # ÅÅÐаñ×Öµä {(billboardType, groupValue1, groupValue2):CrossBillboard, ...} return def GetBillboardGroupList(self, bType): ## ¸ù¾Ý°ñµ¥ÀàÐÍ»ñÈ¡¸ÃÀàÐÍËùÓзÖ×é°ñµ¥ÐÅÏ¢ ## @return: [(billboardType, groupValue1, groupValue2), ...] groupList = [] for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys(): if bType == billboardType: groupList.append((billboardType, groupValue1, groupValue2)) return groupList def GetCrossBillboard(self, billboardType, groupValue1, groupValue2=0): ''' »ñÈ¡¿ç·þÅÅÐаñ @param billboardType: ÅÅÐаñÀàÐÍ @param groupValue1: ·Ö×éÖµ1 @param groupValue2: ·Ö×éÖµ2£¬Óë·Ö×éÖµ1×éºÏ¹éΪͬ×é°ñµ¥Êý¾Ý @return: CrossBillboard ''' key = (billboardType, groupValue1, groupValue2) if key in self.__billboardDict: billboardObj = self.__billboardDict[key] else: billboardObj = CrossBillboard(billboardType, groupValue1, groupValue2) self.__billboardDict[key] = billboardObj return billboardObj def RemoveBillboard(self, billboardType): ## ÒÆ³ýij¸öÀàÐ͵İñµ¥ËùÓÐÊý¾Ý for key in self.__billboardDict.keys(): if key[0] == billboardType: self.__billboardDict.pop(key) return def ClearBillboard(self, billboardType, groupValue1=None, groupValue2=None): '''Çå³ýij¸öÀàÐ͵İñµ¥ËùÓÐÊý¾Ý£¬¿ÉÖ¸¶¨¹ýÂËgroupValue£¬ÓÐÁ÷Ïò¼Ç¼ @param groupValue1: ²»ÎªNoneʱÑéÖ¤ groupValue1 ÊÇ·ñÏàͬ @param groupValue2: ²»ÎªNoneʱÑéÖ¤ groupValue2 ÊÇ·ñÏàͬ Èç¹ûgroupValue1 groupValue2 ¶¼´«ÈëNone£¬Ï൱ÓÚÇå¿Õ billboardType ÀàÐ͵ÄËùÓаñµ¥Êý¾Ý ''' clearList = [] for bType, gValue1, gValue2 in self.__billboardDict.keys(): if bType != billboardType: continue if groupValue1 != None and groupValue1 != gValue1: continue if groupValue2 != None and groupValue2 != gValue2: continue key = (bType, gValue1, gValue2) clearList.append(key) for bType, gValue1, gValue2 in clearList: self.GetCrossBillboard(bType, gValue1, gValue2).ClearData() return # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup def GetSaveData(self): savaData = "" cntData = "" cnt = 0 for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys(): billboardObj = self.GetCrossBillboard(billboardType, groupValue1, groupValue2) for i in xrange(billboardObj.GetCount()): billboardData = billboardObj.At(i) cnt += 1 savaData += billboardData.getBuffer() GameWorld.Log("Save DBCrossBillboard 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 DBCrossBillboard count :%s" % cnt) for _ in xrange(cnt): billboardData = PyGameDataStruct.tagDBCrossBillboard() billboardData.clear() pos += billboardData.readData(datas, pos, dataslen) billboardType, groupValue1, groupValue2 = billboardData.BillboardType, billboardData.GroupValue1, billboardData.GroupValue2 billboardObj = self.GetCrossBillboard(billboardType, groupValue1, groupValue2) billboardObj.AddBillboardData(billboardData) # ÅÅÐò for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys(): billboardObj = self.GetCrossBillboard(billboardType, groupValue1, groupValue2) billboardObj.SortData() return pos class CrossBillboard(object): ''' ¶ÔÓ¦¾ßÌåÀàÐÍÅÅÐаñÂß¼­Àà ''' def __init__(self, billboardType, groupValue1=0, groupValue2=0): self.__billboardType = billboardType self.__groupValue1 = groupValue1 self.__groupValue2 = groupValue2 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 def GetGroupValue1(self): return self.__groupValue1 def GetGroupValue2(self): return self.__groupValue2 def ClearData(self): 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("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): ## Ìí¼Ó°ñµ¥Êý¾Ýµ½¸Ã°ñ # @param billboardData: PyGameDataStruct.tagDBCrossBillboard() # @return: ÊÇ·ñ³É¹¦ if self.IsFull(): return False self.__billboardList.append(billboardData) return True def FindByID(self, findID): ''' ¸ù¾ÝID²éѯ°ñµ¥Êý¾Ý @param findID: ²éÕÒµÄID @return: None or PyGameDataStruct.tagDBCrossBillboard() ''' self.GetIDOrderDict() if findID not in self.__idIndexDict: return None idIndex = self.__idIndexDict[findID] if idIndex >= len(self.__billboardList): return None return self.__billboardList[idIndex] 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={}): ## ¼Ç¼Á÷ÏòÊý¾Ý 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, "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 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): maxCountDict = IpyGameDataPY.GetFuncEvalCfg("CrossBillboardSet", 1, {}) return maxCountDict.get(self.__billboardType, 100) def At(self, i): billData = self.__billboardList[i] if not billData and False: billData = PyGameDataStruct.tagDBCrossBillboard() # ²»»áÖ´Ðе½£¬Ö»ÎªÁË.³ö´úÂëÌáʾ return billData def IsFull(self): return len(self.__billboardList) >= self.GetMaxCount() def UpdCrossServerDataVer(self, version=None): ## ¸üпç·þ°ñµ¥Êý¾Ý°æ±¾ºÅ£¬ÓÃÓÚ¿ç·þÖ÷·þ¡¢×Ó·þÑéÖ¤Êý¾Ý°æ±¾£¬Í¬²½°ñµ¥Êý¾ÝÓà if not GameWorld.IsCrossServer(): return if version == None: version = int(time.time()) self.__crossServerDataVer = version #SyncCrossBillboardToClientServer(self.__billboardType, self.__groupValue1, self.__groupValue2) return def GetCrossServerDataVer(self): return self.__crossServerDataVer def CheckClientServerDataVer(self): ## ¼ì²é×Ó·þ°ñµ¥Êý¾Ý°æ±¾ÊÇ·ñÐèҪͬ²½ # @return: ÊÇ·ñÐèÒªÏò¿ç·þÖ÷·þͬ²½×îÐÂÊý¾Ý return self.__clientServerDataVer == 0 or self.__clientServerDataVer != self.__crossServerDataVer def UpdClientServerBillboard(self, crossServerDataVer, syncBillboardList=None): ## ¸üб¾·þµÄ¿ç·þ°ñµ¥Êý¾Ý # ¸üпç·þÊý¾Ý°æ±¾ self.__crossServerDataVer = crossServerDataVer # ÌØÊâ°æ±¾0´ú±íÇå³ýÊý¾Ý if crossServerDataVer == 0: self.ClearData() # ¸üÐÂÊý¾Ý 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, Value3, Value4, Value5, Value6, Value7, Value8, UserData = syncData if i < len(self.__billboardList): billboardData = self.__billboardList[i] billboardData.clear() else: billboardData = PyGameDataStruct.tagDBCrossBillboard() self.__billboardList.append(billboardData) billboardData.GroupValue1 = self.__groupValue1 billboardData.GroupValue2 = self.__groupValue2 billboardData.BillboardType = self.__billboardType billboardData.ID = ID billboardData.ID2 = ID2 billboardData.Name1 = Name1 billboardData.Name2 = Name2 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 return def CopyBillboardOnDay(): billboardMgr = PyDataManager.GetCrossBillboardManager() for billboardType in ShareDefine.CrossBillboardTypeList: if billboardType in [ShareDefine.Def_CBT_BossTrialSubmitBak, ShareDefine.Def_CBT_BossTrialSubmitFamilyBak, ShareDefine.Def_CBT_CrossRealmPK]: continue groupList = billboardMgr.GetBillboardGroupList(billboardType) for billboardType, groupValue1, groupValue2 in groupList: billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) 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 # #struct tagCGViewCrossBillboard #{ # tagHead Head; # BYTE Type; //°ñµ¥ÀàÐÍ # DWORD GroupValue1; // ·Ö×éÖµ1 # DWORD 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) if GameWorld.IsCrossServer(): 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 # Ö§³Ö·ÖÒ³²éѯ£¬¸ÄΪֱ½Ó²é¿ç·þ·þÎñÆ÷ GameWorld.DebugLog("Íæ¼ÒÇëÇó²é¿´¿ç·þÅÅÐаñ: billboardType=%s,groupValue1=%s,groupValue2=%s" % (billboardType, groupValue1, groupValue2)) # ÇëÇó²éѯ¿ç·þ·þÎñÆ÷ dataMsg = {"BillboardType":billboardType, "GroupValue1":groupValue1, "GroupValue2":groupValue2, "PlayerID":playerID, "QueryType":"View", "QueryData":{"StartIndex":startIndex, "WatchCnt":watchCnt, "WatchID":watchID}} CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_QueryBillboard, dataMsg) return def OnQueryPlayerBillboardRank(playerID, funcName, funcData, billboardType, groupValue1, groupValue2=0, tagPlayerID=0): ## ²éÑ¯Íæ¼ÒIDÅÅÃû if GameWorld.IsCrossServer(): return if billboardType not in ShareDefine.CrossBillboardTypeList: return if not tagPlayerID: tagPlayerID = playerID # ĬÈϲé×Ô¼º dataMsg = {"BillboardType":billboardType, "GroupValue1":groupValue1, "GroupValue2":groupValue2, "PlayerID":playerID, "QueryType":"Ranking", "QueryData":{"PlayerID":tagPlayerID, "funcName":funcName, "funcData":funcData}} CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_QueryBillboard, dataMsg) return def ClientServerMsg_QueryBillboard(serverGroupID, msgData): ## ÊÕµ½×Ó·þÇëÇó²éѯÅÅÐаñÐÅÏ¢ billboardType = msgData["BillboardType"] groupValue1 = msgData["GroupValue1"] groupValue2 = msgData["GroupValue2"] playerID = msgData.get("PlayerID", 0) # ·¢ÆðµÄÍæ¼ÒID queryType = msgData.get("QueryType", "") # Ô­Êý¾Ý·µ»Ø×Ó·þ queryData = msgData.get("QueryData", {}) # Ô­Êý¾Ý·µ»Ø×Ó·þ SyncCrossBillboardToClientServer(billboardType, groupValue1, groupValue2, [serverGroupID], playerID, queryType, queryData) return def SyncCrossBillboardToClientServer(billboardType, groupValue1, groupValue2, serverGroupIDList=None, playerID=0, queryType="", queryData=None): ## ͬ²½¿ç·þ°ñµ¥µ½×Ó·þ if not GameWorld.IsCrossServer(): return if serverGroupIDList == None: serverGroupIDList = [] if queryData == None: queryData = {} billboardMgr = PyDataManager.GetCrossBillboardManager() billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) billboardObj.DoDelaySort() idOrderDict = billboardObj.GetIDOrderDict() msgData = {"BillboardType":billboardType, "GroupValue1":groupValue1, "GroupValue2":groupValue2, "PlayerID":playerID, "QueryType":queryType, "QueryData":queryData} # ²éѯÃû´Î if queryType == "Ranking": tagPlayerID = queryData.get("PlayerID", 0) if not tagPlayerID: return queryData["OrderIndex"] = idOrderDict.get(tagPlayerID, 0) - 1 # -1-δÉϰñ£¬0-µÚÒ»Ãû CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_SyncBillboard, msgData, serverGroupIDList) return # ÓвéѯÊý¾Ýʱ²Åͬ²½°ñµ¥Êý¾ÝÁÐ±í£¬·ñÔòֻͬ²½Êý¾Ý°æ±¾ºÅ 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 = [] 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 Name2 = billboardData.Name2 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 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) return def CrossServerMsg_SyncBillboard(msgData, tick): ## ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄÅÅÐаñÐÅÏ¢ billboardType = msgData["BillboardType"] groupValue1 = msgData["GroupValue1"] groupValue2 = msgData["GroupValue2"] playerID = msgData.get("PlayerID", 0) # ·¢ÆðµÄÍæ¼ÒID queryType = msgData.get("QueryType", "") queryData = msgData.get("QueryData", {}) GameWorld.DebugLog("ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄÅÅÐаñÐÅÏ¢: billboardType=%s,groupValue1=%s,groupValue2=%s,queryType=%s" % (billboardType, groupValue1, groupValue2, queryType), playerID) if not queryType or not queryData: return if queryType == "View": queryPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if not queryPlayer: return watchID = queryData.get("WatchID", 0) syncBillboardList = msgData.get("BillboardDataList") SyncCrossBillboardToPlayer(queryPlayer, billboardType, groupValue1, groupValue2, syncBillboardList, watchID) elif queryType == "Ranking": funcName = queryData.get("funcName", "") funcData = queryData.get("funcData", {}) #tagPlayerID = queryData.get("PlayerID", 0) orderIndex = queryData.get("OrderIndex", 0) if funcName == "QueryCrossPKSeasonOrder": CrossRealmPK.OnQueryCrossPKSeasonOrderRet(playerID, funcData, orderIndex) return 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 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.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) return def MapServer_UpdateCrossBillboard(billInfoDict): '''µØÍ¼¸üпç·þÅÅÐаñ, ͨÓà {"Type":bType, "GroupValue1":groupValue1, "Type2":type2, "ID":dataID, "ID2":id2, "Name1":name1, "Name2":name2, "Value1":value1, "Value2":value2, "CmpValue":cmpValue, "CmpValue2":cmpValue2, "CmpValue3":cmpValue3, "GroupValue2":groupValue2} ''' if GameWorld.IsCrossServer(): # Ö»ÓÐ×Ó·þÎñÆ÷Äܵ÷Óà return GameWorld.DebugLog("×Ó·þµØÍ¼¸üпç·þ°ñµ¥Êý¾Ý! %s" % billInfoDict) billboardType = billInfoDict["Type"] if billboardType not in ShareDefine.CrossBillboardTypeList: return groupValue1 = billInfoDict["GroupValue1"] groupValue2 = billInfoDict["GroupValue2"] dataID = billInfoDict["ID"] if not groupValue1 or not dataID: return type2 = billInfoDict["Type2"] id2 = billInfoDict["ID2"] name1 = billInfoDict["Name1"] 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) billboardData = billboardObj.FindByID(dataID) if billboardData: 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 userData == billboardData.UserData: GameWorld.DebugLog(" °ñµ¥ÖµÏàͬ£¬²»Í¬²½¿ç·þ·þÎñÆ÷! ") return elif billboardObj.IsFull(): lastBillBoardData = __CmpLastBillboardData(cmpValue, cmpValue2, cmpValue3, billboardObj) if not lastBillBoardData: GameWorld.DebugLog(" °ñµ¥Öµ²»³¬¹ý×îºóÒ»Ãû£¬²»Í¬²½¿ç·þ·þÎñÆ÷! ") return else: GameWorld.DebugLog(" ±¾·þûÓÐÔÚ°ñÉÏ!") # ͬ²½¿ç·þ·þÎñÆ÷ CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_UpdateBillboard, billInfoDict) return def ClientServerMsg_UpdateBillboard(serverGroupID, billInfoDict): GameWorld.Log("ÊÕµ½×Ó·þ¸üпç·þ°ñµ¥Êý¾Ý! serverGroupID=%s, %s" % (serverGroupID, billInfoDict)) billboardType = billInfoDict["Type"] if billboardType not in ShareDefine.CrossBillboardTypeList: return groupValue1 = billInfoDict["GroupValue1"] groupValue2 = billInfoDict["GroupValue2"] type2 = billInfoDict["Type2"] dataID = billInfoDict["ID"] id2 = billInfoDict["ID2"] name1 = billInfoDict["Name1"] 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, **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 UpdCrossBillboardPlayer(bType, playerID, groupValue1, cmpValue, cmpValue2=0, value1=0, value2=0, groupValue2=0, autoSort=True, **kwargs): ## ͨÓõĸüпç·þÍæ¼Ò°ñ£¬GameServerÖ±½Óµ÷Óà playerInfo = PlayerViewCache.GetShotCacheDict(playerID, "AccID", "ServerID", "Face", "FacePic") name1 = playerInfo.get("Name", "") name2 = playerInfo.get("AccID", "") type2 = playerInfo.get("Job", 1) if not value1: value1 = playerInfo.get("RealmLV", 1) value3 = playerInfo.get("Face", 0) value4 = playerInfo.get("FacePic", 0) value5 = playerInfo.get("ServerID", 0) UpdCrossBillboard(bType, groupValue1, playerID, name1, name2, type2, value1, value2, cmpValue, cmpValue2, 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, noSortAndSync=False, **kwargs): ''' ¸üпç·þÅÅÐаñ @param billboardType: ÅÅÐаñË÷ÒýÀàÐÍ£¬Í¬¸ö°ñµ¥ÀàÐÍ¿ÉÒÔÓжà¸ö·Ö×é°ñµ¥Êý¾Ý£¬¶ÀÁ¢ÅÅÐò @param groupValue1: °ñµ¥·Ö×é1 @param dataID: °ñµ¥Î¨Ò»Êý¾ÝID£¬ÈçÍæ¼ÒIDµÈ @param name1: ÏÔʾÃû³Æ1£¬²»Ó°ÏìÅÅÐò @param name2: ÏÔʾÃû³Æ2£¬²»Ó°ÏìÅÅÐò @param type2: °ñµ¥Êý¾ÝÀàÐÍ2£¬×Ô¶¨Ò壬һ°ãΪְҵµÈ¶þ¼¶·ÖÀ࣬²»Ó°ÏìÅÅÐò @param value1: ÏÔʾֵ1£¬²»Ó°ÏìÅÅÐò @param value2: ÏÔʾֵ2£¬²»Ó°ÏìÅÅÐò @param cmpValue: ±È½ÏÖµ1 @param cmpValue2: ±È½ÏÖµ2 @param cmpValue3: ±È½ÏÖµ3£¬Ã»É趨µÄ»°Ä¬ÈÏΪʱ¼ä´Á±È½ÏÖµ @param groupValue1: °ñµ¥·Ö×é2 @param id2: À©Õ¹Êý¾ÝID2 @param autoSort: ÊÇ·ñÅÅÐò£¬Ä¬ÈÏTrue @param noSortAndSync: ²»ÅÅÐò¼°Í¬²½×Ó·þ£¬Ä¬ÈÏFalse; Ò»°ãÓÃÓÚÅúÁ¿¸üÐÂÊý¾ÝʱÉèÖÃΪTrue£¬¼õÉÙÅÅÐò¼°Í¬²½ÆµÂÊ£¬µ«ÊÇÒ»¶¨ÒªÔÚÉèÖÃÍêÊý¾Ý»ò×îºóÒ»ÌõÊý¾ÝºóÊÖ¶¯µ÷ÓÃÒ»´ÎÅÅÐòSortData @return: ÊÇ·ñÉϰñ¸üаñµ¥ ''' if not GameWorld.IsCrossServer(): # Ö»Óпç·þ·þÎñÆ÷Äܵ÷Óà return if not groupValue1 or not dataID: return billboardMgr = PyDataManager.GetCrossBillboardManager() billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2) billboardData = billboardObj.FindByID(dataID) isNewData = False if not billboardData: isNewData = True if billboardObj.IsFull(): # Óë×îºóÒ»Ãû¶Ô±È lastBillBoardData = __CmpLastBillboardData(cmpValue, cmpValue2, cmpValue3, billboardObj) if not lastBillBoardData: GameWorld.DebugLog(" °ñµ¥Öµ²»³¬¹ý×îºóÒ»Ãû£¬²»Éϰñ! ") return billboardData = lastBillBoardData billboardData.clear() else: billboardData = PyGameDataStruct.tagDBCrossBillboard() 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 cmpValueChange: calcTime = GameWorld.ChangeTimeStrToNum("2090-01-01 00:00:00") cmpValue3 = max(0, calcTime - int(time.time())) # ±È½ÏÖµ3Èç¹ûûָ¶¨ÖµÔòĬÈϴ浱ǰ¸üеÄtime else: cmpValue3 = billboardData.CmpValue3 # ¸üÐÂËùÓÐÖµ billboardData.GroupValue1 = groupValue1 billboardData.GroupValue2 = groupValue2 billboardData.BillboardType = billboardType billboardData.ID = dataID billboardData.ID2 = id2 billboardData.SetName1(name1) billboardData.SetName2(name2) 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) userData = kwargs.get("userData", "") if userData and not isinstance(userData, str): if isinstance(userData, dict) or isinstance(userData, list): userData = json.dumps(userData, ensure_ascii=False) userData = userData.replace(" ", "") billboardData.UserData = 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,%s" % (billboardType, groupValue1, groupValue2, dataID, isNewData, cmpValueChange, type2, value1, value2, cmpValue, cmpValue2, cmpValue3, kwargs), dataID) if noSortAndSync: return True # ÐÂÊý¾Ý¿ÉÄܵ¼Ö°ñµ¥IDÔö¼õ£¬Ç¿ÖÆÅÅÐòÒ»´Î if isNewData: billboardObj.SortData() elif cmpValueChange: if autoSort: billboardObj.SortData() else: billboardObj.SetDelaySort() else: billboardObj.UpdCrossServerDataVer() return True def __CmpLastBillboardData(cmpValue, cmpValue2, cmpValue3, billboardObj): ## ±È½ÏÊÇ·ñ³¬¹ý×îºóÒ»Ãû # @return: ³¬¹ýÔò·µ»Ø×îºóÒ»ÃûÊý¾ÝʵÀý£¬·ñÔò·µ»ØNone if not billboardObj.GetCount(): return lastBillBoardData = billboardObj.At(billboardObj.GetCount() - 1) if cmpValue < lastBillBoardData.CmpValue: #ÎÞ·¨Éϰñ return elif cmpValue == lastBillBoardData.CmpValue: if cmpValue2 < lastBillBoardData.CmpValue2: return elif cmpValue2 == lastBillBoardData.CmpValue2: if cmpValue3 <= lastBillBoardData.CmpValue3: return return lastBillBoardData