| | |
| | | import SkillCommon
|
| | | import base64
|
| | | import ChConfig
|
| | | import PyGameData
|
| | |
|
| | | # 发送格式: 类型+(数量)+数据
|
| | | # 向跨服发送的数据类型
|
| | |
| | | MergeData_Buff, # 即时发送
|
| | | ) = range(0, 4)
|
| | |
|
| | | # 发送主服玩家数据给跨服
|
| | | # 影响跨服战力属性列表
|
| | | 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.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]:
|
| | |
| | |
|
| | | buffType = SkillCommon.GetBuffType(curSkill)
|
| | | BuffSkill.AddBuffNoRefreshState(curPlayer, buffType, curSkill, tick, plusValueList)
|
| | |
|
| | | |
| | | elif dataType == MergeData_Player:
|
| | | __ReadMainServerSyncPlayerData(curPlayer, curPlayer.GetMergePlayerData(), pos)
|
| | |
|
| | | 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
|
| | | |
| | | 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)
|
| | | 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 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 < 5000:
|
| | | return
|
| | | PyGameData.g_crossSyncTickDict.pop(playerID)
|
| | | GameWorld.DebugLog("开始同步本服变更的属性...", playerID)
|
| | | |
| | | # 这里只做可能引起战力变化所需要同步的数据
|
| | | data = ""
|
| | | data = __WriteSyncPlayerAttrData(curPlayer, data) # 玩家属性
|
| | | data = __WriteSyncPlayerDictData(curPlayer, data) # 字典
|
| | | # 物品
|
| | | |
| | | # 技能
|
| | | |
| | | #直接用字节流会报错
|
| | | data = base64.b64encode(data)
|
| | | curPlayer.SendMergePlayerData(data)
|
| | | return
|
| | |
|
| | | def __ReadMainServerSyncPlayerData(curPlayer, pdata, pos):
|
| | | ## 读取子服同步的玩家战力变更相关属性
|
| | | |
| | | GameWorld.DebugLog("收到子服同步的玩家变更数据:", curPlayer.GetPlayerID())
|
| | | |
| | | pos = __ReadSyncPlayerAttrData(curPlayer, pdata, pos) # 玩家属性
|
| | | pos = __ReadSyncPlayerDictData(curPlayer, pdata, pos) # 字典
|
| | | # 物品
|
| | | |
| | | # 技能
|
| | | |
| | | # 强刷一次属性
|
| | | PlayerControl.PlayerControl(curPlayer).ReCalcAllState()
|
| | | return
|
| | |
|
| | | def __WriteSyncPlayerAttrData(curPlayer, data):
|
| | | ## 写入需要同步的玩家属性
|
| | | |
| | | data = CommFunc.WriteBYTE(data, MergeData_Player)
|
| | | 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.WriteBYTE(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
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|