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