| | |
| | | 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:
|
| | |
| | | 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
|
| | |
| | | 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
|