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 ++++++++++++++++++++++++++++++++++++++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py | 2
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py | 6 +
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py | 14 +++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py | 3
5 files changed, 220 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
+
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index 6e7664b..8d1217a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -86,6 +86,7 @@
import PlayerCrossRealmPK
import FunctionNPCCommon
import CrossRealmPlayer
+import CrossPlayerData
import ChNetSendPack
import PlayerCoat
import PlayerState
@@ -1208,6 +1209,9 @@
PyGameData.g_needRefreshMapServerState = True # 有玩家离开地图设置需要刷新
PlayerSuccess.FinishDelayAddSuccessProgress(curPlayer, tick)
+
+ if not isDisconnect:
+ CrossPlayerData.ClearCrossSyncDataCache(curPlayer)
return
##更新保存玩家在线时间
@@ -4787,6 +4791,7 @@
PlayerBillboard.UpdatePlayerFPTotalBillboard(curPlayer)
# 记录开服活动数据
OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_FightPower, totalFightPower)
+ CrossPlayerData.OnPlayerFightPowerChange(curPlayer)
return
def __RefreshMoveSpeed(self, allAttrListBuffs):
@@ -5744,6 +5749,8 @@
def GetCrossMapID(curPlayer): return curPlayer.GetExAttr5()
def SetCrossMapID(curPlayer, value):
curPlayer.SetExAttr5(value, False, True)
+ if not value:
+ CrossPlayerData.ClearCrossSyncDataCache(curPlayer)
return
## 铜钱点, 支持铜钱超20亿
@@ -6798,6 +6805,13 @@
#-------------------------------------------------------------------------------
## 设置玩家字典值, 存库
def NomalDictSetProperty(curPlayer, key, value, dType=0):
+ if CrossPlayerData.IsNeedProcessCrossPlayer(curPlayer) and key not in \
+ [ChConfig.Def_PDict_FightPower_Total, ChConfig.Def_PlayerKey_CrossRegisterMap]:
+ playerID = curPlayer.GetPlayerID()
+ changeDict = PyGameData.g_crossPlayerDictChangeInfo.get(playerID, {})
+ changeDict[(key, dType)] = value
+ PyGameData.g_crossPlayerDictChangeInfo[playerID] = changeDict
+
if value == 0:
curPlayer.NomalDictDelProperty(key, dType)
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
index b936a48..c99aa27 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -52,6 +52,7 @@
import PlayerTJG
import AICommon
import PlayerSuccess
+import CrossPlayerData
import PassiveBuffEffMng
import PlayerFamilyRedPacket
import FormulaControl
@@ -1273,6 +1274,8 @@
PlayerFlashSale.ProcessFlashSaleMail(curPlayer, tick)
#地图经验
ProcessAreaExp(curPlayer, tick)
+ #跨服数据同步,放最后
+ CrossPlayerData.ProcessCrossPlayer(curPlayer, tick)
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py
index 38697a6..70aff26 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossRealmReg.py
@@ -20,6 +20,7 @@
import CrossRealmPlayer
import IPY_GameWorld
import ChPyNetSendPack
+import CrossPlayerData
import NetPackCommon
import ChConfig
@@ -87,6 +88,7 @@
prepareEnterCrossServer.DataMapID = registerMap
NetPackCommon.SendFakePack(curPlayer, prepareEnterCrossServer)
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PlayerKey_CrossRegisterMap, registerMap)
+ CrossPlayerData.OnPlayerCrossReg(curPlayer)
#curPlayer.SendMergeRegisterPlayer(mapID, dataMapID, copyMapID, posX, posY)
curPlayer.SendMergeRegisterPlayerAfterChange(CrossRealmPlayer.GetCrossPlayerName(curPlayer), mapID, dataMapID, copyMapID, posX, posY)
GameWorld.Log(" 发送跨服玩家数据注册: registerMap=%s,zoneID=%s,mapID=%s,dataMapID=%s,copyMapID=%s,posX=%s,posY=%s,GetVsRoomId=%s"
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index 0c0ee25..ba5199f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -80,3 +80,9 @@
g_fbRobotJobDict = {} #副本机器人职业 {lineID:{objID:job, ...}, ...}
g_gathersoulfbAwardDict = {} #聚魂副本奖励记录{playerID:[[itemID,itemCnt]]}
+
+g_crossRegPlayerAttrDict = {} #跨服注册时登记的会影响战力的属性值 {playerID:[value, ...], ...}
+g_crossSyncTickDict = {} #需要同步跨服数据的玩家同步tick字典 {playerID:tick, ...}
+g_crossPlayerDictChangeInfo = {} #跨服玩家字典变化信息 {playerID:{(key, dType):value, ...}, ...}
+
+
--
Gitblit v1.8.0