#!/usr/bin/python # -*- coding: GBK -*- # ##@package # # @todo: # # @author: Alee # @date 2019-1-14 ÏÂÎç11:30:12 # @version 1.0 # # @note: # #--------------------------------------------------------------------- import GameWorld import CommFunc import PlayerControl import IPY_GameWorld import BuffSkill import SkillCommon import base64 import ChConfig import PyGameData import PlayerDienstgrad import IpyGameDataPY import PlayerHorse import PlayerPet import traceback # ·¢Ë͸ñʽ£º ÀàÐÍ+£¨ÊýÁ¿£©+Êý¾Ý # Ïò¿ç·þ·¢Ë͵ÄÊý¾ÝÀàÐÍ ( MergeData_Player, # ¶Ô±È´¦Àí MergeData_Item, # ¶Ô±È´¦Àí Ö»ËãÊôÐԵı³°ü ×°±¸ ³èÎï MergeData_Skill, # Ö»´¦ÀíID MergeData_Buff, # ¼´Ê±·¢ËÍ CrossData_PetState, # ¼´Ê±·¢ËÍ ³èÎï³öÕ½ CrossData_HorseChange, # ¼´Ê±·¢ËÍ Æï³Ë×øÆï±ä¸ü CrossData_RideHorse, # ¼´Ê±·¢ËÍ ÉÏÏÂÂí ) = range(0, 7) ## дÊý¾ÝÀàÐͶ¨Òå ( WDT_BYTE, WDT_WORD, WDT_DWORD, WDT_String, ) = range(4) CrossDataInfo = { CrossData_PetState:[[WDT_DWORD, WDT_BYTE, WDT_BYTE], lambda curObj, valueList:PlayerPet.CrossServer_DoChangePetState(curObj, valueList)], CrossData_HorseChange:[[WDT_DWORD], lambda curObj, valueList:PlayerHorse.CrossServer_ChangeHorse(curObj, valueList)], CrossData_RideHorse:[[WDT_BYTE], lambda curObj, valueList:PlayerHorse.CrossServer_RideHorse(curObj, valueList)], } # Ó°Ïì¿ç·þÕ½Á¦ÊôÐÔÁбí CrossFightPowerAttrList = [ [lambda curObj:curObj.GetBaseSTR(), lambda curObj, value:curObj.SetBaseSTR(value)], # Á¦Á¿ [lambda curObj:curObj.GetBasePNE(), lambda curObj, value:curObj.SetBasePNE(value)], # ÖÇÁ¦ [lambda curObj:curObj.GetBasePHY(), lambda curObj, value:curObj.SetBasePHY(value)], # Ãô½Ý [lambda curObj:curObj.GetBaseCON(), lambda curObj, value:curObj.SetBaseCON(value)], # ÌåÖÊ [lambda curObj:curObj.GetLV(), lambda curObj, value:curObj.SetLV(value)], # µÈ¼¶ [lambda curObj:curObj.GetOfficialRank(), lambda curObj, value:curObj.SetOfficialRank(value)], # ¾³½ç [lambda curObj:curObj.GetVIPLv(), lambda curObj, value:curObj.SetVIPLv(value)], # VIPµÈ¼¶ ] # ·¢ËÍÖ÷·þÍæ¼ÒÊý¾Ý¸ø¿ç·þ def SendMergeData_Buff(curPlayer, buffID, plusValueList): if buffID in [ChConfig.Def_SkillID_LimitSuperBuff, ChConfig.Def_SkillID_TJGSuperBuff]: # ²»ÐèÒª´¦ÀíµÄbuff return if curPlayer.GetGameObjType() != IPY_GameWorld.gotPlayer: return if GameWorld.IsCrossServer(): # ·ÇÖ÷·þ return if not PlayerControl.GetCrossMapID(curPlayer): # ·Ç¿ç·þÖÐ return data = '' data = CommFunc.WriteBYTE(data, MergeData_Buff) data = CommFunc.WriteDWORD(data, buffID) data = CommFunc.WriteBYTE(data, len(plusValueList)) for value in plusValueList: data = CommFunc.WriteDWORD(data, value) #Ö±½ÓÓÃ×Ö½ÚÁ÷»á±¨´í data = base64.b64encode(data) curPlayer.SendMergePlayerData(data) return # ½ÓÊÕ×Ó·þÍæ¼ÒÊý¾Ý def OnMergePlayerData(index, tick): if not GameWorld.IsCrossServer(): # ·Ç¿ç·þ return try: # ¿ç·þ·þÎñÆ÷´¦Àí curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) pdata = base64.b64decode(curPlayer.GetMergePlayerData()) pos = 0 dataType, pos = CommFunc.ReadBYTE(pdata, pos) if dataType == MergeData_Buff: buffID, pos = CommFunc.ReadDWORD(pdata, pos) curSkill = GameWorld.GetGameData().GetSkillBySkillID(buffID) if not curSkill: return plusValueList = [] cnt, pos = CommFunc.ReadBYTE(pdata, pos) for i in range(cnt): value, pos = CommFunc.ReadDWORD(pdata, pos) plusValueList.append(value) buffType = SkillCommon.GetBuffType(curSkill) BuffSkill.AddBuffNoRefreshState(curPlayer, buffType, curSkill, tick, plusValueList) elif dataType == MergeData_Player: __ReadMainServerSyncPlayerData(curPlayer, curPlayer.GetMergePlayerData(), pos) else: __ReadCrossData(curPlayer, dataType, curPlayer.GetMergePlayerData(), pos) except BaseException: errorMsg = str(traceback.format_exc()) GameWorld.ErrLog('½ÓÊÕ¿ç·þ±ä¸üÍæ¼ÒÊý¾Ý´íÎó - > %s' % errorMsg, curPlayer.GetPlayerID()) if GameWorld.GetGameWorld().GetDebugLevel(): raise Exception(errorMsg) return ## ---------------------------------------------------------------------------------------------- def SendDataToCrossServer(curPlayer, dataType, dataList): ## ͨÓõĸù¾ÝÀàÐÍÏò¿ç·þ·¢ËÍÊý¾Ý if dataType not in CrossDataInfo: return if not IsNeedProcessCrossPlayer(curPlayer): return dataInfo = CrossDataInfo[dataType][0] if len(dataList) != len(dataInfo): return data = '' data = CommFunc.WriteBYTE(data, dataType) for i, wDType in enumerate(dataInfo): value = dataList[i] if wDType == WDT_BYTE: data = CommFunc.WriteBYTE(data, value) elif wDType == WDT_WORD: data = CommFunc.WriteWORD(data, value) elif wDType == WDT_DWORD: data = CommFunc.WriteDWORD(data, value) elif wDType == WDT_String: sLen = len(value) data = CommFunc.WriteBYTE(data, sLen) data = CommFunc.WriteString(data, sLen, value) #Ö±½ÓÓÃ×Ö½ÚÁ÷»á±¨´í data = base64.b64encode(data) curPlayer.SendMergePlayerData(data) GameWorld.DebugLog("·¢ËÍÊý¾Ýµ½¿ç·þ·þÎñÆ÷: dataType=%s,dataList=%s" % (dataType, dataList), curPlayer.GetPlayerID()) return def __ReadCrossData(curPlayer, dataType, pdata, pos): if dataType not in CrossDataInfo: return dataInfo, callFunc = CrossDataInfo[dataType] if not callFunc: return dataList = [] pdata = base64.b64decode(pdata) for wDType in dataInfo: if wDType == WDT_BYTE: value, pos = CommFunc.ReadBYTE(pdata, pos) elif wDType == WDT_WORD: value, pos = CommFunc.ReadWORD(pdata, pos) elif wDType == WDT_DWORD: value, pos = CommFunc.ReadDWORD(pdata, pos) elif wDType == WDT_String: sLen, pos = CommFunc.ReadBYTE(pdata, pos) value, pos = CommFunc.ReadString(pdata, pos, sLen) else: continue dataList.append(value) GameWorld.DebugLog("ÊÕµ½Ö÷·þÊý¾Ý: dataType=%s,dataList=%s" % (dataType, dataList), curPlayer.GetPlayerID()) callFunc(curPlayer, dataList) return def IsNeedProcessCrossPlayer(curPlayer): ## ÊÇ·ñÐèÒª´¦Àíͬ²½¿ç·þÖеÄÍæ¼ÒÊý¾Ý if GameWorld.IsCrossServer(): return crossMapID = curPlayer.NomalDictGetProperty(ChConfig.Def_PlayerKey_CrossRegisterMap) if not crossMapID: crossMapID = PlayerControl.GetCrossMapID(curPlayer) if not crossMapID or crossMapID not in ChConfig.Def_CrossMapIDList: return # ²»ÐèÒª´¦ÀíµÄ¿ç·þµØÍ¼ if crossMapID in [ChConfig.Def_FBMapID_CrossRealmPK]: return if not IpyGameDataPY.GetFuncCfg("CrossSyncPlayerData", 1): return return True def ClearCrossSyncDataCache(curPlayer): ## Çå³ýͬ²½¿ç·þÊý¾ÝµÄÁÙʱ»º´æ playerID = curPlayer.GetPlayerID() PyGameData.g_crossRegPlayerAttrDict.pop(playerID, None) PyGameData.g_crossSyncTickDict.pop(playerID, None) PyGameData.g_crossPlayerDictChangeInfo.pop(playerID, None) PyGameData.g_crossPlayerDienstgradChangeInfo.pop(playerID, None) GameWorld.DebugLog("Çå³ýͬ²½¿ç·þÊý¾ÝµÄÁÙʱ»º´æ", playerID) return def OnPlayerCrossReg(curPlayer): ## Íæ¼Ò¿ç·þÊý¾Ý×¢²á if not IsNeedProcessCrossPlayer(curPlayer): return ClearCrossSyncDataCache(curPlayer) attrList = [] for attrInfo in CrossFightPowerAttrList: attrList.append(attrInfo[0](curPlayer)) playerID = curPlayer.GetPlayerID() PyGameData.g_crossRegPlayerAttrDict[playerID] = attrList return def OnDienstgradChange(curPlayer, dienstgradID, state): ## ³ÆºÅ±ä¸ü if not IsNeedProcessCrossPlayer(curPlayer): return playerID = curPlayer.GetPlayerID() dienstgradStateDict = PyGameData.g_crossPlayerDienstgradChangeInfo.get(playerID, {}) dienstgradStateDict[dienstgradID] = state PyGameData.g_crossPlayerDienstgradChangeInfo[playerID] = dienstgradStateDict return def OnPlayerFightPowerChange(curPlayer): ## Íæ¼ÒÕ½Á¦±ä¸üʱ if not IsNeedProcessCrossPlayer(curPlayer): return playerID = curPlayer.GetPlayerID() if playerID in PyGameData.g_crossSyncTickDict: return tick = GameWorld.GetGameWorld().GetTick() PyGameData.g_crossSyncTickDict[playerID] = tick #GameWorld.DebugLog("±ê¼ÇÐèҪͬ²½¿ç·þÍæ¼ÒÕ½Á¦±ä¸üÏà¹ØÊý¾Ý! tick=%s" % tick, curPlayer.GetPlayerID()) return def ProcessCrossPlayer(curPlayer, tick): ## ¿ç·þ״̬µÄ±¾·þÍæ¼Ò´¦Àí if not IsNeedProcessCrossPlayer(curPlayer): return playerID = curPlayer.GetPlayerID() if playerID not in PyGameData.g_crossSyncTickDict: return setTick = PyGameData.g_crossSyncTickDict[playerID] if tick - setTick < IpyGameDataPY.GetFuncCfg("CrossSyncPlayerData", 1) * 1000: return PyGameData.g_crossSyncTickDict.pop(playerID) GameWorld.DebugLog("¿ªÊ¼Í¬²½±¾·þ±ä¸üµÄÊôÐÔ...", playerID) try: # ÕâÀïÖ»×ö¿ÉÄÜÒýÆðÕ½Á¦±ä»¯ËùÐèҪͬ²½µÄÊý¾Ý data = "" data = CommFunc.WriteBYTE(data, MergeData_Player) data = __WriteSyncPlayerAttrData(curPlayer, data) # Íæ¼ÒÊôÐÔ data = __WriteSyncPlayerDictData(curPlayer, data) # ×Öµä data = __WriteSyncPlayerDienstgradData(curPlayer, data) # ³ÆºÅ # ÎïÆ· # ¼¼ÄÜ #Ö±½ÓÓÃ×Ö½ÚÁ÷»á±¨´í data = base64.b64encode(data) curPlayer.SendMergePlayerData(data) except BaseException: errorMsg = str(traceback.format_exc()) GameWorld.ErrLog('´ò°ü¿ç·þ±ä¸üÍæ¼ÒÊý¾Ý´íÎó - > %s' % errorMsg, curPlayer.GetPlayerID()) if GameWorld.GetGameWorld().GetDebugLevel(): raise Exception(errorMsg) return def __ReadMainServerSyncPlayerData(curPlayer, pdata, pos): ## ¶ÁÈ¡×Ó·þͬ²½µÄÍæ¼ÒÕ½Á¦±ä¸üÏà¹ØÊôÐÔ GameWorld.DebugLog("ÊÕµ½×Ó·þͬ²½µÄÍæ¼Ò±ä¸üÊý¾Ý:", curPlayer.GetPlayerID()) pos = __ReadSyncPlayerAttrData(curPlayer, pdata, pos) # Íæ¼ÒÊôÐÔ pos = __ReadSyncPlayerDictData(curPlayer, pdata, pos) # ×Öµä pos = __ReadSyncPlayerDienstgradData(curPlayer, pdata, pos) # ³ÆºÅ # ÎïÆ· # ¼¼ÄÜ # ǿˢһ´ÎÊôÐÔ PlayerControl.PlayerControl(curPlayer).ReCalcAllState() return def __WriteSyncPlayerAttrData(curPlayer, data): ## дÈëÐèҪͬ²½µÄÍæ¼ÒÊôÐÔ playerID = curPlayer.GetPlayerID() if playerID not in PyGameData.g_crossRegPlayerAttrDict: return CommFunc.WriteBYTE(data, 0) attrList = PyGameData.g_crossRegPlayerAttrDict[playerID] if len(attrList) != len(CrossFightPowerAttrList): return CommFunc.WriteBYTE(data, 0) changeAttrList = [] for i, attrInfo in enumerate(CrossFightPowerAttrList): befValue = attrList[i] curValue = attrInfo[0](curPlayer) if befValue == curValue: continue changeAttrList.append([i, curValue]) attrList[i] = curValue # ¸üмǼµÄÖµ if not changeAttrList: return CommFunc.WriteBYTE(data, 0) count = len(changeAttrList) GameWorld.DebugLog("±ä¸üµÄÍæ¼ÒÊôÐÔ¸öÊý: %s" % count) data = CommFunc.WriteBYTE(data, count) for index, curValue in changeAttrList: data = CommFunc.WriteBYTE(data, index) data = CommFunc.WriteDWORD(data, curValue) GameWorld.DebugLog(" index=%s,value=%s" % (index, curValue)) return data def __ReadSyncPlayerAttrData(curPlayer, pdata, pos): ## ¶Áȡͬ²½µÄÍæ¼ÒÊôÐÔ pdata = base64.b64decode(pdata) count, pos = CommFunc.ReadBYTE(pdata, pos) GameWorld.DebugLog("±ä¸üµÄÍæ¼ÒÊôÐÔ¸öÊý: %s" % count) for _ in range(count): index, pos = CommFunc.ReadBYTE(pdata, pos) value, pos = CommFunc.ReadDWORD(pdata, pos) CrossFightPowerAttrList[index][1](curPlayer, value) # ÉèÖøüÐÂÖµ GameWorld.DebugLog(" index=%s,value=%s" % (index, value)) return pos def __WriteSyncPlayerDictData(curPlayer, data): ## дÈëÐèҪͬ²½µÄÍæ¼Ò×Öµä playerID = curPlayer.GetPlayerID() if playerID not in PyGameData.g_crossPlayerDictChangeInfo: return CommFunc.WriteWORD(data, 0) changeDict = PyGameData.g_crossPlayerDictChangeInfo.pop(playerID) count = len(changeDict) GameWorld.DebugLog("±ä¸üµÄÍæ¼Ò×Öµä¸öÊý: %s" % count) data = CommFunc.WriteWORD(data, count) for keyInfo, value in changeDict.items(): key, dType = keyInfo keyLen = len(key) data = CommFunc.WriteBYTE(data, keyLen) data = CommFunc.WriteString(data, keyLen, key) data = CommFunc.WriteDWORD(data, value) data = CommFunc.WriteBYTE(data, dType) GameWorld.DebugLog(" key=%s, value=%s, dType=%s" % (key, value, dType)) return data def __ReadSyncPlayerDictData(curPlayer, pdata, pos): ## ¶Áȡͬ²½µÄÍæ¼Ò×Öµä pdata = base64.b64decode(pdata) count, pos = CommFunc.ReadWORD(pdata, pos) GameWorld.DebugLog("±ä¸üµÄÍæ¼Ò×Öµä¸öÊý: %s" % count) for _ in xrange(count): keyLen, pos = CommFunc.ReadBYTE(pdata, pos) key, pos = CommFunc.ReadString(pdata, pos, keyLen) value, pos = CommFunc.ReadDWORD(pdata, pos) dType, pos = CommFunc.ReadBYTE(pdata, pos) PlayerControl.NomalDictSetProperty(curPlayer, key, value, dType) GameWorld.DebugLog(" key=%s, value=%s, dType=%s" % (key, value, dType)) return pos def __WriteSyncPlayerDienstgradData(curPlayer, data): ## дÈëÐèҪͬ²½µÄÍæ¼Ò³ÆºÅ playerID = curPlayer.GetPlayerID() if playerID not in PyGameData.g_crossPlayerDienstgradChangeInfo: return CommFunc.WriteBYTE(data, 0) changeDienstgradDict = PyGameData.g_crossPlayerDienstgradChangeInfo.pop(playerID) count = len(changeDienstgradDict) GameWorld.DebugLog("±ä¸üµÄÍæ¼Ò³ÆºÅ¸öÊý: %s" % count) data = CommFunc.WriteBYTE(data, count) for dienstgradID, state in changeDienstgradDict.items(): data = CommFunc.WriteDWORD(data, dienstgradID) data = CommFunc.WriteBYTE(data, state) GameWorld.DebugLog(" dienstgradID=%s, state=%s" % (dienstgradID, state)) return data def __ReadSyncPlayerDienstgradData(curPlayer, pdata, pos): ## ¶Áȡͬ²½µÄÍæ¼Ò³ÆºÅ pdata = base64.b64decode(pdata) count, pos = CommFunc.ReadBYTE(pdata, pos) GameWorld.DebugLog("±ä¸üµÄÍæ¼Ò³ÆºÅ¸öÊý: %s" % count) for _ in xrange(count): dienstgradID, pos = CommFunc.ReadDWORD(pdata, pos) state, pos = CommFunc.ReadBYTE(pdata, pos) GameWorld.DebugLog(" dienstgradID=%s, state=%s" % (dienstgradID, state)) if state: PlayerDienstgrad.PlayerAddDienstgrad(curPlayer, dienstgradID, isRefreshAttr=False) else: PlayerDienstgrad.PlayerDelDienstgrad(curPlayer, dienstgradID, False) return pos