#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package Script.DB.DBDataMgr # # @todo:DBÊý¾Ý¹ÜÀíÆ÷ # @author hxp # @date 2025-05-09 # @version 1.0 # # ÏêϸÃèÊö: DBÊý¾Ý¹ÜÀíÆ÷ # #------------------------------------------------------------------------------- #"""Version = 2025-05-09 12:20""" #------------------------------------------------------------------------------- import GameWorld import PyGameData import DBEventTrig import DBPlayerViewCache import DBBillboard import DBFamily import DBMail import binascii import time import zlib import os BakRoot = "C:\ServerRealTimeBackup" BakFileType = ".bak" #ÁÙʱ±äÁ¿£¬Ö®ºóÓÅ»¯ g_loadErr = False Map2ServerID = { 10010:87, 10090:89, } def OnServerStart(): GameWorld.DebugLog("µØÍ¼·þÎñÆ÷Æô¶¯") LoadServerDataBackup() return def OnServerClose(): return def OnMinute(curTime): #curMinute = curTime.minute ServerDataBackup() DBFamily.OnMinute() DBBillboard.OnMinute() return #------------------------------------------- ±¸µµ --------------------------------------------------- def GetBakFileSortList(bakPath): ## °´±¸µµÊ±¼äµ¹ÐòÅÅÐò·µ»Ø [[bakTime, filePath], ...] bakFileList = [] for parent, _, filenames in os.walk(bakPath): for filename in filenames: if not filename.endswith(BakFileType): continue fullPath = os.path.join(parent, filename) bakTime = GameWorld.ToIntDef(filename[:filename.index(".")].split("_")[1]) bakFileList.append([bakTime, fullPath]) bakFileList.sort(reverse=True) return bakFileList def LoadServerDataBackup(): ## ·þÎñÆ÷¹«¹²Êý¾Ý±¸µµ¼ÓÔØ global g_loadErr mapID = GameWorld.GetMap().GetMapID() if mapID not in Map2ServerID: return serverName = "S%s" % Map2ServerID[mapID] BakDir = os.path.join(BakRoot, serverName) GameWorld.Log("¼ÓÔØ±¸µµ: %s" % BakDir) bakFileList = GetBakFileSortList(BakDir) if not bakFileList: GameWorld.Log("²»´æÔÚ±¸µµ!") return bakFilePath = bakFileList[0][1] # È¡µÚÒ»¸öΪ×î½üµÄÒ»´Î±¸µµ GameWorld.Log("¶ÁÈ¡±¸µµ: %s" % bakFilePath) f = open(bakFilePath, 'rb') compressed_data = f.read().strip() f.close() try: decompressed_data = zlib.decompress(compressed_data) bakData = binascii.a2b_hex(decompressed_data) except: g_loadErr = True raise LoadPyGameData(bakData, 0) return def ServerDataBackup(): ## ·þÎñÆ÷¹«¹²Êý¾Ý¶¨Ê±±¸µµ£¬ÔÝʱֱ½Ó´æÅÌ if g_loadErr: GameWorld.ErrLog("¼ÓÔØ±¸µµÒÑÒì³££¬ÔÝʱ²»ÔÚ´æ´¢±¸µµ") return mapID = GameWorld.GetMap().GetMapID() if mapID not in Map2ServerID: return serverName = "S%s" % Map2ServerID[mapID] BakDir = os.path.join(BakRoot, serverName) BackupCopyMax = 3 GameWorld.Log("·þÎñÆ÷±¸µµ: %s" % serverName) if not os.path.exists(BakDir): os.makedirs(BakDir) curTime = int(time.time()) bakFilePath = os.path.join(BakDir, "%s_%s%s" % (serverName, curTime, BakFileType)) bakData = GetSavePyData() GameWorld.Log("Bak:%s, len=%s, %s" % (serverName, len(bakData), bakFilePath)) try: compressed_data = zlib.compress(bakData, 9) #×î´óѹËõ GameWorld.Log("compress len=%s" % len(compressed_data)) fp = open(bakFilePath, "wb") fp.write(compressed_data) fp.close() except: return bakFileList = GetBakFileSortList(BakDir) # ɾ³ý¶àÓ౸µµ for _, filePath in bakFileList[BackupCopyMax:]: os.remove(filePath) GameWorld.Log("ɾ³ý¶àÓ౸µµÎļþ: %s" % filePath) return #-------------------------------------------------------------------------------------------------- def GetSavePyData(): #´æ´¢Êý¾Ýǰ£¬Ò»Ð©¹¦ÄÜÒµÎñÊý¾ÝÏÈת»¯Îª´æµµÊý¾Ý #... pyGameDataMgr = GetDBDataMgr() result = pyGameDataMgr.GetSaveData() GameWorld.Log("GetSavePyData!! id = %s-%s"%(id(pyGameDataMgr), len(result))) result = binascii.b2a_hex(result) #GameWorld.DebugLog("GetSavePyData!! result = %s-%s"%(result, len(result))) # ×Ö½ÚÂëÔÚC++ת»¯»á·¢Éú´íÎómust be string without null bytes, not str£¬µ«ÊÇ¿ÉÒÔÕý³£±£´æ£¬´íÎó»áÔÚÏ´ε÷ÓñãÒ˽ӿڲŻᴥ·¢ # ÔÝʱ¸Ä³É×Ö·û´®·µ»Ø£¬ÔÝÎÞ½â¾ö·½°¸ return result # return str(len(result)) + "|" + result def LoadPyGameData(gameBuffer, pos): pyGameDataMgr = GetDBDataMgr() GameWorld.Log("LoadPyGameData!!id = %s %s"%(id(pyGameDataMgr), len(gameBuffer))) pos = pyGameDataMgr.LoadGameData(gameBuffer, pos) #¼ÓÔØÊý¾Ýºó£¬Ò»Ð©¹¦ÄÜת»¯Îª¹¦ÄÜÒµÎñÊý¾Ý #... return pos class PyGameDataManager(object): def __init__(self): self.EventTrigMgr = DBEventTrig.EventTrigMgr() self.PlayerViewCacheMgr = DBPlayerViewCache.PlayerViewCacheMgr() self.FamilyMgr = DBFamily.FamilyMgr() self.MailMgr = DBMail.MailMgr() self.BillboardMgr = DBBillboard.BillboardMgr() return def GetSaveData(self): buff = "" buff += self.EventTrigMgr.GetSaveData() buff += self.PlayerViewCacheMgr.GetSaveData() buff += self.FamilyMgr.GetSaveData() buff += self.MailMgr.GetSaveData() buff += self.BillboardMgr.GetSaveData() return buff def LoadGameData(self, gameBuffer, pos): dataslen = len(gameBuffer) pos = self.EventTrigMgr.LoadPyGameData(gameBuffer, pos, dataslen) pos = self.PlayerViewCacheMgr.LoadPyGameData(gameBuffer, pos, dataslen) pos = self.FamilyMgr.LoadPyGameData(gameBuffer, pos, dataslen) pos = self.MailMgr.LoadPyGameData(gameBuffer, pos, dataslen) pos = self.BillboardMgr.LoadPyGameData(gameBuffer, pos, dataslen) return pos def GetDBDataMgr(): ## pyÊý¾Ý¿â±íÊý¾Ý¹ÜÀíÆ÷ pyGameDataMgr = PyGameData.g_pyGameDataManager if not pyGameDataMgr: pyGameDataMgr = PyGameDataManager() PyGameData.g_pyGameDataManager = pyGameDataMgr return pyGameDataMgr def GetEventTrigMgr(): ## ʼþÖµ¹ÜÀíÆ÷ dbDataMgr = GetDBDataMgr() return dbDataMgr.EventTrigMgr def GetPlayerViewCacheMgr(): ## Íæ¼Ò²é¿´»º´æÊý¾Ý¹ÜÀíÆ÷ dbDataMgr = GetDBDataMgr() return dbDataMgr.PlayerViewCacheMgr def GetFamilyMgr(): ## ¼Ò×åÊý¾Ý¹ÜÀíÆ÷ dbDataMgr = GetDBDataMgr() return dbDataMgr.FamilyMgr def GetFamilyActionMgr(): ## ¼Ò×åActionÊý¾Ý¹ÜÀíÆ÷ return GetFamilyMgr().GetFamilyActionMgr() def GetMailMgr(): ## ÓʼþÊý¾Ý¹ÜÀíÆ÷ dbDataMgr = GetDBDataMgr() return dbDataMgr.MailMgr def GetBillboardMgr(): ## ÅÅÐаñÊý¾Ý¹ÜÀíÆ÷ dbDataMgr = GetDBDataMgr() return dbDataMgr.BillboardMgr