From 4e6d5af98a0e0810ddfe2cc0faaec2832f865bd6 Mon Sep 17 00:00:00 2001
From: hch <305670599@qq.com>
Date: 星期二, 20 五月 2025 15:23:30 +0800
Subject: [PATCH] 15 卡牌服务端搭建 - 地图增加FindStr接口;玩家下线保存,python增加MapCallDB调用DB逻辑
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py | 15 +++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IPY_GameWorld1.py | 1
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py | 16 ++--
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/LogicProcess/UserCtrlDB.py | 186 ++++++++++++++-------------------------------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/RecvPackToMapDB.py | 12 +++
5 files changed, 94 insertions(+), 136 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IPY_GameWorld1.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IPY_GameWorld1.py
index 962b03e..f6ad5d3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IPY_GameWorld1.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IPY_GameWorld1.py
@@ -439,6 +439,7 @@
def GetActiveEventCount(self): return _IPY_GameWorld1.IPY_GameWorld_GetActiveEventCount(self)
def GetActiveEventByIndex(self, *args): return _IPY_GameWorld1.IPY_GameWorld_GetActiveEventByIndex(self, *args)
def DataServer_Rec(self, *args): return _IPY_GameWorld1.IPY_GameWorld_DataServer_Rec(self, *args)
+ def FindStr(self, *args): return _IPY_GameWorld1.IPY_GameWorld_FindStr(self, *args)
def SetTickTypeCount(self, *args): return _IPY_GameWorld1.IPY_GameWorld_SetTickTypeCount(self, *args)
def GetTickByType(self, *args): return _IPY_GameWorld1.IPY_GameWorld_GetTickByType(self, *args)
def SetTickByType(self, *args): return _IPY_GameWorld1.IPY_GameWorld_SetTickByType(self, *args)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index 5eb0616..09f53f7 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -175,11 +175,15 @@
import PlayerMail
import DBDataMgr
import GameServerRefresh
+import IPY_ServerDefine
+import CommFunc
+from PyMongoDB import RecvPackToMapDB
import datetime
import time
import math
import re
+import base64
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -3113,10 +3117,19 @@
except:
import traceback
GameWorld.RaiseException("玩家下线逻辑错误\r\n%s" % traceback.format_exc())
-
+ RecvPackToMapDB.MapCallDB(GetPackSaveData(curPlayer))
#调用底层使玩家下线
curPlayer.DoDisconnect(tick)
+# 简化c++的保存数据封包
+def GetPackSaveData(curPlayer):
+ roleSaveData = base64.b64decode(curPlayer.GetPackData()) # base64加密了
+ allData = ""
+ allData = CommFunc.WriteBYTE(allData, IPY_ServerDefine.gstUpdate)
+ allData = CommFunc.WriteString(allData, len(roleSaveData), roleSaveData)
+ return allData
+
+
##玩家正常下线
#@param curPlayer 玩家索引
#@param tick 时间戳
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py
index 94eeee2..98b53fa 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py
@@ -340,15 +340,15 @@
# @return None
# @remarks 函数详细说明.
def GameServer_PlayerSave(index, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- #2009-07-04 因地图服务器有可能关闭重开,这里要判定空
- if not curPlayer:
- return
+ # curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ # #2009-07-04 因地图服务器有可能关闭重开,这里要判定空
+ # if not curPlayer:
+ # return
- # 1为保存 0为正常下线
- curPlayer.SetCountryLastWeekHornor(1) # 利用此字段通知为保存数据,非下线数据
- curPlayer.PushSaveData()
- curPlayer.SetCountryLastWeekHornor(0) # 利用此字段通知为保存数据,非下线数据
+ # # 1为保存 0为正常下线
+ # curPlayer.SetCountryLastWeekHornor(1) # 利用此字段通知为保存数据,非下线数据
+ # curPlayer.PushSaveData()
+ # curPlayer.SetCountryLastWeekHornor(0) # 利用此字段通知为保存数据,非下线数据
return
#===============================================================================
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/LogicProcess/UserCtrlDB.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/LogicProcess/UserCtrlDB.py
index 7ea3eda..6459dcf 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/LogicProcess/UserCtrlDB.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/LogicProcess/UserCtrlDB.py
@@ -556,19 +556,13 @@
oFuncGrade.End()
return True
if requestType == CommonDefine.gstUpdate:
- if DBConfig.IsOpenDbSaveServer:
- msg = error.formatMsg('DeployError', error.ERROR_NO_56, "DbSaveServer is open, type = %d request should be send to PyMongoDBSaveServer"%CommonDefine.gstUpdate)
- mylog.DeployError(msg, True)
- return False
-
oFuncGrade = self.GetFuncGrade("gstUpdate")
oFuncGrade.Start()
if self.IsMergeServer():
- if not self.onSaveMapServerPlayerDataMergeServer(db, pack):
- mylog.error("onSaveMapServerPlayerDataMergeServer failed!sessionID = 0x%X", pack.getPackHead().sessionID)
+ self.onSaveMapServerPlayerDataMergeServer(db, pack)
else:
- if not self.onSaveMapServerPlayerData(db, pack):
- mylog.error("onSaveMapServerPlayerData failed!sessionID = 0x%X", pack.getPackHead().sessionID)
+ self.onSaveMapServerPlayerData(db, pack)
+
oFuncGrade.End()
return True
if requestType == CommonDefine.gstSavePlayerInfo:
@@ -1506,124 +1500,62 @@
g_mergeRegisterPlayerDict = PyGameData.g_mergeRegisterPlayerDict
'''玩家下线,跨服服务器下线不保存'''
pos = 1 #跳过gstUpdate
- buf = pack.getBuffer()
- length = pack.getLength()
- type, pos = CommFunc.ReadBYTE(buf, pos)
- if type == CommonDefine.gstPlayerDetail:
- needReturn, pos = CommFunc.ReadBYTE(buf, pos)
- packCrcPos = pos
- packCrc, pos = CommFunc.ReadDWORD(buf, pos)
- serverTypePos = pos
- serverType, pos = CommFunc.ReadBYTE(buf, pos)
- if serverType == MMORPGPack.stMin:
- #其他服务器未发现异常,检查CRC
- saveData, pos = CommFunc.ReadString(buf, pos, length - pos)
- calcCrc = CommFunc.ToDWORD(crc32(saveData))
- if not packCrc == calcCrc:
- #CRC校验错误
- serverTypeData = chr(MMORPGPack.stData)
- buf = buf[:serverTypePos] + serverTypeData+ buf[(serverTypePos + 1):]
- self.onSavePlayerDataCRCError(db, pack, buf[packCrcPos:])
- return (False, 0)
- else:
- pass #正常情况
- else:
- self.onSavePlayerDataCRCError(db, pack, buf[packCrcPos:])
- return (False,0)
+ saveData, pos = CommFunc.ReadString(pack.getBuffer(), pos, pack.getLength() - pos)
+
+
+ # 与策划约定 离线超过3分钟则必须从子服再次登录汇报新数据
+ # 为了避免 g_mergeRegisterPlayerDict 占用过多内存,每10分钟清除一次已下线数据
+ result, playerID, accID = self.__ReadPlayerID(db, saveData)
+
+ # 保存跨服数据主要是为了避免短时间断线重连玩家数据不对应,如坐标又回到了起点
+ if accID in g_mergeRegisterPlayerDict:
+ g_mergeRegisterPlayerDict[accID][MergeRegPInfoIndex_LogoutTime] = time()
+ g_mergeRegisterPlayerDict[accID][MergeRegPInfoIndex_PackData].Data = saveData
+ g_mergeRegisterPlayerDict[accID][MergeRegPInfoIndex_PackData].DataLen = len(saveData)
- # 与策划约定 离线超过3分钟则必须从子服再次登录汇报新数据
- # 为了避免 g_mergeRegisterPlayerDict 占用过多内存,每10分钟清除一次已下线数据
- result, playerID, accID = self.__ReadPlayerID(db, saveData)
-
- # 保存跨服数据主要是为了避免短时间断线重连玩家数据不对应,如坐标又回到了起点
- if accID in g_mergeRegisterPlayerDict:
- g_mergeRegisterPlayerDict[accID][MergeRegPInfoIndex_LogoutTime] = time()
- g_mergeRegisterPlayerDict[accID][MergeRegPInfoIndex_PackData].Data = saveData
- g_mergeRegisterPlayerDict[accID][MergeRegPInfoIndex_PackData].DataLen = len(saveData)
-
- mylog.info("onSaveMapServerPlayerDataMergeServer result = %s, playerID = %s, sessionID = 0x%X"
- % (result, playerID, pack.getPackHead().sessionID))
- #回报
- if needReturn:
- updateReturn = SendPackProtocol.tagDBUpdateReturn()
- updateReturn.CallType = CommonDefine.dgUpDate
- updateReturn.UpdateType = CommonDefine.gstPlayerDetail
- updateReturn.Result = result
- updateReturn.PlayerID = playerID
- self.sendString(pack, updateReturn.GetBuffer())
- return (result, playerID)
+ mylog.info("onSaveMapServerPlayerDataMergeServer result = %s, playerID = %s" % (result, playerID))
+
+ return (result, playerID)
def onSaveMapServerPlayerData(self, db, pack):
'''玩家下线,保存玩家在MapServer的数据'''
pos = 1 #跳过gstUpdate
- buf = pack.getBuffer()
- length = pack.getLength()
- type, pos = CommFunc.ReadBYTE(buf, pos)
- if type == CommonDefine.gstPlayerDetail:
- needReturn, pos = CommFunc.ReadBYTE(buf, pos)
- packCrcPos = pos
- packCrc, pos = CommFunc.ReadDWORD(buf, pos)
- serverTypePos = pos
- serverType, pos = CommFunc.ReadBYTE(buf, pos)
- if serverType == MMORPGPack.stMin:
- #其他服务器未发现异常,检查CRC
- saveData, pos = CommFunc.ReadString(buf, pos, length - pos)
- calcCrc = CommFunc.ToDWORD(crc32(saveData))
- if not packCrc == calcCrc:
- #CRC校验错误
- serverTypeData = chr(MMORPGPack.stData)
- buf = buf[:serverTypePos] + serverTypeData+ buf[(serverTypePos + 1):]
- self.onSavePlayerDataCRCError(db, pack, buf[packCrcPos:])
- return (False, 0)
- else:
- pass #正常情况
- else:
- self.onSavePlayerDataCRCError(db, pack, buf[packCrcPos:])
- return (False,0)
- #正常情况
- #保存数据
- result = False
- playerID = 0
- if DBConfig.PackSave:
- result, playerID, accID = self.SavePlayerMapServerDataEx(db, saveData)
- else:
- result, playerID, accID = self.SavePlayerMapServerData(db, saveData)
- if not result:
- #保存失败
- sessionID = pack.getPackHead().sessionID
- msg = error.formatMsg('error', error.ERROR_NO_59, 'Player save data failed!sessionID = %s'%sessionID)
- mylog.error(msg)
-
- DataDumper.DumpData(GlobalFunctions.getAppPath(), 'UserLogs\\SaveFailDump', '%s.mdat'%sessionID, buf[pos:])
-# self.sendString(pack, updateReturn.GetBuffer())
-# return
- #回报
- if needReturn:
- updateReturn = SendPackProtocol.tagDBUpdateReturn()
- updateReturn.CallType = CommonDefine.dgUpDate
- updateReturn.UpdateType = CommonDefine.gstPlayerDetail
- updateReturn.Result = result
- updateReturn.PlayerID = playerID
- self.sendString(pack, updateReturn.GetBuffer())
-
- # 玩家下线恢复充值兑换中的订单,IsProcee为1,但endtime为空的情况
- self.RevoverBillProcess(db, accID)
- mylog.info("onSaveMapServerPlayerData result = %s, playerID = %s, sessionID = 0x%X"%(result, playerID, pack.getPackHead().sessionID))
+ saveData, pos = CommFunc.ReadString(pack.getBuffer(), pos, pack.getLength() - pos)
+
+ #正常情况
+ #保存数据
+ result = False
+ playerID = 0
+ if DBConfig.PackSave:
+ result, playerID, accID = self.SavePlayerMapServerDataEx(db, saveData)
+ else:
+ result, playerID, accID = self.SavePlayerMapServerData(db, saveData)
+ if not result:
+ #保存失败
+ msg = error.formatMsg('error', error.ERROR_NO_59, 'Player save data failed!playerID = %s'%playerID)
+ mylog.error(msg)
- # 下线成功入库后同步移动玩家备档备份文件夹
- PlayerBakDir = os.path.join(DBConfig.PlayerBakRoot, str(playerID))
- if os.path.exists(PlayerBakDir):
- BakCopyDir = os.path.join(PlayerBakDir, "Backup")
- for filename in os.listdir(PlayerBakDir):
- if not filename.endswith(DBConfig.PlayerBakFileType):
- continue
- fullPath = os.path.join(PlayerBakDir, filename)
- if not os.path.exists(os.path.join(BakCopyDir, filename)):
- shutil.move(fullPath, BakCopyDir)
- else:
- os.remove(fullPath)
-
- return (result, playerID)
+ DataDumper.DumpData(GlobalFunctions.getAppPath(), 'UserLogs\\SaveFailDump', '%s.mdat'%playerID, saveData)
+
+
+ # 玩家下线恢复充值兑换中的订单,IsProcee为1,但endtime为空的情况
+ self.RevoverBillProcess(db, accID)
+ mylog.info("onSaveMapServerPlayerData result = %s, playerID = %s"%(result, playerID))
+
+ # 下线成功入库后同步移动玩家备档备份文件夹
+ PlayerBakDir = os.path.join(DBConfig.PlayerBakRoot, str(playerID))
+ if os.path.exists(PlayerBakDir):
+ BakCopyDir = os.path.join(PlayerBakDir, "Backup")
+ for filename in os.listdir(PlayerBakDir):
+ if not filename.endswith(DBConfig.PlayerBakFileType):
+ continue
+ fullPath = os.path.join(PlayerBakDir, filename)
+ if not os.path.exists(os.path.join(BakCopyDir, filename)):
+ shutil.move(fullPath, BakCopyDir)
+ else:
+ os.remove(fullPath)
+
+ return (result, playerID)
def __PlayerBackupSave(self):
db = self.db
@@ -2187,12 +2119,12 @@
if self.updatePlayerAccState(db, playerRec.PlayerID, CommonDefine.pysForbidden):
#封号成功,记录封号日志
self.sendAccForbiddenLogReq(playerRec.AccID, 1)
- #回报保存失败
- updateReturn = SendPackProtocol.tagDBUpdateReturn()
- updateReturn.CallType = CommonDefine.dgUpDate
- updateReturn.UpdateType = CommonDefine.gstPlayerDetail
- updateReturn.Result = 0
- self.sendString(pack, updateReturn.GetBuffer())
+ # #回报保存失败
+ # updateReturn = SendPackProtocol.tagDBUpdateReturn()
+ # updateReturn.CallType = CommonDefine.dgUpDate
+ # updateReturn.UpdateType = CommonDefine.gstPlayerDetail
+ # updateReturn.Result = 0
+ # self.sendString(pack, updateReturn.GetBuffer())
def sendAccForbiddenLogReq(self, accid, isForbidden):
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/RecvPackToMapDB.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/RecvPackToMapDB.py
index 5e831b5..5748da7 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/RecvPackToMapDB.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/RecvPackToMapDB.py
@@ -12,6 +12,7 @@
import PyGameData
import GameWorld
+# C++调用 用封包格式 通知map处理DB数据
def RecvPackToMapDB(packBuff):
pack = MMORPGPack.MMORPGPacket()
pack.readData(packBuff)
@@ -25,4 +26,15 @@
return False
#GameWorld.Log("RecvPackToMapDB packlen %s"%len(packBuff))
+ PyGameData.g_usrCtrlDB.requestLogicProcess(pack)
+
+
+# 地图自己调用处理DB数据,不一定要符合封包格式,PY根据功能自定义组成封包
+def MapCallDB(packBuff, isBuffer = True):
+ pack = MMORPGPack.MMORPGPacket()
+ if isBuffer:
+ pack.setBuffer(packBuff) # 只设置数据
+ else:
+ pack.readData(packBuff) # 设置封包头 和 数据
+
PyGameData.g_usrCtrlDB.requestLogicProcess(pack)
\ No newline at end of file
--
Gitblit v1.8.0