From fc7847f19424c902c7e6fdac1d024b5039b3d725 Mon Sep 17 00:00:00 2001
From: xdh <xiefantasy@qq.com>
Date: 星期四, 14 二月 2019 15:16:49 +0800
Subject: [PATCH] 5315 【后端】【1.6】登录奖励活动

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py |  581 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 560 insertions(+), 21 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py
index 7eadb42..e0ae076 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py
@@ -20,7 +20,14 @@
 import SkillCommon
 import base64
 import ChConfig
-
+import PyGameData
+import PlayerDienstgrad
+import IpyGameDataPY
+import PlayerHorse
+import PlayerPet
+import traceback
+import ShareDefine
+import md5
 # 发送格式: 类型+(数量)+数据
 # 向跨服发送的数据类型
 (
@@ -28,10 +35,37 @@
 MergeData_Item,     # 对比处理 只算属性的背包 装备 宠物 
 MergeData_Skill,    # 只处理ID
 MergeData_Buff,     # 即时发送
-) = range(0, 4)
+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]:
@@ -68,29 +102,534 @@
         # 非跨服
         return
     
-    # 跨服服务器处理
-    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
+    try:
+        # 跨服服务器处理
+        curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+        pdata = base64.b64decode(curPlayer.GetMergePlayerData())
         
-        plusValueList = []
-        cnt, pos = CommFunc.ReadBYTE(pdata, pos)
-        for i in range(cnt):
-            value, pos = CommFunc.ReadDWORD(pdata, pos)
-            plusValueList.append(value)
+        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
             
-        buffType = SkillCommon.GetBuffType(curSkill)
-        BuffSkill.AddBuffNoRefreshState(curPlayer, buffType, curSkill, tick, plusValueList)
+            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)
+    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, ShareDefine.rptZhuXianEquip]
+    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
+

--
Gitblit v1.8.0