9651 【后端】玩家个人数据保存问题(地图玩家支持按每个玩家独立备档)
4个文件已修改
1个文件已添加
99 ■■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IPY_GameObj.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBackup.py 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ReadChConfig.py 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -3409,6 +3409,7 @@
# 玩家字典key定义规则, key的长度不能超过29个字节, 注意尽量避免命名重复
# 新增参数TYPE 用于字典分类,默认0
Def_PDict_BackupTime = "BackupTime" # 最近一次数据备档时间
Def_QuDao_DoubleBillGold = "qddbGold"   # 渠道返利的仙玉
Def_QuDao_DoubleBillCount = "qddbCount"   # 渠道返利的仙玉领取次数 日期+次数组合数字
Def_PDict_GeTuiSet = "GetuiSet"     # 推送提醒的设置
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IPY_GameObj.py
@@ -1668,6 +1668,7 @@
    def SetClientMoveTick(self, *args): return _IPY_GameObj.IPY_Player_SetClientMoveTick(self, *args)
    def Sync_ClientTick(self): return _IPY_GameObj.IPY_Player_Sync_ClientTick(self)
    def PushSaveData(self): return _IPY_GameObj.IPY_Player_PushSaveData(self)
    def RealTimeBackupSinglePlayerLogic(self, *args): return _IPY_GameObj.IPY_Player_RealTimeBackupSinglePlayerLogic(self, *args)
    def Sync_FbSystemMessage(self, *args): return _IPY_GameObj.IPY_Player_Sync_FbSystemMessage(self, *args)
    def Sync_ShowFbBillboard(self): return _IPY_GameObj.IPY_Player_Sync_ShowFbBillboard(self)
    def Interface_SaveCard(self, *args): return _IPY_GameObj.IPY_Player_Interface_SaveCard(self, *args)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBackup.py
New file
@@ -0,0 +1,86 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.PlayerBackup
#
# @todo:玩家备档
# @author hxp
# @date 2022-12-06
# @version 1.0
#
# 详细描述: 玩家备档
#
#-------------------------------------------------------------------------------
#"""Version = 2022-12-06 18:30"""
#-------------------------------------------------------------------------------
import ChConfig
import PlayerControl
import ReadChConfig
import GameWorld
import shutil
import time
import os
def CheckPlayerBackup(curPlayer):
    PlayerBakRoot = ReadChConfig.GetPyMongoConfig("Backup", "PlayerBakRoot", isLog=False)
    if not PlayerBakRoot:
        #GameWorld.DebugLog("未启用备档")
        return
    curTime = int(time.time())
    backupTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BackupTime)
    if not backupTime:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BackupTime, curTime)
        return
    playerID = curPlayer.GetPlayerID()
    BackupCDTimes = GameWorld.ToIntDef(ReadChConfig.GetPyMongoConfig("Backup", "BackupMinutes"))
    if not BackupCDTimes or curTime - backupTime < BackupCDTimes * 60:
        #GameWorld.DebugLog("备档cd中, BackupCDTimes=%s,pass=%s" % (BackupCDTimes, curTime - backupTime), playerID)
        return
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BackupTime, curTime)
    PlayerBakDir = os.path.join(PlayerBakRoot, str(playerID))
    BakCopyDir = os.path.join(PlayerBakDir, "Backup")
    if not os.path.exists(PlayerBakDir):
        os.makedirs(PlayerBakDir)
        os.makedirs(BakCopyDir)
    fileType = ReadChConfig.GetPyMongoConfig("Backup", "PlayerBakFileType", defaultValue=".pdbak")
    moveList, copyList = [], []
    for parent, _, filenames in os.walk(PlayerBakDir):
        for filename in filenames:
            if not filename.endswith(fileType):
                continue
            fullPath = os.path.join(parent, filename)
            if parent == BakCopyDir:
                bakTime = GameWorld.ToIntDef(filename[:filename.index(".")].split("_")[1])
                copyList.append([bakTime, fullPath])
            else:
                if not os.path.exists(os.path.join(BakCopyDir, filename)):
                    moveList.append(fullPath)
                else:
                    os.remove(fullPath)
    for filePath in moveList:
        shutil.move(filePath, BakCopyDir)
    copyList.sort()
    BackupCopyMax = GameWorld.ToIntDef(ReadChConfig.GetPyMongoConfig("Backup", "BackupCopy")) # 保留旧备档份数
    delCopyCount = len(copyList) + len(moveList) - BackupCopyMax
    for _, copyFilePath in copyList:
        if delCopyCount > 0:
            delCopyCount -= 1
            os.remove(copyFilePath)
        else:
            break
    # 玩家备档文件格式:  玩家ID_备档时间戳.pb
    pdBakPath = os.path.join(PlayerBakDir, "%s_%s%s" % (playerID, curTime, fileType))
    curPlayer.RealTimeBackupSinglePlayerLogic(pdBakPath)
    GameWorld.DebugLog("DoPlayerBackup: %s" % pdBakPath, playerID)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -58,6 +58,7 @@
import ChEquip
import PlayerYinji
import PlayerActivity
import PlayerBackup
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -1161,6 +1162,9 @@
        #GameWorld.Log("玩家还未初始化成功, 不处理")
        return
    
    #定时备档
    PlayerBackup.CheckPlayerBackup(curPlayer)
    #被GM封状态响应
    ProcessGMOperLogic(curPlayer, tick)
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ReadChConfig.py
@@ -216,7 +216,7 @@
#  @param option: 配置项名
#  @return
#  @remarks \db\PyMongoDataServer\PyMongoDataServer.ini配置读取
def GetPyMongoConfig(section, option, raw=False):
def GetPyMongoConfig(section, option, raw=False, defaultValue=None, isLog=True):
    global PyMongoDataServerConfig
    
    if not PyMongoDataServerConfig:
@@ -231,7 +231,10 @@
        GameWorld.DebugLog("Reload dbAPPath=%s" % str(dbAPPath))
    
    if not PyMongoDataServerConfig.has_option(section, option):
        GameWorld.ErrLog("PyMongoDataServer.ini找不到配置: section=%s,option=%s" % (section, option))
        if defaultValue != None:
            return defaultValue
        if isLog:
            GameWorld.ErrLog("PyMongoDataServer.ini找不到配置: section=%s,option=%s" % (section, option))
        return ""
    
    strParam = PyMongoDataServerConfig.get(section, option, raw)