15 卡牌服务端搭建 - 地图增加FindStr接口;玩家下线保存,python增加MapCallDB调用DB逻辑
5个文件已修改
150 ■■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IPY_GameWorld1.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/LogicProcess/UserCtrlDB.py 106 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/RecvPackToMapDB.py 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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)
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 时间戳
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
#===============================================================================
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,30 +1500,8 @@
        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分钟清除一次已下线数据
@@ -1541,45 +1513,15 @@
                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())
            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)
        saveData, pos = CommFunc.ReadString(pack.getBuffer(), pos, pack.getLength() - pos)
            #正常情况
            #保存数据
            result = False
@@ -1590,25 +1532,15 @@
                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)
            msg = error.formatMsg('error', error.ERROR_NO_59, 'Player save data failed!playerID = %s'%playerID)
                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())
            DataDumper.DumpData(GlobalFunctions.getAppPath(), 'UserLogs\\SaveFailDump', '%s.mdat'%playerID, saveData)
                
            # 玩家下线恢复充值兑换中的订单,IsProcee为1,但endtime为空的情况
            self.RevoverBillProcess(db, accID)
            mylog.info("onSaveMapServerPlayerData result = %s, playerID = %s, sessionID = 0x%X"%(result, playerID, pack.getPackHead().sessionID))
        mylog.info("onSaveMapServerPlayerData result = %s, playerID = %s"%(result, playerID))
            
            # 下线成功入库后同步移动玩家备档备份文件夹
            PlayerBakDir = os.path.join(DBConfig.PlayerBakRoot, str(playerID))
@@ -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
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)
@@ -26,3 +27,14 @@
    #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)