From ed55412a729dc711b908bef765e2465866b2c4e7 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期四, 17 一月 2019 23:07:52 +0800 Subject: [PATCH] 5722 【后端】【1.5】跨服BOSS开发(同步影响玩家战力的属性、字典到跨服服务器,暂定延迟5秒同步) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py | 197 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 195 insertions(+), 2 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..ec3ae5c 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py @@ -20,6 +20,7 @@ import SkillCommon import base64 import ChConfig +import PyGameData # 发送格式: 类型+(数量)+数据 # 向跨服发送的数据类型 @@ -30,8 +31,17 @@ 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]: @@ -88,9 +98,192 @@ 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 + + + -- Gitblit v1.8.0