From 5878f2872607b9b9186ad5ce3623aff88bbcef6b Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 04 三月 2025 16:34:07 +0800
Subject: [PATCH] 5563 【英文】【BT】跨服服务器维护优化(打包数据改为db自己管理存取)
---
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py | 13
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py | 7
ServerPython/db/PyMongoDataServer/__init__.py | 0
ServerPython/CoreServerGroup/GameServer/Script/GM/GMShell.py | 16
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetCrossPK.py | 16
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/PlayerMirror.py | 103 +----
ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py | 44 --
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py | 295 ++-------------
ServerPython/db/PyMongoDataServer/GM/Commands/__init__.py | 0
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py | 5
ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py | 7
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py | 84 ++--
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/QueryDBLogicResult.py | 8
ServerPython/db/PyMongoDataServer/GM/__init__.py | 0
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py | 232 ++++++++++-
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py | 6
ServerPython/db/PyMongoDataServer/GM/Commands/PlayerMirror.py | 108 ++++++
ServerPython/db/PyMongoDataServer/GM/GMShell.py | 112 ++++++
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py | 5
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MirrorBattle.py | 15
20 files changed, 617 insertions(+), 459 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
index bf17296..88bf6d7 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -448,8 +448,10 @@
# GameWorld.GetGameWorld().SendDBLogic(BYTE queryType, DWORD id, char* sData, int nDataLen)
# GameServer请求db逻辑类型,db接受 OnGameServerToDBLogic,回调 RecvDGDBLogicResult
(
-gstDBLogic_PlayerPackData, # 请求打包玩家数据 0
-) = range(1)
+gstDBLogic_PlayerPackDataReq, # 请求打包玩家数据,仅子服用 0
+gstDBLogic_PlayerPackDataUpd, # 更新打包玩家数据,仅子服用,跨服通过拦截消息处理即可 1
+gstDBLogic_GMCmd, # 更新打包玩家数据 2
+) = range(3)
#GM工具回复值
Def_GMTool_Succeed = 1
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/PlayerMirror.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/PlayerMirror.py
index f4d9a4b..7ac46d8 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/PlayerMirror.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/PlayerMirror.py
@@ -15,31 +15,20 @@
#"""Version = 2024-12-26 17:00"""
#-------------------------------------------------------------------------------
-import ChConfig
-import ShareDefine
-import PyDataManager
-import PlayerPackData
-import ReadChConfig
+import PlayerViewCache
import GameWorld
import base64
import random
+import PyDataManager
## 执行逻辑
# @param curPlayer 当前玩家
# @param gmList []
# @return None
def OnExec(curPlayer, gmList):
- if not gmList:
- return
- value = gmList[0]
- if value == "a":
- __addFackPackData(gmList[1:])
- elif value == "d":
- __delFackPackData()
- elif value == "p":
- __printPackData(gmList[1:])
- return
+ isSendToDB = True
+ return isSendToDB
def OnGetMergeParam(curPlayer):
return []
@@ -56,89 +45,53 @@
return
def __addFackPackData(gmList):
- ## 添加假的打包数据,一般用于开发测试功能用
- FakeName = "假名字".decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
- packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
- #GameWorld.DebugAnswer(curPlayer, "添加镜像: PlayerMirror a 个数 [起始ID 战力 区服ID 模版key]")
+ ## 添加假的打包数据,一般用于开发测试功能用,打包数据在db添加,GameServer添加查看缓存
+ #GameWorld.DebugAnswer(None, "跨服GameServer玩家查看数据数:%s" % PyDataManager.GetPlayerViewCachePyManager().GetCount())
+ #return
addCount = gmList[0] if len(gmList) > 0 else 1
startID = gmList[1] if len(gmList) > 1 else 1
fightPower = gmList[2] if len(gmList) > 2 else 0
serverID = gmList[3] if len(gmList) > 3 else 0
- packDataTempKey = gmList[4] if len(gmList) > 4 else ""
-
- jobFackPackDataDict = ReadChConfig.GetEvalChConfig("FackPackData")
+ #packDataTempKey = gmList[4] if len(gmList) > 4 else ""
addOKCount = 0
for index in range(addCount):
fackID = startID + index
- if packDataMgr.IsPlayerIn(fackID):
+ curCache = PlayerViewCache.FindViewCache(fackID, True)
+ if not curCache:
continue
+ propDict = PlayerViewCache.GetCachePropDataDict(curCache)
- job = random.randint(1, 2)
- tempKey = packDataTempKey if packDataTempKey else "job%s" % job
- if tempKey not in jobFackPackDataDict:
- GameWorld.DebugAnswer(None, "配置FackPackData.txt没有该模版key:%s" % tempKey)
- return
- packDataTeam = jobFackPackDataDict[tempKey]
- packDataTeamBuff = base64.b64decode(packDataTeam)
-
- tempDBPlayer = PlayerPackData.GetDBPlayerByPackData(packDataTeam)
- tempDBPlayer.PlayerID = fackID
- tempDBPlayer.PlayerName = "%s%s" % (FakeName, fackID)
- curServerID = serverID if serverID else fackID / 100
- if not curServerID:
- curServerID = 9999
- tempDBPlayer.AccID = "fack%s@test@s%s" % (fackID, curServerID)
- # 没有指定模版,则随机数据
- if not packDataTempKey:
- tempDBPlayer.Job = job
- tempDBPlayer.LV = random.randint(tempDBPlayer.LV, tempDBPlayer.LV + 2)
- tempDBPlayer.OfficialRank = random.randint(tempDBPlayer.OfficialRank, tempDBPlayer.OfficialRank + 2)
+ if serverID:
+ propDict["AccID"] = "fake%s@test@s%s" % (fackID, serverID)
- curFightPower = fightPower if fightPower else (tempDBPlayer.FightPowerEx * ChConfig.Def_PerPointValue + tempDBPlayer.FightPower)
- curFightPower += index
- tempDBPlayer.FightPower = curFightPower % ChConfig.Def_PerPointValue
- tempDBPlayer.FightPowerEx = curFightPower / ChConfig.Def_PerPointValue
-
- updBuff = tempDBPlayer.getBuffer() + packDataTeamBuff[tempDBPlayer.getLength():]
- updPackData = base64.b64encode(updBuff)
- packDataMgr.UpdPlayerPackData(fackID, updPackData)
+ if fightPower:
+ propDict["FightPower"] = fightPower + index
+
addOKCount += 1
- packDataMgr.Sort()
-
- GameWorld.DebugAnswer(None, "添加假玩家打包数据数:%s,总:%s" % (addOKCount, packDataMgr.GetCount()))
+ GameWorld.DebugAnswer(None, "跨服GameServer添加假玩家查看数据数:%s,%s~%s,总:%s"
+ % (addOKCount, startID, fackID, PyDataManager.GetPlayerViewCachePyManager().GetCount()))
return
def __delFackPackData():
delCount = 0
- packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
- for index in range(packDataMgr.GetCount())[::-1]:
- packObj = packDataMgr.At(index)
- if packObj.playerID >= 10000:
+ cacheMgr = PyDataManager.GetPlayerViewCachePyManager()
+ for index in range(cacheMgr.GetCount())[::-1]:
+ viewCache = cacheMgr.At(index)
+ if viewCache.PlayerID >= 10000:
continue
- packDataMgr.DelPlayerPackData(packObj.playerID)
+ cacheMgr.DelPlayerViewCache(viewCache.PlayerID)
delCount += 1
- GameWorld.DebugAnswer(None, "删除假玩家打包数据数:%s,剩:%s" % (delCount, packDataMgr.GetCount()))
+ GameWorld.DebugAnswer(None, "删除假玩家数据数:%s" % delCount)
return
def __printPackData(gmList):
- startIndex = gmList[0] if len(gmList) > 0 else 0
- printCount = gmList[1] if len(gmList) > 1 else 100
- packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
- packDataMgr.Sort()
- dataCount = packDataMgr.GetCount()
- GameWorld.DebugLog("=== 打包数据总数: dataCount=%s,startIndex=%s" % (dataCount, startIndex))
- for index in range(startIndex, startIndex + printCount):
- if index >= dataCount:
- break
- packObj = packDataMgr.At(index)
- playerID = packObj.playerID
- fightPower = packObj.fightPower
- serverID = packObj.serverID
- GameWorld.DebugLog("index=%s,playerID=%s,serverID=%s,fightPower=%s,%s" % (index, playerID, serverID, fightPower, packObj.GetBaseDict()))
- GameWorld.DebugAnswer(None, "输出完毕详见GameServer日志!总:%s" % (dataCount))
+ GameWorld.DebugAnswer(None, "跨服GameServer缓存条数:%s,打包条数:%s"
+ % (PyDataManager.GetPlayerViewCachePyManager().GetCount(),
+ PyDataManager.GetDBPlayerPackDataManager().GetCount()
+ ))
return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/GMShell.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/GMShell.py
index a9dfa02..c7b5484 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/GMShell.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/GMShell.py
@@ -102,7 +102,7 @@
callFunc = GameWorld.GetExecFunc(Commands, "%s.%s"%(callFunName, "OnGetMergeParam"))
if callFunc != None:
extendParamList = callFunc(curPlayer)
- CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_GMCMD, alist + extendParamList)
+ CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_GMCMD, {"cmdMsgList":alist + extendParamList})
callFunc = GameWorld.GetExecFunc(Commands, "%s.%s"%(callFunName, "OnExec"))
if callFunc == None:
@@ -111,8 +111,11 @@
GameWorld.DebugAnswer(curPlayer, 'no cmd !!!')
return
- callFunc(curPlayer, alist[1:])
-
+ isSendToDB = callFunc(curPlayer, alist[1:])
+ if isSendToDB:
+ msg = str(alist)
+ GameWorld.GetGameWorld().SendDBLogic(ChConfig.gstDBLogic_GMCmd, 0, msg, len(msg))
+
except BaseException:
GameWorld.DebugAnswer(curPlayer, "执行GM命令错误, 请查看GameServer日志!")
errorMsg = str(traceback.format_exc())
@@ -241,7 +244,12 @@
return cmdDict
## 收到子服务器发送的GM命令
-def ClientServerMsg_GMCMD(cmdMsgList, tick):
+def ClientServerMsg_GMCMD(msgData, tick):
+ cmdMsgList = msgData["cmdMsgList"]
+ dbAnswerList = msgData.get("dbAnswerList", [])
+ for dbAnswer in dbAnswerList:
+ GameWorld.DebugAnswer(None, dbAnswer)
+
if len(cmdMsgList) == 0:
return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
index d7ad0ea..3bdf3f6 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
@@ -1248,6 +1248,13 @@
text = text.decode(ShareDefine.Def_Game_Character_Encoding).encode(GetCharacterEncoding())
if curPlayer:
curPlayer.DebugAnswer(text)
+ else:
+ playerManager = GetPlayerManager()
+ for i in xrange(playerManager.GetActivePlayerCount()):
+ player = playerManager.GetActivePlayerAt(i)
+ if player == None:
+ continue
+ player.DebugAnswer(text)
return
def CrossServerMsg_DebugAnswer(msgData):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
index 294786f..6caac90 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
@@ -353,19 +353,6 @@
if not obj or not hasattr(obj, "playerName"):
return
- packDataObj = PyDataManager.GetDBPlayerPackDataManager().GetPlayerPackObj(playerID)
- # 如果有打包数据,以打包数据为准
- if packDataObj:
- obj.accID = packDataObj.accID
- obj.playerName = packDataObj.playerName
- obj.job = packDataObj.job
- obj.lv = packDataObj.lv
- obj.fightPower = packDataObj.fightPower
- obj.realmLV = packDataObj.realmLV
- obj.face = packDataObj.face
- obj.facePic = packDataObj.facePic
- return
-
if playerID < 10000:
if obj.playerName:
return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
index af170b4..5fe4e8d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmPK.py
@@ -22,6 +22,7 @@
import ChPyNetSendPack
import PyGameDataStruct
import PlayerDBGSEvent
+import PlayerViewCache
import CrossBillboard
import PyDataManager
import NetPackCommon
@@ -450,9 +451,10 @@
playerID = playerInfoDict["playerID"] # 角色ID
fightPower = playerInfoDict["fightPower"]
requestType = playerInfoDict.get("requestType", 0)
+ gmMatchIDList = playerInfoDict.get("gmMatchIDList", [])
isRefresh = requestType == 1
- OnRefreshPKMatch(zoneID, seasonID, playerID, fightPower, serverGroupID, isRefresh)
+ OnRefreshPKMatch(zoneID, seasonID, playerID, fightPower, serverGroupID, isRefresh, gmMatchIDList)
return
def ClientServerMsg_PKOver(serverGroupID, playerInfoDict, tick):
@@ -512,9 +514,8 @@
# 通知子服
pkScore = updScore
- packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
- tagPackObj = packDataMgr.GetPlayerPackObj(tagPlayerID)
- tagPlayerName = tagPackObj.playerName if tagPackObj else ""
+ tagCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(tagPlayerID))
+ tagPlayerName = tagCacheDict.get("Name", "")
winnerID = playerID if isWinner else tagPlayerID
timeStr = GameWorld.GetCurrentDataTimeStr()
playerOverDict = {}
@@ -526,30 +527,27 @@
OnRefreshPKMatch(zoneID, seasonID, playerID, fightPower, serverGroupID, True)
return
-def OnRefreshPKMatch(zoneID, seasonID, playerID, fightPower, serverGroupID, isRefresh):
+def OnRefreshPKMatch(zoneID, seasonID, playerID, fightPower, serverGroupID, isRefresh, gmMatchIDList=None):
# 刷新匹配数据
# @param isRefresh: 是否强制重新刷新
if isRefresh or playerID not in PyGameData.g_crossPKMatchDict:
# 执行匹配逻辑
- matchIDList = __DoPKMatch(zoneID, seasonID, playerID, fightPower)
- if matchIDList: # 有新结果才替换
- PyGameData.g_crossPKMatchDict[playerID] = matchIDList
-
- packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
+ __DoPKMatch(zoneID, seasonID, playerID, fightPower, gmMatchIDList)
+
matchIDList = PyGameData.g_crossPKMatchDict.get(playerID, [])
matchInfoDict = {}
for matchID in matchIDList:
- packObj = packDataMgr.GetPlayerPackObj(matchID)
- if not packObj:
+ viewCache = PlayerViewCache.FindViewCache(matchID)
+ if not viewCache:
continue
- matchInfoDict[matchID] = packObj.GetBaseDict()
+ matchInfoDict[matchID] = viewCache.getBuffer()
dataMsg = {"playerID":playerID, "matchIDList":matchIDList, "matchInfoDict":matchInfoDict}
CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PKMatchReqRet, dataMsg, [serverGroupID])
return
-def __DoPKMatch(zoneID, seasonID, playerID, fightPower):
+def __DoPKMatch(zoneID, seasonID, playerID, fightPower, gmMatchIDList=None):
## 执行匹配
if not IsCrossRealmPKMatchState():
@@ -630,12 +628,22 @@
matchIDList[-1] = robotID
GameWorld.DebugLog("没有匹配到机器人,概率直接匹配到机器人: robotID=%s" % robotID, playerID)
- GameWorld.DebugLog("最终匹配结果: matchIDList=%s" % str(matchIDList), playerID)
+ #GM指定匹配
+ if gmMatchIDList:
+ GameWorld.DebugLog("GM指定匹配目标玩家ID: gmMatchIDList=%s" % gmMatchIDList, playerID)
+ for gmMatchID in gmMatchIDList:
+ if matchIDList:
+ matchIDList.pop(0)
+ matchIDList.append(gmMatchID)
+
+ GameWorld.DebugLog("最终匹配结果: matchIDList=%s" % str(matchIDList), playerID)
+ if matchIDList: # 有新结果才替换
+ PyGameData.g_crossPKMatchDict[playerID] = matchIDList
return matchIDList
def __addRandMatchID(playerID, matchIndex, rankRange, randIDList, matchIDList, loopPlayerIDList, sign):
## 根据所有可循环玩家ID列表,添加对应匹配轮次可随机匹配的玩家
- packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
+ pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()
indexStart = matchIndex * rankRange
indexEnd = indexStart + rankRange - 1
loopIDCount = len(loopPlayerIDList)
@@ -653,8 +661,8 @@
if dataID in matchIDList:
GameWorld.DebugLog(" 不可添加已匹配过玩家: dataID=%s,randIDList=%s,matchIDList=%s" % (dataID, randIDList, matchIDList), playerID)
continue
- if not packDataMgr.IsPlayerIn(dataID):
- GameWorld.DebugLog(" 不匹配无打包数据玩家: dataID=%s,randIDList=%s" % (dataID, randIDList), playerID)
+ if not pyViewCacheMgr.IsPlayerIn(dataID):
+ GameWorld.DebugLog(" 不匹配无缓存数据玩家: dataID=%s,randIDList=%s" % (dataID, randIDList), playerID)
continue
randIDList.append(dataID)
GameWorld.DebugLog(" 添加可以随机匹配玩家: dataID=%s,randIDList=%s" % (dataID, randIDList), playerID)
@@ -666,10 +674,9 @@
crossZoneName = GameWorld.GetCrossZoneName()
zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, zoneID)
if zoneIpyData:
- packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
- packDataMgr.Sort()
serverIDList = zoneIpyData.GetServerGroupIDList()
- zonePackPlayerIDList = packDataMgr.GetPlayerIDListByServerIDInfo(zoneIpyData.GetServerGroupIDList())
+ pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()
+ zonePackPlayerIDList = pyViewCacheMgr.GetPlayerIDListByServerIDInfo(serverIDList)
GameWorld.DebugLog(" 获得赛区活跃打包数据玩家: zoneID=%s,serverIDList=%s,%s,%s"
% (zoneID, serverIDList, len(zonePackPlayerIDList), zonePackPlayerIDList), playerID)
return zonePackPlayerIDList
@@ -824,22 +831,27 @@
matchOKPack.MatchPlayer = []
for matchID in matchIDList:
matchPlayer = ChPyNetSendPack.tagGCCrossRealmPKMatchPlayer()
- if matchID not in matchInfoDict:
- matchPlayer.PlayerID = matchID
- matchOKPack.MatchPlayer.append(matchPlayer)
- continue
- matchInfo = matchInfoDict[matchID]
- matchPlayer.PlayerID = matchInfo["playerID"]
- matchPlayer.PlayerName = matchInfo["playerName"]
- matchPlayer.NameLen = len(matchPlayer.PlayerName)
- matchPlayer.Job = matchInfo["job"]
- matchPlayer.LV = matchInfo["lv"]
- matchPlayer.RealmLV = matchInfo["realmLV"]
- matchPlayer.Face = matchInfo["face"]
- matchPlayer.FacePic = matchInfo["facePic"]
- matchPlayer.FightPower = matchInfo["fightPower"] % ChConfig.Def_PerPointValue
- matchPlayer.FightPowerEx = matchInfo["fightPower"] / ChConfig.Def_PerPointValue
+ matchPlayer.PlayerID = matchID
matchOKPack.MatchPlayer.append(matchPlayer)
+ if matchID not in matchInfoDict:
+ continue
+ cacheBuffer = matchInfoDict[matchID]
+ curCache = PlayerViewCache.ReadCacheBufferToCacheObj(matchID, cacheBuffer)
+ if not curCache:
+ continue
+ PlayerViewCache.Sync_PlayerCache(curPlayer, curCache)
+ cacheDict = PlayerViewCache.GetCachePropDataDict(curCache)
+ matchPlayer.PlayerID = matchID
+ matchPlayer.PlayerName = cacheDict.get("Name", "")
+ matchPlayer.NameLen = len(matchPlayer.PlayerName)
+ matchPlayer.Job = cacheDict.get("Job", 1)
+ matchPlayer.LV = cacheDict.get("LV", 1)
+ matchPlayer.RealmLV = cacheDict.get("RealmLV", 0)
+ matchPlayer.Face = cacheDict.get("Face", 0)
+ matchPlayer.FacePic = cacheDict.get("FacePic", 0)
+ matchPlayer.FightPower = cacheDict.get("FightPower", 0) % ChConfig.Def_PerPointValue
+ matchPlayer.FightPowerEx = cacheDict.get("FightPower", 0) / ChConfig.Def_PerPointValue
+ #matchOKPack.MatchPlayer.append(matchPlayer)
matchOKPack.MatchPlayerCount = len(matchOKPack.MatchPlayer)
NetPackCommon.SendFakePack(curPlayer, matchOKPack)
return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/QueryDBLogicResult.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/QueryDBLogicResult.py
index b58cd0b..d8aca7c 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/QueryDBLogicResult.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/QueryDBLogicResult.py
@@ -9,6 +9,7 @@
import PlayerPackData
import IPY_GameServer
import ChConfig
+import GameWorld
#-------------------------------------------------------------------------
@@ -36,11 +37,16 @@
return
queryType = dbResultPack.GetQueryType()
- if queryType == ChConfig.gstDBLogic_PlayerPackData:
+ if queryType == ChConfig.gstDBLogic_PlayerPackDataReq:
mirrorID = dbResultPack.GetID()
playerData = dbResultPack.GetResultSet()
msgInfo = eval(dbResultPack.GetData())
PlayerPackData.OnDBPlayerPackData(mirrorID, playerData, msgInfo)
+ elif queryType == ChConfig.gstDBLogic_GMCmd:
+ dbAnswerList = eval(dbResultPack.GetResultSet())
+ for dbAnswer in dbAnswerList:
+ GameWorld.DebugAnswer(None, dbAnswer)
+
return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py
index 49e8ab3..8775a48 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py
@@ -24,25 +24,25 @@
# 如切磋一下,玩家可以在任意场景对任意本服或跨服玩家发起切磋,与其镜像进行一场友谊PK,纯娱乐
# 这种为被动式,即目标玩家可能不存在打包数据表中,需要取拉取
#
+# 由于打包数据较大,影响开关服及备档的速度,还会导致内存不足,故改为db直接管理打包数据获取及入库
+# GameServer仅保留单次启动后有同步/获取的玩家数据,一般比db少,只保留打包数据信息,玩家基本信息改为从ViewCahce中获取
#-------------------------------------------------------------------------------
#"""Version = 2024-10-17 15:00"""
#-------------------------------------------------------------------------------
-import CommFunc
import GameWorld
import PyDataManager
import PlayerViewCache
import PyGameDataStruct
-import CrossChampionship
import CrossRealmMsg
import PlayerControl
import ShareDefine
import PyGameData
import ChConfig
-import time
import base64
+Def_CahceCountMax = 100 # 最大缓存个数,注:GameServer缓不缓存这个数据都无所谓(改为在db缓存),保留原取数据逻辑不变,暂时缓存个x条,方便本服的直接取
TempDBPlayer = PyGameDataStruct.tagDBPlayer()
def GetDBPlayerByPackData(packData):
@@ -51,249 +51,48 @@
if packData:
TempDBPlayer.readData(base64.b64decode(packData))
return TempDBPlayer
-
-class PlayerPackDataObj():
-
- def __init__(self):
- self.dbPlayerPackData = None
- self.playerID = 0
- self.playerName = ""
- self.accID = ""
- self.lv = 0
- self.job = 0
- self.realmLV = 0
- self.face = 0
- self.facePic = 0
- self.fightPower = 0
- self.serverID = 0
- return
-
- def GetBaseDict(self):
- return {"playerID":self.playerID, "playerName":self.playerName, "lv":self.lv, "job":self.job,
- "realmLV":self.realmLV, "face":self.face, "facePic":self.facePic, "fightPower":self.fightPower}
-
- def UpdPackData(self, packData):
- if not packData:
- return
- if not self.dbPlayerPackData:
- self.dbPlayerPackData = PyGameDataStruct.tagDBPlayerPackData()
- self.dbPlayerPackData.PlayerID = self.playerID
- self.dbPlayerPackData.PackData = packData
- self.dbPlayerPackData.PackDataSize = len(self.dbPlayerPackData.PackData)
- self.dbPlayerPackData.UpdTime = int(time.time())
- self.Unpack()
- return
-
- def Unpack(self):
- if not self.dbPlayerPackData:
- return
- dbPlayer = GetDBPlayerByPackData(self.dbPlayerPackData.PackData)
- self.playerID = dbPlayer.PlayerID
- self.accID = dbPlayer.AccID
- self.playerName = dbPlayer.PlayerName
- self.lv = dbPlayer.LV
- self.job = dbPlayer.Job
- self.realmLV = dbPlayer.OfficialRank
- self.face = dbPlayer.Face
- self.facePic = dbPlayer.FacePic
- self.fightPower = dbPlayer.FightPowerEx * ChConfig.Def_PerPointValue + dbPlayer.FightPower
- self.serverID = GameWorld.GetAccIDServerID(self.accID)
- return
-
- def GetPackData(self): return self.dbPlayerPackData.PackData if self.dbPlayerPackData else ""
- def GetUpdTime(self): return self.dbPlayerPackData.UpdTime if self.dbPlayerPackData else 0
class DBPlayerPackDataManager():
- ## 玩家打包数据管理
+ ## 玩家打包数据管理 - 这里仅管理本次启动后的热数据缓存,不入库
def __init__(self):
self.Clear()
return
def Clear(self):
- self.__packDataList = [] # [PlayerPackDataObj, ...]
- self.__idIndexDict = {} # {playerID:index, ...}
- self.__needSort = False
- self.__serverIDRangePlayerIDDict = {} # {serverIDRangeTuple:[playerID, ...], ....}
+ self.__packDataDcit = {} # {playerID:packData, ...}
+ self.__packDataPlayerIDList = [] # [playerID, ...] # 限制缓存数,先进先出
return
-
- def GetPlayerPackObj(self, playerID, isAddNew=False):
- packDataObj = None
- self.__refreshIDIndex()
- if playerID in self.__idIndexDict:
- index = self.__idIndexDict[playerID]
- if index < len(self.__packDataList):
- packDataObj = self.__packDataList[index]
-
- if not packDataObj and isAddNew:
- packDataObj = PlayerPackDataObj()
- packDataObj.playerID = playerID
- self.__packDataList.append(packDataObj)
- self.__idIndexDict[playerID] = len(self.__packDataList) - 1
- self.__needSort = True
-
- return packDataObj
-
- def GetPlayerIDListByServerIDInfo(self, serverIDList):
- ## 根据服务器ID列表信息获取对应服务器ID范围的玩家ID战力排序列表
- self.Sort()
- key = tuple(serverIDList)
- if key not in self.__serverIDRangePlayerIDDict:
- playerIDList = []
- for dataObj in self.__packDataList:
- playerID = dataObj.playerID
- serverID = dataObj.serverID
- for idInfo in serverIDList:
- if (isinstance(idInfo, int) and serverID == idInfo) \
- or ((isinstance(idInfo, tuple) or isinstance(idInfo, list)) \
- and len(idInfo) == 2 and idInfo[0] <= serverID <= idInfo[1]):
- playerIDList.append(playerID)
- GameWorld.DebugLog("重新加载区服打包玩家ID列表: %s, %s, %s" % (key, len(playerIDList), playerIDList))
- self.__serverIDRangePlayerIDDict[key] = playerIDList
- return self.__serverIDRangePlayerIDDict[key]
-
+
def IsPlayerIn(self, playerID):
- self.__refreshIDIndex()
- return playerID in self.__idIndexDict
+ return playerID in self.__packDataDcit
- def __refreshIDIndex(self):
- if not self.__idIndexDict:
- self.__idIndexDict = {}
- for index, dataObj in enumerate(self.__packDataList):
- self.__idIndexDict[dataObj.playerID] = index
- return self.__idIndexDict
+ def GetCount(self): return len(self.__packDataDcit)
+
+ def GetPlayerPackdata(self, playerID):
+ if playerID not in self.__packDataDcit:
+ return ""
+ # 恢复数据热度
+ if playerID in self.__packDataPlayerIDList:
+ self.__packDataPlayerIDList.remove(playerID)
+ self.__packDataPlayerIDList.append(playerID)
+ GameWorld.DebugLog("获取打包数据缓存数更新: %s,%s" % (len(self.__packDataPlayerIDList), self.__packDataPlayerIDList))
+ return self.__packDataDcit[playerID]
def UpdPlayerPackData(self, playerID, packData):
if not packData:
return
- packObj = self.GetPlayerPackObj(playerID, True)
- packObj.UpdPackData(packData)
- self.__needSort = True
- return packObj
-
- def DelPlayerPackData(self, playerID):
- self.__refreshIDIndex()
- index = self.__idIndexDict.pop(playerID, -1)
- if index >= 0 and index < len(self.__packDataList):
- self.__packDataList.pop(index)
- for playerIDList in self.__serverIDRangePlayerIDDict.values():
- if playerID in playerIDList:
- playerIDList.remove(playerID)
-
- #只要有删除,需重置index映射
- self.__idIndexDict = {}
- self.__serverIDRangePlayerIDDict = {}
+ self.__packDataDcit[playerID] = packData
+ if playerID in self.__packDataPlayerIDList:
+ # 添加热度,重复更新的不影响热度
+ self.__packDataPlayerIDList.append(playerID)
+ if len(self.__packDataPlayerIDList) > Def_CahceCountMax:
+ delPlayerID = self.__packDataPlayerIDList.pop(0)
+ if delPlayerID in self.__packDataDcit:
+ del self.__packDataDcit[delPlayerID]
+ GameWorld.DebugLog("删除打包数据缓存: delPlayerID=%s" % delPlayerID)
+ GameWorld.DebugLog("添加打包数据缓存数更新: %s,%s" % (len(self.__packDataPlayerIDList), self.__packDataPlayerIDList))
return
-
- def GetCount(self): return len(self.__packDataList)
- def At(self, index):
- dataObj = self.__packDataList[index]
- if not dataObj and False:
- dataObj = PlayerPackDataObj() # 不会执行到,只为了.出代码提示
- return dataObj
-
- def Sort(self):
- ## 默认按战力倒序排
- if not self.__needSort:
- return
- self.__needSort = False
- self.__packDataList.sort(key=lambda d: (d.fightPower), reverse=True)
- self.__idIndexDict = {}
- self.__serverIDRangePlayerIDDict = {}
- self.__refreshIDIndex()
- return
-
- # 保存数据 存数据库和realtimebackup
- def GetSaveData(self):
- savaData = ""
- cntData = ""
- cnt = 0
-
- for index in xrange(self.GetCount()):
- dataObj = self.At(index)
- if not dataObj.dbPlayerPackData:
- continue
- cnt += 1
- savaData += dataObj.dbPlayerPackData.getBuffer()
- if cnt >= 10:
- break
-
- GameWorld.Log("Save DBPlayerPackData count :%s len=%s" % (cnt, len(savaData)))
- return CommFunc.WriteDWORD(cntData, cnt) + savaData
-
- # 从数据库载入数据
- def LoadPyGameData(self, datas, pos, dataslen):
- cnt, pos = CommFunc.ReadDWORD(datas, pos)
- GameWorld.Log("Load DBPlayerPackData count :%s" % cnt)
-
- self.Clear()
-
- for _ in xrange(cnt):
- dbData = PyGameDataStruct.tagDBPlayerPackData()
- pos += dbData.readData(datas, pos, dataslen)
- playerID = dbData.PlayerID
-
- packObj = self.GetPlayerPackObj(playerID, True)
- packObj.dbPlayerPackData = dbData
- packObj.Unpack()
-
- self.Sort()
- return pos
-
-def IsSaveDB(packDataObj):
- ## 是否入库
- if not packDataObj:
- return False
-
- playerID = packDataObj.playerID
-
- if CrossChampionship.IsChampionshipPlayer(playerID):
- return True
-
- #跨服榜单上的默认保留
- if GameWorld.IsCrossServer():
- billboardMgr = PyDataManager.GetCrossBillboardManager()
- for billboardType in ShareDefine.CrossBillboardTypeList:
- groupList = billboardMgr.GetBillboardGroupList(billboardType)
- for billboardType, groupValue1, groupValue2 in groupList:
- billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
- if billboardObj.FindByID(playerID):
- return True
-
- else:
- pass
-# NeedCheckBillBoardType = IpyGameDataPY.GetFuncEvalCfg("PlayerViewCache", 2)
-# #校验玩家是否上排行榜
-# billboardMgr = GameWorld.GetBillboard()
-# for BillBoardType in NeedCheckBillBoardType:
-# curBillboard = billboardMgr.FindBillboard(BillBoardType)
-# if not curBillboard:
-# continue
-# if curBillboard.FindByID(playerID):
-# return True
-
- # 以上是相关功能需要用到的数据,必定不能删除的
-
- maxDays = 7 # 默认7天
- MaxTime = maxDays * 3600 * 24
- curTime = int(time.time())
- passTime = curTime - packDataObj.GetUpdTime()
- if passTime < MaxTime:
- return True
-
- return False
-
-def DelOutofTimePackData():
- ## 删除过期
-
- packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
- for index in range(packDataMgr.GetCount())[::-1]: # 可能删数据,倒序遍历
- packDataObj = packDataMgr.At(index)
- if IsSaveDB(packDataObj):
- continue
- packDataMgr.DelPlayerPackData(packDataObj.playerID)
-
- return
def IsPackDataPlayer(playerID):
return PyDataManager.GetDBPlayerPackDataManager().IsPlayerIn(playerID)
@@ -341,6 +140,7 @@
# pullFrom 0-跨服拉子服; >0-子服通过跨服拉子服
if GameWorld.IsCrossServer():
+ PlayerViewCache.SetNeedViewCache(pullPlayerIDList) # 拉打包数据的时候默认需要缓存数据
# 广播给子服拉数据
msgInfo["pullFrom"] = 0
dataMsg = {"pullPlayerIDList":pullPlayerIDList, "msgInfo":msgInfo}
@@ -371,7 +171,7 @@
if not curPlayer:
GameWorld.DebugLog("玩家不在线的调用打包db数据! playerID=%s" % (playerID), playerID)
data = str(msgInfo)
- GameWorld.GetGameWorld().SendDBLogic(ChConfig.gstDBLogic_PlayerPackData, playerID, data, len(data))
+ GameWorld.GetGameWorld().SendDBLogic(ChConfig.gstDBLogic_PlayerPackDataReq, playerID, data, len(data))
return
GameWorld.DebugLog("玩家在线的发给地图打包数据! playerID=%s" % (playerID), playerID)
# 在线的转发给地图
@@ -442,9 +242,6 @@
## 收到子服同步的玩家打包数据
playerID = msgData["playerID"]
packData = msgData["packData"]
- cacheBase = msgData.get("cacheBase", {})
- if cacheBase:
- PlayerViewCache.UpdCrossCacheBase(playerID, cacheBase)
PyDataManager.GetDBPlayerPackDataManager().UpdPlayerPackData(playerID, packData)
msgInfo = msgData.get("msgInfo", {})
@@ -469,21 +266,23 @@
msgInfo = msgData["msgInfo"]
pullPlayerIDList = msgData["pullPlayerIDList"]
+ dbPackDataIDList = msgData.get("dbPackDataIDList", []) # db标记的有打包数据的玩家ID
otherServerPlayerIDList = []
packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
for playerID in pullPlayerIDList:
- packObj = packDataMgr.GetPlayerPackObj(playerID)
+ packData = packDataMgr.GetPlayerPackdata(playerID)
# 已经有的数据先推送回去
- if packObj:
- GameWorld.DebugLog("跨服有缓存玩家打包数据,直接推给子服! playerID=%s" % playerID)
- dataMsg = {"playerID":playerID, "packData":packObj.GetPackData(), "msgInfo":msgInfo}
+ if packData or playerID in dbPackDataIDList:
+ GameWorld.DebugLog("跨服GameServer或db有缓存玩家打包数据,直接推给子服! playerID=%s" % playerID)
+ dataMsg = {"playerID":playerID, "packData":packData, "msgInfo":msgInfo}
CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PushPlayerPackData, dataMsg, [serverGroupID])
else:
otherServerPlayerIDList.append(playerID)
# 还没有数据的,广播给其他子服拉数据
if otherServerPlayerIDList:
+ PlayerViewCache.SetNeedViewCache(otherServerPlayerIDList) # 拉打包数据的时候默认需要缓存数据
dataMsg = {"pullPlayerIDList":otherServerPlayerIDList, "msgInfo":msgInfo}
CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PullPlayerPackData, dataMsg)
@@ -508,10 +307,10 @@
packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
for playerID in pullPlayerIDList:
- packObj = packDataMgr.GetPlayerPackObj(playerID)
- if packObj:
+ packData = packDataMgr.GetPlayerPackdata(playerID)
+ if packData:
GameWorld.DebugLog("本服有缓存玩家打包数据,直接推给跨服! playerID=%s" % playerID)
- dataMsg = {"playerID":playerID, "packData":packObj.GetPackData(), "msgInfo":msgInfo}
+ dataMsg = {"playerID":playerID, "packData":packData, "msgInfo":msgInfo}
CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PlayerPackData, dataMsg)
else:
DoPullPlayerPackData(playerID, msgInfo)
@@ -541,14 +340,14 @@
if not packDataSyncState or not packData:
return
- # 本服需要,先更新数据
- if packDataSyncState&pow(2, 0):
+ # 本服需要,先更新数据;跨服需要则也默认本服需要
+ if packDataSyncState&pow(2, 0) or packDataSyncState&pow(2, 1):
PyDataManager.GetDBPlayerPackDataManager().UpdPlayerPackData(playerID, packData)
+ GameWorld.GetGameWorld().SendDBLogic(ChConfig.gstDBLogic_PlayerPackDataUpd, playerID, packData, len(packData))
# 跨服需要,同步给跨服,由跨服服务器再进一步处理
if packDataSyncState&pow(2, 1):
- cacheBase = PlayerViewCache.GetSyncCrossCacheBase(curPlayer) if curPlayer else {}
- dataMsg = {"playerID":playerID, "packData":packData, "cacheBase":cacheBase, "msgInfo":msgInfo}
+ dataMsg = {"playerID":playerID, "packData":packData, "msgInfo":msgInfo}
CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PlayerPackData, dataMsg)
# 本服需要的功能
@@ -585,9 +384,9 @@
requestID = msgInfo["requestID"]
mirrorIDList = msgInfo["mirrorIDList"]
for mirrorID in mirrorIDList:
- packObj = packDataMgr.GetPlayerPackObj(mirrorID)
- if packObj:
- packDataDict[mirrorID] = packObj.GetPackData()
+ packData = packDataMgr.GetPlayerPackdata(mirrorID)
+ if packData:
+ packDataDict[mirrorID] = packData
continue
pullPlayerIDList.append(mirrorID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
index ee23ee1..7620a80 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
@@ -37,6 +37,7 @@
import CrossRealmMsg
import ShareDefine
import PyGameData
+import CommFunc
import ChPlayer
import ChConfig
@@ -46,6 +47,146 @@
TempCache = PyGameDataStruct.tagPlayerViewCachePy()
+#玩家缓存管理,该类只做数据缓存存取,不写功能逻辑,防止重读脚本时功能逻辑脚本不生效
+class PlayerViewCachePyManager(object):
+
+ def __init__(self):
+ self.__viewCacheList = [] # [tagPlayerViewCachePy, ...]
+ self.__idIndexDict = {} # {playerID:index, ...}
+ self.__needSort = False
+ self.__serverIDRangePlayerIDDict = {} # {serverIDRangeTuple:[playerID, ...], ....}
+ return
+
+ def GetPlayerViewCache(self, playerID):
+ self.__refreshIDIndex()
+ viewCache = None
+ if playerID in self.__idIndexDict:
+ index = self.__idIndexDict[playerID]
+ if index < len(self.__viewCacheList):
+ viewCache = self.__viewCacheList[index]
+
+ return viewCache
+
+ def AddPlayerViewCache(self, playerID, viewCache):
+ self.__refreshIDIndex()
+ if playerID in self.__idIndexDict:
+ return
+ viewCache.PlayerID = playerID
+ self.__viewCacheList.append(viewCache)
+ self.__idIndexDict[playerID] = len(self.__viewCacheList) - 1
+ self.__needSort = True
+ return
+
+ def GetPlayerIDListByServerIDInfo(self, serverIDList):
+ ## 根据服务器ID列表信息获取对应服务器ID范围的玩家ID战力排序列表
+ if serverIDList == None:
+ return []
+ self.Sort()
+ key = tuple(serverIDList)
+ if key not in self.__serverIDRangePlayerIDDict:
+ playerIDList = []
+ for viewCache in self.__viewCacheList:
+ playerID = viewCache.PlayerID
+ cacheDict = GetCachePropDataDict(viewCache)
+ if not cacheDict:
+ continue
+ serverID = GameWorld.GetAccIDServerID(cacheDict["AccID"])
+ for idInfo in serverIDList:
+ if (isinstance(idInfo, int) and serverID == idInfo) \
+ or ((isinstance(idInfo, tuple) or isinstance(idInfo, list)) \
+ and len(idInfo) == 2 and idInfo[0] <= serverID <= idInfo[1]):
+ playerIDList.append(playerID)
+ GameWorld.DebugLog("重新加载区服玩家查看缓存ID列表: %s, %s, %s" % (key, len(playerIDList), playerIDList))
+ self.__serverIDRangePlayerIDDict[key] = playerIDList
+ return self.__serverIDRangePlayerIDDict[key]
+
+ def IsPlayerIn(self, playerID):
+ self.__refreshIDIndex()
+ return playerID in self.__idIndexDict
+
+ def __refreshIDIndex(self):
+ if not self.__idIndexDict:
+ self.__idIndexDict = {}
+ for index, viewCache in enumerate(self.__viewCacheList):
+ self.__idIndexDict[viewCache.PlayerID] = index
+ return self.__idIndexDict
+
+ def DelPlayerViewCache(self, playerID):
+ self.__refreshIDIndex()
+ index = self.__idIndexDict.pop(playerID, -1)
+ if index >= 0 and index < len(self.__viewCacheList):
+ self.__viewCacheList.pop(index)
+ for playerIDList in self.__serverIDRangePlayerIDDict.values():
+ if playerID in playerIDList:
+ playerIDList.remove(playerID)
+
+ self.__idIndexDict = {}
+ self.__serverIDRangePlayerIDDict = {}
+ return
+
+ def GetCount(self): return len(self.__viewCacheList)
+ def At(self, index):
+ viewCache = self.__viewCacheList[index]
+ if not viewCache and False:
+ viewCache = PyGameDataStruct.tagPlayerViewCachePy() # 不会执行到,只为了.出代码提示
+ return viewCache
+
+ def Sort(self):
+ ## 默认按战力倒序排
+ if not self.__needSort:
+ return
+ self.__needSort = False
+ self.__viewCacheList.sort(cmp=self.__cmp)
+ self.__idIndexDict = {}
+ self.__serverIDRangePlayerIDDict = {}
+ self.__refreshIDIndex()
+ return
+
+ def __cmp(self, a, b):
+ ## 按战力倒序, cmp模式排序效率较低,如果需要再改为key模式
+ aFightPower = 0
+ cacheDict = GetCachePropDataDict(a)
+ if cacheDict:
+ aFightPower = cacheDict.get("FightPower", 0)
+
+ bFightPower = 0
+ cacheDict = GetCachePropDataDict(b)
+ if cacheDict:
+ bFightPower = cacheDict.get("FightPower", 0)
+
+ return cmp(bFightPower, aFightPower)
+
+ # 保存数据 存数据库和realtimebackup
+ def GetSaveData(self):
+ savaData = ""
+ cntData = ""
+ cnt = 0
+
+ for dbData in self.__viewCacheList:
+ #if dbData.PlayerID < 10000:
+ # 假人玩家不存储
+ # continue
+ cnt += 1
+ savaData += dbData.getBuffer()
+
+ GameWorld.Log("Save PlayerViewCachePy count :%s len=%s" % (cnt, len(savaData)))
+ return CommFunc.WriteDWORD(cntData, cnt) + savaData
+
+ # 从数据库载入数据
+ def LoadPyGameData(self, datas, pos, dataslen):
+ cnt, pos = CommFunc.ReadDWORD(datas, pos)
+ GameWorld.Log("Load PlayerViewCachePy count :%s" % cnt)
+
+ for _ in xrange(cnt):
+ dbData = PyGameDataStruct.tagPlayerViewCachePy()
+ dbData.clear()
+ pos += dbData.readData(datas, pos, dataslen)
+
+ self.AddPlayerViewCache(dbData.PlayerID, dbData)
+
+ self.Sort()
+ return pos
+
def DoOnDayEx():
DelOutofTimeViewCacheData()
return
@@ -129,14 +270,12 @@
def DelOutofTimeViewCacheData():
## 删除过期的查看缓存数据
- PlayerPackData.DelOutofTimePackData()
-
pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()
- playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict
- for playerID, viewCache in playerViewCachePyDict.items():
+ for index in range(pyViewCacheMgr.GetCount())[::-1]: # 有删除需倒序遍历
+ viewCache = pyViewCacheMgr.At(index)
if IsSaveDBViewCache(viewCache):
continue
- playerViewCachePyDict.pop(playerID)
+ pyViewCacheMgr.DelPlayerViewCache(viewCache.PlayerID)
PyGameData.g_crossPlayerViewCache = {} # 每日直接清空跨服玩家查看缓存
return
@@ -144,50 +283,56 @@
def DeleteViewCache(playerID):
## 删除玩家缓存
pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()
- playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict
- playerViewCachePyDict.pop(playerID, None)
+ pyViewCacheMgr.DelPlayerViewCache(playerID)
GameWorld.DebugLog("删除查看缓存!", playerID)
return
-def FindViewCache(playerID, isAddNew=False, newPropData={}):
+def FindViewCache(playerID, isAddNew=False, newPropData=None):
## 查找玩家缓存
# @param newPropData: 新数据初始PropData {}, key: LV,RealmLV,Job,VIPLV,Name,FamilyID,FamilyName,FightPower
- curCache = None
pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()
- playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict
- if playerID in playerViewCachePyDict:
- curCache = playerViewCachePyDict[playerID]
+ curCache = pyViewCacheMgr.GetPlayerViewCache(playerID)
+ if curCache:
+ pass
elif isAddNew or playerID < 10000:
# 内网测试假玩家
- if playerID < 10000 and not newPropData:
- openJobList = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1)
- fakeName = "神秘道友".decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
- fakeName = "%s%s" % (fakeName, playerID)
- serverID = playerID % 200 + 1 # 1 ~ 200 服
+ if playerID < 10000:
+ if not newPropData:
+ newPropData = {}
+ fakeName = newPropData.get("Name", "")
+ if not fakeName:
+ fakeName = "神秘道友".decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
+ fakeName = "%s%s" % (fakeName, playerID)
+ accID = newPropData.get("AccID", "")
+ if not accID:
+ serverID = playerID % 100 + 1 # 1 ~ 100 服
+ accID = "fake%s@test@s%s" % (playerID, serverID)
+ else:
+ serverID = GameWorld.GetAccIDServerID(accID)
serverGroupID = serverID
if serverID < 50:
serverGroupID = serverGroupID / 10 + 1 # 前50服每10服1主服
isOnline = True if playerID % 2 == 0 else False
olMgr = ChPlayer.GetOnlinePlayerMgr()
olMgr.SetOnlineState(playerID, isOnline, serverGroupID)
- accID = "fake%s@test@s%s" % (playerID, serverID)
- newPropData = {
- "AccID":accID,
- "PlayerID":playerID,
- "Name":fakeName,
- "Job":random.choice(openJobList) if openJobList else 1,
- "LV":random.randint(100, 200),
- "RealmLV":random.randint(5, 15),
- "FightPower":random.randint(1000000, 100000000),
- "ServerGroupID":serverGroupID,
- }
+
+ job = newPropData.get("Job", 0)
+ if not job:
+ openJobList = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1)
+ job = random.choice(openJobList) if openJobList else 1
+ lv = newPropData.get("LV", random.randint(100, 200))
+ realmLV = newPropData.get("RealmLV", random.randint(5, 15))
+ fightPower = newPropData.get("FightPower", random.randint(1000000, 100000000))
+
+ newPropData.update({"AccID":accID, "PlayerID":playerID, "Name":fakeName, "Job":job, "LV":lv,
+ "RealmLV":realmLV, "FightPower":fightPower, "ServerGroupID":serverGroupID,})
curCache = PyGameDataStruct.tagPlayerViewCachePy()
curCache.PlayerID = playerID
curCache.OffTime = int(time.time())
if newPropData:
curCache.PropData = json.dumps(newPropData, ensure_ascii=False).replace(" ", "")
curCache.PropDataSize = len(curCache.PropData)
- playerViewCachePyDict[playerID] = curCache
+ pyViewCacheMgr.AddPlayerViewCache(playerID, curCache)
return curCache
def GetCachePropDataDict(curCache):
@@ -241,7 +386,7 @@
"RealmLV":curPlayer.GetOfficialRank(),
"Job":curPlayer.GetJob(),
"VIPLV":curPlayer.GetVIPLv(),
- "Name":CrossRealmPlayer.GetCrossPlayerName(curPlayer),
+ "Name":curPlayer.GetName(), # 此处不用跨服名称,如前端需要展示跨服名称,可通过ServerID或AccID取得ServerID展示
"Face":curPlayer.GetFace(),
"FacePic":curPlayer.GetFacePic(),
"FamilyID":curPlayer.GetFamilyID(),
@@ -421,6 +566,19 @@
OnQueryPlayerCache(curPlayer, tagPlayerID, isShort=1)
return
+def SetNeedViewCache(playerIDList):
+ ## 设置需要缓存数据,跨服专用
+ if not GameWorld.IsCrossServer():
+ return
+
+ for playerID in playerIDList:
+ curCache = FindViewCache(playerID)
+ if curCache:
+ continue
+ dataMsg = {"tagPlayerID":playerID}
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PullPlayerViewCache, dataMsg)
+ return
+
def OnQueryPlayerCache(curPlayer, tagPlayerID, equipClassLV=0, isShort=0):
'''查询玩家缓存,支持直接在本服或跨服查询任意服务器玩家
@param tagPlayerID: 目标玩家ID
@@ -564,7 +722,7 @@
GameWorld.DebugLog("子服推送的玩家缓存数据为空! playerID=%s" % playerID, serverGroupID)
else:
curCache = FindViewCache(playerID, True)
- __updCacheBufferToCacheObj(playerID, cacheBuffer, curCache)
+ ReadCacheBufferToCacheObj(playerID, cacheBuffer, curCache)
if not msgInfo:
return
@@ -587,9 +745,10 @@
Sync_PlayerCache(curPlayer, curCache, equipClassLV, isShort)
return
-def __updCacheBufferToCacheObj(playerID, cacheBuffer, cacheObj):
+def ReadCacheBufferToCacheObj(playerID, cacheBuffer, cacheObj=None):
try:
TempCache.clear()
+ setattr(TempCache, "PropDataDict", {})
if TempCache.readData(cacheBuffer) == -1:
GameWorld.ErrLog("玩家缓存数据readData失败! playerID=%s" % playerID)
return
@@ -599,6 +758,9 @@
if TempCache.PlayerID != playerID:
GameWorld.ErrLog("玩家缓存数据readData后玩家ID不一致! playerID=%s != cachePlayerID=%s" % (playerID, TempCache.PlayerID))
return
+
+ if not cacheObj:
+ return TempCache
cacheObj.PropDataDict = {} # 每次更新数据时,重置字典缓存,下次获取时重新eval缓存
cacheObj.PlayerID = TempCache.PlayerID
@@ -618,7 +780,7 @@
setattr(cacheObj, "ItemData%s" % classLV, itemData)
setattr(cacheObj, "ItemDataSize%s" % classLV, itemDataSize)
- return True
+ return cacheObj
def CrossServerMsg_ViewPlayerCacheRet(msgData, tick):
## 收到跨服服务器回复的查看玩家信息
@@ -634,7 +796,7 @@
curCache = PyGameData.g_crossPlayerViewCache[tagPlayerID][0]
else:
curCache = PyGameDataStruct.tagPlayerViewCachePy()
- if __updCacheBufferToCacheObj(tagPlayerID, cacheBuffer, curCache):
+ if ReadCacheBufferToCacheObj(tagPlayerID, cacheBuffer, curCache):
PyGameData.g_crossPlayerViewCache[tagPlayerID] = [curCache, tick] # 更新信息
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
@@ -644,7 +806,7 @@
def CrossServerMsg_PullPlayerViewCache(msgData):
## 收到跨服服务器拉取玩家玩家缓存数据
- msgInfo = msgData["msgInfo"]
+ msgInfo = msgData.get("msgInfo", {})
tagPlayerID = msgData["tagPlayerID"]
DoPullPlayerViewCache(tagPlayerID, msgInfo)
return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py
index 283e6b7..58a23dc 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py
@@ -648,8 +648,9 @@
underList2, aboveList2 = [], [] #大范围
pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()
- playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict
- for playerID, curCache in playerViewCachePyDict.items():
+ for index in range(pyViewCacheMgr.GetCount()):
+ curCache = pyViewCacheMgr.At(index)
+ playerID = curCache.PlayerID
if myPlayerID == playerID:
#不和自己pk
continue
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
index 32db39d..d4581aa 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
@@ -28,6 +28,7 @@
import PlayerAssist
import GameRecData
import PlayerRecData
+import PlayerViewCache
import GameWorldMineArea
import PyGameDataStruct
import PlayerPackData
@@ -134,43 +135,6 @@
self.playerAssistDict[PlayerID] = []
playerAssistList = self.playerAssistDict[PlayerID]
playerAssistList.append(dbData)
-
- return pos
-
-#玩家缓存管理,该类只做数据缓存存取,不写功能逻辑,防止重读脚本时功能逻辑脚本不生效
-class PlayerViewCachePyManager(object):
-
- def __init__(self):
- self.playerViewCachePyDict = {} # 玩家缓存 {playerID:tagPlayerViewCachePy, ...}
- return
-
- # 保存数据 存数据库和realtimebackup
- def GetSaveData(self):
- savaData = ""
- cntData = ""
- cnt = 0
-
- for dbData in self.playerViewCachePyDict.values():
- if dbData.PlayerID < 10000:
- # 假人玩家不存储
- continue
- cnt += 1
- savaData += dbData.getBuffer()
-
- GameWorld.Log("Save PlayerViewCachePy count :%s len=%s" % (cnt, len(savaData)))
- return CommFunc.WriteDWORD(cntData, cnt) + savaData
-
- # 从数据库载入数据
- def LoadPyGameData(self, datas, pos, dataslen):
- cnt, pos = CommFunc.ReadDWORD(datas, pos)
- GameWorld.Log("Load PlayerViewCachePy count :%s" % cnt)
-
- for _ in xrange(cnt):
- dbData = PyGameDataStruct.tagPlayerViewCachePy()
- dbData.clear()
- pos += dbData.readData(datas, pos, dataslen)
-
- self.playerViewCachePyDict[dbData.PlayerID] = dbData
return pos
@@ -317,7 +281,7 @@
class PyGameDataManager(object):
def __init__(self):
- self.DBPlayerPackDataManager = PlayerPackData.DBPlayerPackDataManager()
+ self.DBPlayerPackDataManager = PlayerPackData.DBPlayerPackDataManager() # 该表GameServer只做内存处理,不从db取,也不发db入库,由db自行处理
self.DBGameRecDataManager = GameRecData.DBGameRecDataManager()
self.DBPyFuncTeamManager = PlayerFuncTeam.DBPyFuncTeamManager()
self.DBPyFuncTeamMemManager = PlayerFuncTeam.DBPyFuncTeamMemManager()
@@ -333,7 +297,7 @@
self.CrossBillboardManager = CrossBillboard.CrossBillboardManager()
self.PlayerAssistThanksPyManager = PlayerAssistThanksPyManager()
self.PlayerAssistPyManager = PlayerAssistPyManager()
- self.PlayerViewCachePyManager = PlayerViewCachePyManager()
+ self.PlayerViewCachePyManager = PlayerViewCache.PlayerViewCachePyManager()
self.AuctionAttentionManager = AuctionAttentionManager()
self.AuctionRecordManager = AuctionRecordManager()
self.AuctionItemManager = AuctionItemManager()
@@ -354,7 +318,6 @@
def GetSaveData(self):
buff = ""
- buff += self.DBPlayerPackDataManager.GetSaveData()
buff += self.DBGameRecDataManager.GetSaveData()
buff += self.DBPyFuncTeamManager.GetSaveData()
buff += self.DBPyFuncTeamMemManager.GetSaveData()
@@ -390,7 +353,6 @@
return buff
def LoadGameData(self, gameBuffer, pos):
- pos = self.DBPlayerPackDataManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
pos = self.DBGameRecDataManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
pos = self.DBPyFuncTeamManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
pos = self.DBPyFuncTeamMemManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
index 2cec016..83f8293 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
@@ -37,6 +37,7 @@
import PlayerState
import SkillShell
import CommFunc
+import FBCommon
import PlayerFB
import GameMap
import FBLogic
@@ -115,6 +116,7 @@
self.stateTick = tick
self.stateTickRemain = self.GetStateTickMax()
self.SyncFBStepTime(tick)
+ FBCommon.SetFBStep(state, tick)
return
def CaclStateTick(self, tick):
@@ -574,6 +576,11 @@
if not curPlayer or curPlayer.IsEmpty() or not curPlayer.GetMapLoadOK():
return
+ fbStep = GameWorld.GetGameFB().GetFBStep()
+ if fbStep != ChConfig.Def_MirrorBatState_Init:
+ GameWorld.ErrLog("镜像战斗该阶段已经不能初始化了! fbStep=%s" % fbStep, curPlayer.GetPlayerID())
+ return
+
battle = GetMirrorBattle(curPlayer)
if battle:
GameWorld.DebugLog("镜像战斗玩家断线重连成功!", curPlayer.GetPlayerID())
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py
index b189e3e..e2132aa 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py
@@ -34,11 +34,14 @@
GameWorld.DebugAnswer(curPlayer, "更新镜像: PlayerMirror 5")
GameWorld.DebugAnswer(curPlayer, "加假数据: PlayerMirror a 个数 [起始ID 战力 区服ID 模版key]")
GameWorld.DebugAnswer(curPlayer, "删假数据: PlayerMirror d")
- GameWorld.DebugAnswer(curPlayer, "输出数据: PlayerMirror p [起始索引 个数 ]")
+ #GameWorld.DebugAnswer(curPlayer, "导入数据: PlayerMirror i 模版key账号")
+ #GameWorld.DebugAnswer(curPlayer, "输出数据: PlayerMirror p [起始索引 个数 ]")
GameWorld.DebugAnswer(curPlayer, "多对多阵营分配ID为前后前后即AABB")
GameWorld.DebugAnswer(curPlayer, "后台战斗时ID阵营分配为[AABB]")
GameWorld.DebugAnswer(curPlayer, "切图战斗时ID阵营分配为[自己ABB]")
GameWorld.DebugAnswer(curPlayer, "玩家ID不填时默认自己跟自己打")
+ GameWorld.DebugAnswer(curPlayer, "模版key:在db/TestPackData文件夹下")
+
return
tick = GameWorld.GetGameWorld().GetTick()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetCrossPK.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetCrossPK.py
index feab5e2..92e7667 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetCrossPK.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetCrossPK.py
@@ -35,6 +35,19 @@
__PrintHelp(curPlayer)
return
+ if msgList[0] == "m":
+ gmMatchIDList = msgList[1:]
+ dataMsg = {
+ "requestType":1,
+ "seasonID":GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonID), # 赛季ID
+ "zoneID":GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID), # PK赛区
+ "playerID":curPlayer.GetPlayerID(),
+ "fightPower":PlayerControl.GetFightPower(curPlayer),
+ "gmMatchIDList":gmMatchIDList,
+ }
+ GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PKMatch, dataMsg)
+ return
+
if msgList[0] == "b":
zoneID = msgList[1] if len(msgList) > 1 else 0
seasonID = msgList[2] if len(msgList) > 2 else 0
@@ -139,10 +152,11 @@
GameWorld.DebugAnswer(curPlayer, "设置数据: SetCrossPK 类型 值")
GameWorld.DebugAnswer(curPlayer, "类型:0-积分,2-段位,3-PK次数,4-胜利次数,5-连胜次数,6-连败次数")
GameWorld.DebugAnswer(curPlayer, "7-今日PK次数,8-今日胜利次数,9-今日购买次数,10-今日刷新次数")
- GameWorld.DebugAnswer(curPlayer, "设置历史记录: SetCrossPK 赛季ID 类型 数值")
+ GameWorld.DebugAnswer(curPlayer, "设置历史: SetCrossPK 赛季ID 类型 数值")
GameWorld.DebugAnswer(curPlayer, "类型:0-段位,1-名次,2-积分,3-奖励等级")
GameWorld.DebugAnswer(curPlayer, "当前连败次数: %s" % curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CrossPK_CLoseCount))
GameWorld.DebugAnswer(curPlayer, "设置上榜: SetCrossPK b 分区 赛季 段位 [积分 连胜]")
+ GameWorld.DebugAnswer(curPlayer, "指定匹配: SetCrossPK m [playerID ...]")
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MirrorBattle.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MirrorBattle.py
index 6673827..14f30c4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MirrorBattle.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MirrorBattle.py
@@ -21,6 +21,7 @@
import PlayerControl
import IpyGameDataPY
import PlayerCrossRealmPK
+import GameWorldProcess
import CrossRealmPlayer
import PlayerArena
import GameWorld
@@ -45,6 +46,20 @@
MirrorAttack.DoPlayerLeaveFB(curPlayer, tick)
return
+## 副本定时器
+def OnProcess(tick):
+ fbStep = GameWorld.GetGameFB().GetFBStep()
+
+ # 等待镜像初始化阶段
+ if fbStep == ChConfig.Def_MirrorBatState_Init:
+ if tick - GameWorld.GetGameFB().GetFBStepTick() < 20 * 1000:
+ return
+ FBCommon.SetFBStep(ChConfig.Def_MirrorBatState_Over, tick)
+ GameWorld.ErrLog("没有等到镜像创建,直接关闭副本!")
+ GameWorldProcess.CloseFB(tick)
+
+ return
+
def CheckPlayersRelation_IsFriend(curPlayer, curTagPlayer):
return not CanAttackPlayer(curPlayer, curTagPlayer)
diff --git a/ServerPython/db/PyMongoDataServer/GM/Commands/PlayerMirror.py b/ServerPython/db/PyMongoDataServer/GM/Commands/PlayerMirror.py
new file mode 100644
index 0000000..9769ce3
--- /dev/null
+++ b/ServerPython/db/PyMongoDataServer/GM/Commands/PlayerMirror.py
@@ -0,0 +1,108 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package PyMongoDataServer.GM.Commands.PlayerMirror
+#
+# @todo:玩家镜像数据
+# @author hxp
+# @date 2025-03-04
+# @version 1.0
+#
+# 详细描述: 玩家镜像数据
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-03-04 16:30"""
+#-------------------------------------------------------------------------------
+
+from Common import mylog
+import DBCommon.CommonDefine as CommonDefine
+from Collections import DataServerPlayerData
+from LogicProcess import CtrlDBManager
+from DBCommon import GlobalFunctions
+import PyGameData
+import base64
+import os
+
+def OnDBExec(gmList, dbAnswerList):
+ ## db收到GameServer同步的命令处理
+ #mylog.debug("db打包数据: %s" % gmList)
+ dbAnswerList.append("db收到GM命令测试回复")
+ return
+
+def OnCrossDBExec(gmList, dbAnswerList):
+ ## 跨服db收到子服同步的命令处理
+ if not gmList:
+ return
+ value = gmList[0]
+ if value == "a":
+ __addFackPackData(gmList[1:], dbAnswerList)
+ elif value == "d":
+ __delFackPackData(dbAnswerList)
+ return
+
+def __addFackPackData(gmList, dbAnswerList):
+ ## 添加假的打包数据,一般用于开发测试功能用
+
+ addCount = gmList[0] if len(gmList) > 0 else 1
+ startID = gmList[1] if len(gmList) > 1 else 1
+ #fightPower = gmList[2] if len(gmList) > 2 else 0
+ serverID = gmList[3] if len(gmList) > 3 else 0
+ packDataTempKey = gmList[4] if len(gmList) > 4 else ""
+
+ appPath = GlobalFunctions.getAppPath()
+ fullPath = os.path.join(appPath, "TestPackData", packDataTempKey, "PackData.json")
+ if not os.path.isfile(fullPath):
+ dbAnswerList.append("跨服db/TestPackData不存在该模版文件夹:%s" % packDataTempKey)
+ return
+ mylog.debug("打包数据模板文件:%s" % fullPath)
+
+ fileObj = open(fullPath, 'rb')
+ content = fileObj.read()
+ fileObj.close()
+ packDataDict = eval(content)
+ packData = packDataDict.get("PackData", "")
+ if not packData:
+ dbAnswerList.append("跨服db/TestPackData/%s没有打包数据" % (packDataTempKey))
+ return
+
+ packDataTeamBuff = base64.b64decode(packData)
+ tempDBPlayer = DataServerPlayerData.tagDBPlayer()
+ tempDBPlayer.readData(packDataTeamBuff)
+ otherDataBuff = packDataTeamBuff[tempDBPlayer.getLength():]
+
+ userCtrlDB = CtrlDBManager.getCtrlMgr().getCtrlDBByName('UserCtrlDB')
+
+ FakeName = "FakeName"
+ addOKCount = 0
+ for index in range(addCount):
+ playerID = fackID = startID + index
+
+ tempDBPlayer.PlayerID = fackID
+ tempDBPlayer.PlayerName = "%s%s" % (FakeName, fackID)
+ curServerID = serverID if serverID else (playerID % 100 + 1) # 1 ~ 100 服
+ tempDBPlayer.AccID = "fack%s@test@s%s" % (fackID, curServerID)
+
+ updBuff = tempDBPlayer.getBuffer() + otherDataBuff
+ updPackData = base64.b64encode(updBuff)
+
+ #mylog.debug("updPackData:%s" % updPackData)
+ userCtrlDB.updPlayerPackData(playerID, updPackData)
+ addOKCount += 1
+
+ mylog.debug("添加假玩家打包数据数:%s" % addOKCount)
+ dbAnswerList.append("跨服db添加假玩家打包数据数:%s,总:%s" % (addOKCount, len(PyGameData.g_packDataDict)))
+ return
+
+def __delFackPackData(dbAnswerList):
+ delCount = 0
+ for playerID in PyGameData.g_packDataDict.keys():
+ if playerID > 10000:
+ continue
+ del PyGameData.g_packDataDict[playerID]
+ delCount += 1
+ mylog.debug("删除假打包数据: delCount:%s" % delCount)
+ dbAnswerList.append("跨服db删除假玩家打包数据数:%s,剩:%s" % (delCount, len(PyGameData.g_packDataDict)))
+ return
+
+
diff --git a/ServerPython/db/PyMongoDataServer/GM/Commands/__init__.py b/ServerPython/db/PyMongoDataServer/GM/Commands/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ServerPython/db/PyMongoDataServer/GM/Commands/__init__.py
diff --git a/ServerPython/db/PyMongoDataServer/GM/GMShell.py b/ServerPython/db/PyMongoDataServer/GM/GMShell.py
new file mode 100644
index 0000000..2a90c9b
--- /dev/null
+++ b/ServerPython/db/PyMongoDataServer/GM/GMShell.py
@@ -0,0 +1,112 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package PyMongoDataServer.GM.GMShell
+#
+# @todo:db执行GM命令
+# @author hxp
+# @date 2025-03-04
+# @version 1.0
+#
+# 详细描述: db执行GM命令
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-03-04 16:30"""
+#-------------------------------------------------------------------------------
+
+
+from DBCommon import GlobalFunctions
+from Common import mylog
+import Commands
+import os
+
+## 导入GM全部命令
+# @param importDir 路径名
+# @return None
+# @remarks 函数详细说明.
+def ImportCommandAll(importDir):
+ curPath = GlobalFunctions.getAppPath()
+ for root, dirs, files in os.walk("%s\\%s"%(curPath, importDir)):
+ for file in files:
+ fileName = os.path.join(root, file)
+ fileName = fileName.replace(curPath, "")
+ fileName = fileName[1:len(fileName)]
+ if fileName.find("__init__") >= 0:
+ continue
+
+ curFileList = fileName.split(".")
+ fileName = curFileList[0]
+ ext = curFileList[1]
+ if ext not in ['pyc', 'py']:
+ continue
+
+ fileName = fileName.replace("\\",".")
+ __import__(fileName)
+
+ImportCommandAll("GM\\Commands")
+
+## 函数调用
+# @param curCallObj 实例(可能是某个文件名)
+# @param callName 实例的某个属性
+# @return 属性
+def ParseNameGetObj(curCallObj, callName):
+ callList = callName.split(".")
+ if len(callList) <= 1:
+ return None
+
+ for curCallName in callList:
+ if hasattr(curCallObj, curCallName) != True:
+ #无此属性
+ return None
+
+ curCallObj = getattr(curCallObj, curCallName)
+
+ return curCallObj
+
+## 外部调用的获取属性,且是可以call的
+# @param curCallObj 实例(可能是某个文件名)
+# @param callName 实例的某个属性
+# @return 可以call的属性
+# @remarks 函数详细说明.
+def GetExecFunc(curCallObj, callName):
+ curCallObj = ParseNameGetObj(curCallObj, callName)
+
+ if curCallObj == None:
+ return None
+
+ if callable(curCallObj) != True:
+ #不可调用
+ return None
+
+ return curCallObj
+
+def ClientGMCommand(msgData):
+ mylog.debug('跨服DB收到子服GM命令: %s' % msgData)
+ cmdMsgList = msgData.get("cmdMsgList", [])
+ if not cmdMsgList:
+ return []
+ dbAnswerList = []
+ cmdName = cmdMsgList[0]
+ callName = "%s.%s"%(cmdName, "OnCrossDBExec")
+ callFunc = GetExecFunc(Commands, callName)
+ if callFunc != None:
+ callFunc(cmdMsgList[1:], dbAnswerList)
+ return dbAnswerList
+
+def DBGMCommand(cmdMsg):
+ mylog.debug('DB收到GameServer的GM命令: %s' % cmdMsg)
+ if not cmdMsg:
+ return []
+ dbAnswerList = []
+ try:
+ cmdMsgList = eval(cmdMsg)
+ cmdName = cmdMsgList[0]
+ callName = "%s.%s"%(cmdName, "OnDBExec")
+ callFunc = GetExecFunc(Commands, callName)
+ if callFunc != None:
+ callFunc(cmdMsgList[1:], dbAnswerList)
+ except:
+ pass
+ return dbAnswerList
+
diff --git a/ServerPython/db/PyMongoDataServer/GM/__init__.py b/ServerPython/db/PyMongoDataServer/GM/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ServerPython/db/PyMongoDataServer/GM/__init__.py
diff --git a/ServerPython/db/PyMongoDataServer/__init__.py b/ServerPython/db/PyMongoDataServer/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ServerPython/db/PyMongoDataServer/__init__.py
--
Gitblit v1.8.0