#!/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  
 | 
import ShareDefine  
 | 
import md5  
 | 
# ·¢Ë͸ñʽ£º ÀàÐÍ+£¨ÊýÁ¿£©+Êý¾Ý  
 | 
# Ïò¿ç·þ·¢Ë͵ÄÊý¾ÝÀàÐÍ  
 | 
(  
 | 
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())  
 | 
        if not pdata:  
 | 
            return  
 | 
        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.RaiseException('½ÓÊÕ¿ç·þ±ä¸üÍæ¼ÒÊý¾Ý´íÎó \r\n%s' % errorMsg, curPlayer.GetPlayerID())  
 | 
    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)  
 | 
    PyGameData.g_crossPlayerItemsChangeInfo.pop(playerID, None)  
 | 
    PyGameData.g_crossPlayerSkillsChangeInfo.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  
 | 
      
 | 
    OnPlayerCrossRegItems(curPlayer)     # ÎïÆ·  
 | 
    OnPlayerCrossRegSkills(curPlayer)   # ¼¼ÄÜ  
 | 
    return  
 | 
  
 | 
# ÎïÆ·Êý¾Ý¸üР 
 | 
def OnPlayerCrossRegItems(curPlayer):  
 | 
    # Ó°ÏìÕ½Á¦µÄÎïÆ·£¬Ð¹¦ÄÜ×¢ÒâÌí¼Ó£¬Ï´ÎÐèÒª¼ÓÉÏÖïÏÉËþ  
 | 
    PyGameData.g_crossPlayerItemsChangeInfo[curPlayer.GetPlayerID()] = GetPlayerCrossRegItems(curPlayer)  
 | 
      
 | 
    return  
 | 
  
 | 
def GetPlayerCrossRegItems(curPlayer):  
 | 
    itemsDict = {}  
 | 
    # Ó°ÏìÕ½Á¦µÄÎïÆ·£¬Ð¹¦ÄÜ×¢ÒâÌí¼Ó£¬Ï´ÎÐèÒª¼ÓÉÏÖïÏÉËþ  
 | 
      
 | 
    packList = [IPY_GameWorld.rptEquip, ShareDefine.rptPet, ShareDefine.rptDogzEquip]  
 | 
    for packIndex in packList:  
 | 
        curPack = curPlayer.GetItemManager().GetPack(packIndex)  
 | 
        for i in range(curPack.GetCount()):  
 | 
            curItem = curPack.GetAt(i)  
 | 
            if not curItem or curItem.IsEmpty():  
 | 
                continue  
 | 
              
 | 
            itemMark = (curItem.GetItemPlaceType(), curItem.GetItemPlaceIndex())  
 | 
            itemsDict[itemMark] = md5.md5(curItem.GetB64ItemData()).hexdigest()  
 | 
      
 | 
    return itemsDict  
 | 
  
 | 
# ¼¼ÄÜÊý¾Ý¸üР 
 | 
def OnPlayerCrossRegSkills(curPlayer):  
 | 
    PyGameData.g_crossPlayerSkillsChangeInfo[curPlayer.GetPlayerID()] = GetPlayerCrossRegSkills(curPlayer)  
 | 
      
 | 
def GetPlayerCrossRegSkills(curPlayer):  
 | 
    skills = []  
 | 
    skillManager = curPlayer.GetSkillManager()  
 | 
    for i in range(0 , skillManager.GetSkillCount()):  
 | 
        curSkill = skillManager.GetSkillByIndex(i)  
 | 
        skills.append(curSkill.GetSkillID())  
 | 
          
 | 
    return skills  
 | 
#===============================================================================  
 | 
# def test(curPlayer):  
 | 
#    curPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)  
 | 
#    curItem = curPack.GetAt(1)  
 | 
#    curItem.GetB64ItemData()  
 | 
#    curSingleItem = GameWorld.GetItemFactory().AddItem(curItem.GetB64ItemData())  
 | 
#    if not curSingleItem:  
 | 
#        return  
 | 
#      
 | 
#    curItem2 = curPack.GetAt(2)  
 | 
#    curItem2.AssignItem(curSingleItem)  
 | 
#===============================================================================  
 | 
      
 | 
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 = __WriteSyncPlayerItems(curPlayer, data)# ÎïÆ·  
 | 
        data = __WriteSyncPlayerSkills(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) # ³ÆºÅ  
 | 
    pos = __ReadSyncPlayerItems(curPlayer, pdata, pos)  # ÎïÆ·  
 | 
    pos = __ReadSyncPlayerSkills(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  
 | 
  
 | 
def __WriteSyncPlayerItems(curPlayer, data):  
 | 
    ## Ð´ÈëÐèҪͬ²½µÄÍæ¼ÒÎïÆ·£¬°üº¬É¾³ý  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    if playerID not in PyGameData.g_crossPlayerItemsChangeInfo:  
 | 
        data = CommFunc.WriteBYTE(data, 0)  # É¾³ý  
 | 
        data = CommFunc.WriteBYTE(data, 0)  # Ôö¸Ä  
 | 
        return data  
 | 
    lastItems = PyGameData.g_crossPlayerItemsChangeInfo[playerID]  
 | 
    # ¶Ô±ÈÊý¾ÝÇø·ÖÔö¸ÄºÍɾ³ý  
 | 
    nowItems = GetPlayerCrossRegItems(curPlayer)  
 | 
      
 | 
    delItems = []  
 | 
    addItems = []  
 | 
    # --ɾ³ýÎïÆ·  
 | 
    for indexs in lastItems:  
 | 
        if indexs not in nowItems:  
 | 
            delItems.append(indexs)  
 | 
      
 | 
    data = CommFunc.WriteBYTE(data, len(delItems))  # É¾³ýÊýÁ¿    
 | 
    for indexs in delItems:  
 | 
        data = CommFunc.WriteBYTE(data, indexs[0])  
 | 
        data = CommFunc.WriteBYTE(data, indexs[1])  
 | 
          
 | 
    # --Ìí¼ÓÐÞ¸ÄÎïÆ·  
 | 
    for indexs in nowItems:  
 | 
        if indexs not in lastItems:  
 | 
            addItems.append(indexs)  
 | 
        elif lastItems[indexs] != nowItems[indexs]:  
 | 
            addItems.append(indexs)  
 | 
              
 | 
    tmpData = ""  
 | 
    cnt = 0  
 | 
    for indexs in addItems:  
 | 
        curPack = curPlayer.GetItemManager().GetPack(indexs[0])  
 | 
        curItem = curPack.GetAt(indexs[1])  
 | 
        if not curItem or curItem.IsEmpty():  
 | 
            continue  
 | 
        itemData = base64.b64decode(curItem.GetB64ItemData())  
 | 
        tmpData = CommFunc.WriteWORD(tmpData, len(itemData))    # ÎïÆ·Êý¾Ý³¤¶È  
 | 
        tmpData = CommFunc.WriteString(tmpData, len(itemData), itemData)  
 | 
        cnt += 1  
 | 
      
 | 
    data = CommFunc.WriteBYTE(data, cnt)  # Ôö¸ÄÊýÁ¿    
 | 
    data += tmpData  
 | 
      
 | 
    # Í¬²½×îÐÂÎïÆ·Êý¾Ý  
 | 
    PyGameData.g_crossPlayerItemsChangeInfo[playerID] = nowItems  
 | 
    return data  
 | 
  
 | 
def __ReadSyncPlayerItems(curPlayer, pdata, pos):  
 | 
    ## ¶Áȡͬ²½µÄÍæ¼ÒÎïÆ·  
 | 
    pdata = base64.b64decode(pdata)  
 | 
    count, pos = CommFunc.ReadBYTE(pdata, pos)  
 | 
    GameWorld.DebugLog("ɾ³ýµÄÍæ¼ÒÎïÆ·¸öÊý: %s" % count)  
 | 
      
 | 
    # É¾³ýÎïÆ·  
 | 
    for _ in xrange(count):  
 | 
        packType, pos = CommFunc.ReadBYTE(pdata, pos)  
 | 
        itemIndex, pos = CommFunc.ReadBYTE(pdata, pos)  
 | 
        curPack = curPlayer.GetItemManager().GetPack(packType)  
 | 
        curItem = curPack.GetAt(itemIndex)  
 | 
        if not curItem or curItem.IsEmpty():  
 | 
            continue  
 | 
        curItem.Clear()  
 | 
          
 | 
          
 | 
    # Ôö¸ÄÎïÆ·  
 | 
    count, pos = CommFunc.ReadBYTE(pdata, pos)  
 | 
    GameWorld.DebugLog("Ôö¸ÄµÄÍæ¼ÒÎïÆ·¸öÊý: %s" % count)  
 | 
      
 | 
    for _ in xrange(count):  
 | 
        #def ReadString(buf, pos, _len):  
 | 
        itemDataLen, pos = CommFunc.ReadWORD(pdata, pos)  
 | 
        itemData, pos = CommFunc.ReadString(pdata, pos, itemDataLen)  
 | 
        curSingleItem = GameWorld.GetItemFactory().AddItem(base64.b64encode(itemData))  
 | 
        if not curSingleItem or curSingleItem.GetItemTypeID() == 0:  
 | 
            continue  
 | 
          
 | 
        curPack = curPlayer.GetItemManager().GetPack(curSingleItem.GetItemPlaceType())  
 | 
        curItem = curPack.GetAt(curSingleItem.GetItemPlaceIndex())  
 | 
        curItem.AssignItem(curSingleItem)  
 | 
  
 | 
    return pos  
 | 
  
 | 
  
 | 
def __WriteSyncPlayerSkills(curPlayer, data):  
 | 
    ## Ð´ÈëÐèҪͬ²½µÄÍæ¼Ò¼¼ÄÜ£¬°üº¬É¾³ý  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    if playerID not in PyGameData.g_crossPlayerSkillsChangeInfo:  
 | 
        data = CommFunc.WriteBYTE(data, 0)  # É¾³ý  
 | 
        data = CommFunc.WriteBYTE(data, 0)  # Ìí¼Ó  
 | 
        return data  
 | 
      
 | 
    # ¶Ô±ÈÊý¾ÝÇø·ÖÌí¼ÓºÍɾ³ý  
 | 
    lastSkills = PyGameData.g_crossPlayerSkillsChangeInfo[playerID]  
 | 
    nowSkills = GetPlayerCrossRegSkills(curPlayer)  
 | 
      
 | 
    delSkills = []  
 | 
    # --ɾ³ýÎïÆ·  
 | 
    for skillID in lastSkills:  
 | 
        if skillID not in nowSkills:  
 | 
            delSkills.append(skillID)  
 | 
      
 | 
    data = CommFunc.WriteBYTE(data, len(delSkills))  # É¾³ýÊýÁ¿    
 | 
    for skillID in delSkills:  
 | 
        data = CommFunc.WriteDWORD(data, skillID)  
 | 
          
 | 
    # --Ìí¼ÓÐÞ¸ÄÎïÆ·  
 | 
    addSkills = []  
 | 
    for skillID in nowSkills:  
 | 
        if skillID not in lastSkills:  
 | 
            addSkills.append(skillID)  
 | 
              
 | 
    data = CommFunc.WriteBYTE(data, len(addSkills))  # Ôö¼ÓÊýÁ¿    
 | 
    for skillID in addSkills:  
 | 
        data = CommFunc.WriteDWORD(data, skillID)  
 | 
          
 | 
      
 | 
    # Í¬²½×îм¼ÄÜÊý¾Ý  
 | 
    PyGameData.g_crossPlayerSkillsChangeInfo[playerID] = nowSkills  
 | 
    return data  
 | 
  
 | 
def __ReadSyncPlayerSkills(curPlayer, pdata, pos):  
 | 
    ## ¶Áȡͬ²½µÄÍæ¼Ò¼¼ÄÜ  
 | 
    skillManager = curPlayer.GetSkillManager()  
 | 
    pdata = base64.b64decode(pdata)  
 | 
    count, pos = CommFunc.ReadBYTE(pdata, pos)  
 | 
    GameWorld.DebugLog("ɾ³ýµÄÍæ¼Ò¼¼ÄܸöÊý: %s" % count)  
 | 
      
 | 
    # É¾³ý¼¼ÄÜ  
 | 
    for _ in xrange(count):  
 | 
        skillID, pos = CommFunc.ReadDWORD(pdata, pos)  
 | 
        skillManager.DeleteSkillBySkillID(skillID, False)  
 | 
  
 | 
    count, pos = CommFunc.ReadBYTE(pdata, pos)  
 | 
    GameWorld.DebugLog("Ôö¼ÓµÄÍæ¼Ò¼¼ÄܸöÊý: %s" % count)  
 | 
      
 | 
    # Ìí¼Ó¼¼ÄÜ  
 | 
    for _ in xrange(count):  
 | 
        skillID, pos = CommFunc.ReadDWORD(pdata, pos)  
 | 
        skillManager.LearnSkillByID(skillID, False)  
 | 
      
 | 
    return pos  
 | 
  
 |