#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package DB.StructData.DBGameRec
|
#
|
# @todo:ͨÓüǼ±íÐÂ
|
# @author hxp
|
# @date 2025-05-23
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: ͨÓüǼ±íУ¬ÔͨÓüǼ×Ö·û³¤¶È¼Ç¼ÓÐÏÞ£¬ÇÒÕë¶Ôij¸ö¼Ç¼ÀàÐÍϵÄ×ÓÀàÐͲéÕÒÿ´ÎÐèÒª±éÀú£¬Ð§Âʲ»¸ß
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2025-05-23 20:00"""
|
#-------------------------------------------------------------------------------
|
|
import DBStruct
|
import GameWorld
|
import ShareDefine
|
import CommFunc
|
import DBComm
|
|
import time
|
|
class GameRecData():
|
|
def __init__(self, dbData=None, dataToJson=False):
|
if not dbData:
|
dbData = DBStruct.tagDBGameRec()
|
self.__dbData = dbData
|
self.__dataDict = DBComm.UserDataDict(self.__dbData, "UserData", "UserDataLen", dataToJson)
|
return
|
def GetRecType(self): return self.__dbData.RecType
|
def SetRecType(self, recType): self.__dbData.RecType = recType
|
def GetRecID(self): return self.__dbData.RecID
|
def SetRecID(self, recID): self.__dbData.RecID = recID
|
def GetTime(self): return self.__dbData.Time
|
def SetTime(self, sTime): self.__dbData.Time = sTime
|
def GetValue1(self): return self.__dbData.Value1
|
def SetValue1(self, value1): self.__dbData.Value1 = value1
|
def GetValue2(self): return self.__dbData.Value2
|
def SetValue2(self, value2): self.__dbData.Value2 = value2
|
def GetValue3(self): return self.__dbData.Value3
|
def SetValue3(self, value3): self.__dbData.Value3 = value3
|
def GetValue4(self): return self.__dbData.Value4
|
def SetValue4(self, value4): self.__dbData.Value4 = value4
|
def GetValue5(self): return self.__dbData.Value5
|
def SetValue5(self, value5): self.__dbData.Value5 = value5
|
def GetValue6(self): return self.__dbData.Value6
|
def SetValue6(self, value6): self.__dbData.Value6 = value6
|
def GetValue7(self): return self.__dbData.Value7
|
def SetValue7(self, value7): self.__dbData.Value7 = value7
|
def GetValue8(self): return self.__dbData.Value8
|
def SetValue8(self, value8): self.__dbData.Value8 = value8
|
def GetUserDict(self): return self.__dataDict.GetData()
|
def GetUserData(self): return self.__dataDict.ToString()
|
def SetUserData(self, value): self.__dataDict.SetData(value)
|
def GetBuffer(self):
|
self.__dataDict.ToString()
|
return self.__dbData.getBuffer()
|
|
def IsMatchValue(self, valueList):
|
# ¼ì²é¼Ç¼ֵÁбíÊÇ·ñÅäÖøüǼ
|
# @param valueList: [value1, value2, ...] valueΪNoneʱ²»ÅжϸÃÖµ
|
if not valueList:
|
return False
|
for i, value in enumerate(valueList, 1):
|
if value == None:
|
continue
|
if not hasattr(self, "GetValue%s" % i):
|
return False
|
curValue = getattr(self, "GetValue%s" % i)()
|
if curValue != value:
|
return False
|
return True
|
|
def GetValueIndexKey(self):
|
## »ñÈ¡Value¿ìËÙ²éÕÒË÷Òýkey£¬Ä¬ÈÏʹÓÃvalue1
|
recType = self.GetRecType()
|
if recType not in ShareDefine.Def_GameRecValueKeyDict:
|
return ""
|
valueNumList = ShareDefine.Def_GameRecValueKeyDict[recType]
|
if not valueNumList:
|
valueNumList = [1]
|
keyStr = ""
|
for num in valueNumList:
|
if not hasattr(self, "GetValue%s" % num):
|
return ""
|
if keyStr:
|
keyStr += "_"
|
keyStr += str(getattr(self, "GetValue%s" % num)())
|
return keyStr
|
|
class GameRecIDMgr():
|
## ÀàÐÍÊý¾ÝID¹ÜÀí
|
|
def __init__(self, recType, recID):
|
self.__recType = recType
|
self.__recID = recID
|
self.__dataList = [] # Êý¾ÝÁбí [GameRecData, ...]
|
self.__valueIndexDict = {} # valueË÷ÒýÖµ¶ÔÓ¦Êý¾ÝÁбí {indexKey:[GameRecData, ...], ...}
|
return
|
|
def InitRecDataInstance(self, dbData):
|
'''³õʼ»¯¹¦ÄÜÊý¾ÝʵÀý£¬´´½¨»ò¼ÓÔØÊý¾ÝʱͨÓ㬹¦ÄÜÒ»°ã²»µ÷ÓÃ
|
@param dbData: ʵÀý¶ÔÓ¦°ó¶¨µÄdbData
|
@return: ³É¹¦·µ»ØÊµÀý¶ÔÏó£¬Ê§°Ü·µ»ØNone
|
'''
|
dataToJson = False
|
# Èç¹ûÐèÒª dataToJson£¬¿É¸ù¾Ý RecType ÔÚÕâÀï´¦Àí
|
if dbData.RecType in []:
|
dataToJson = True
|
recData = GameRecData(dbData, dataToJson)
|
self.__dataList.append(recData)
|
|
keyStr = recData.GetValueIndexKey()
|
if keyStr:
|
if keyStr not in self.__valueIndexDict:
|
self.__valueIndexDict[keyStr] = []
|
recIndexDataList = self.__valueIndexDict[keyStr]
|
recIndexDataList.append(recData)
|
|
return recData
|
|
def GetRecType(self): return self.__recType
|
def GetRecID(self): return self.__recID
|
|
def SortByTime(self):
|
self.__dataList.sort(key=lambda r: (r.GetTime()), reverse=False)
|
return
|
|
def AddRecData(self, maxCount=None):
|
'''Ìí¼Ó¼Ç¼
|
@param maxCount: ¿É´«ÈëÓÉÅäÖþö¶¨µÄ×î´óÌõÊý£¬Èç¹ûΪNoneÔò½øÒ»²½È¡³ÌÐòĬÈÏÉ趨µÄ×î´óÌõÊý£¬¶¼Ã»ÅäÖõϰĬÈϲ»ÏÞÌõÊý
|
'''
|
|
fullClear = True
|
recData = None
|
if maxCount == None:
|
maxCount = 0
|
if maxCount and self.GetCount() >= maxCount:
|
if not fullClear:
|
#³¬¹ý¼Ç¼¼Ç¼²»ÁËÁË
|
return recData
|
#self.SortByTime() # °´Ê±¼äÉýÐò
|
self.DelCount(self.GetCount() - maxCount + 1)
|
|
dbData = DBStruct.tagDBGameRec()
|
dbData.RecType = self.__recType
|
dbData.RecID = self.__recID
|
dbData.Time = int(time.time())
|
#if valueSetList:
|
# for num, v in enumerate(valueSetList, 1):
|
# if not hasattr(dbData, "Value%s" % num):
|
# continue
|
# setattr(dbData, "Value%s" % num, v
|
|
recData = self.InitRecDataInstance(dbData)
|
return recData
|
|
def GetCount(self): return len(self.__dataList)
|
def At(self, index):
|
recData = None
|
if 0 <= index < len(self.__dataList):
|
recData = self.__dataList[index]
|
elif False:
|
recData = GameRecData()
|
return recData
|
|
def GetOneRecData(self, isAddNew=False):
|
## »ñÈ¡µÚÒ»Ìõ¼Ç¼£¬ÊÊÓÃÓÚ½öÐèÒ»ÌõµÄ¼Ç¼ÀàÐÍ
|
# @param isAddNew: ûÓмǼʱÊÇ·ñÌí¼ÓÒ»ÌõмǼ£¬Ò»°ã»ñÈ¡ºóÐèÒª¸üÐÂÊý¾ÝµÄ¿ÉÒÔÉèÖÃΪTrue£¬½öÅжÏÓõĽ¨ÒéÉèÖÃΪFalse£¬¼õÉÙ²úÉú¶àÓà¿ÕÊý¾Ý
|
recData = None
|
if self.__dataList:
|
recData = self.__dataList[0]
|
elif isAddNew:
|
recData = self.AddRecData()
|
return recData
|
|
def GetRecDataByValues(self, valueList, findone=False):
|
'''»ñȡƥÅävalueÖµµÄ¼Ç¼
|
@param valueList: [value1, value2, ...] valueΪNoneʱ²»ÅжϸÃÖµ
|
@param findone: ÊÇ·ñֻƥÅäÒ»ÌõÂú×ãµÄ¼Ç¼
|
@return: recData or [recData, ...] or None
|
'''
|
|
# ÓÐÅäÖÃvalueË÷ÒýkeyµÄ£¬Ö±½Ó¿ìËÙ»ñÈ¡
|
if self.__recType in ShareDefine.Def_GameRecValueKeyDict:
|
keyStr = ""
|
for v in valueList:
|
if keyStr:
|
keyStr += "_"
|
keyStr += str(v)
|
if keyStr not in self.__valueIndexDict:
|
return
|
recIndexDataList = self.__valueIndexDict[keyStr]
|
if not recIndexDataList:
|
return
|
return recIndexDataList[0] if findone else recIndexDataList
|
|
# ûÓеÄÔò±éÀúÆ¥Åä
|
matchRecDataList = []
|
for recData in self.__dataList:
|
if not recData.IsMatchValue(valueList):
|
continue
|
if findone:
|
return recData
|
matchRecDataList.append(recData)
|
return matchRecDataList
|
|
def DelAllData(self):
|
## ɾ³ý¸Ã¼Ç¼IDµÄËùÓÐÊý¾Ý
|
dataCount = self.GetCount()
|
if not dataCount:
|
return 0
|
#GameWorld.DebugLog("ɾ³ýͨÓüǼij¸öÀàÐÍIDËùÓмǼ: recType=%s,recID=%s,dataCount=%s" % (self.__recType, self.__recID, dataCount))
|
self.__dataList = []
|
self.__valueIndexDict = {}
|
return dataCount
|
|
def DelDataByValue(self, valueList):
|
## ɾ³ý¸Ã¼Ç¼IDËùÓÐÆ¥ÅäValueÖµÁбíµÄÊý¾Ý¼Ç¼
|
# @param valueList: [value1, value2, ...] valueΪNoneʱ²»ÅжϸÃÖµ
|
if not valueList:
|
return 0
|
|
delCount = 0
|
for recData in self.__dataList[::-1]: # µ¹Ðò´¦Àíɾ³ý
|
if recData.IsMatchValue(valueList):
|
self.DelRecData(recData)
|
delCount += 1
|
|
#if delCount:
|
# GameWorld.DebugLog("ɾ³ýͨÓüǼij¸öÀàÐÍIDËùÓÐÆ¥ÅäValueÖµµÄ¼Ç¼: recType=%s,recID=%s,valueList=%s,delCount=%s"
|
# % (self.__recType, self.__recID, valueList, delCount))
|
return delCount
|
|
def DelRecData(self, recData):
|
## ɾ³ýÖ¸¶¨¼Ç¼
|
if not recData:
|
return 0
|
|
if recData in self.__dataList:
|
self.__dataList.remove(recData)
|
|
keyStr = recData.GetValueIndexKey()
|
if keyStr in self.__valueIndexDict:
|
recIndexDataList = self.__valueIndexDict[keyStr]
|
if recData in recIndexDataList:
|
recIndexDataList.remove(recData)
|
|
return 1
|
|
def DelCount(self, delCount, reverse=False):
|
## ɾ³ýÌõÊý
|
# @param reverse: False-´ÓË÷Òý0¿ªÊ¼É¾³ý£¬True-´Ó×îºóÒ»¸öË÷ÒýÍùǰɾ
|
delDataList = self.__dataList[:delCount] if not reverse else self.__dataList[-delCount-1:]
|
for recData in delDataList:
|
self.DelRecData(recData)
|
#GameWorld.DebugLog("ɾ³ýͨÓüǼÌõÊý: recType=%s,recID=%s,delCount=%s,remainCount=%s"
|
# % (self.__recType, self.__recID, delCount, len(self.__dataList)))
|
return
|
|
class GameRecTypeMgr():
|
## ÀàÐ͹ÜÀí
|
|
def __init__(self, recType):
|
self.__recType = recType
|
self.__recIDDict = {} # recID¶ÔÓ¦Êý¾ÝÁбí {recID:GameRecIDMgr, ...}
|
return
|
|
def GetRecType(self): return self.__recType
|
|
def GetRecIDMgr(self, recID):
|
recIDMgr = None
|
if recID in self.__recIDDict:
|
recIDMgr = self.__recIDDict[recID]
|
else:
|
recIDMgr = GameRecIDMgr(self.__recType, recID)
|
self.__recIDDict[recID] = recIDMgr
|
return recIDMgr
|
|
def GetRecIDList(self): return self.__recIDDict.keys()
|
|
def GetRecDataByValues(self, valueList, findone=False):
|
## »ñÈ¡¸ÃÀàÐÍËùÓмǼƥÅävalueÖµµÄ¼Ç¼
|
matchRecDataList = []
|
for recID in self.__recIDDict.keys():
|
recIDMgr = self.GetRecIDMgr(recID)
|
ret = recIDMgr.GetRecDataByValues(valueList, findone)
|
if not ret:
|
continue
|
if findone:
|
return ret
|
|
if isinstance(ret, list):
|
matchRecDataList += ret
|
|
return matchRecDataList
|
|
def DelAllData(self):
|
## ɾ³ý¸ÃÀàÐÍËùÓмǼ
|
delCount = 0
|
for recID in self.__recIDDict.keys():
|
delCount += self.DelDataByRecID(recID)
|
return delCount
|
def DelDataByRecID(self, recID):
|
## ɾ³ý¸ÃÀàÐÍij¸ö¼Ç¼IDµÄËùÓмǼ
|
return self.GetRecIDMgr(recID).DelAllData()
|
def DelDataByValue(self, valueList):
|
## ɾ³ý¸ÃÀàÐÍËùÓÐÆ¥ÅäValueÖµÁбíµÄ¼Ç¼
|
delCount = 0
|
for recID in self.__recIDDict.keys():
|
recIDMgr = self.GetRecIDMgr(recID)
|
delCount += recIDMgr.DelDataByValue(valueList)
|
return delCount
|
|
class GameRecMgr():
|
## ͨÓüǼ¹ÜÀí
|
|
def __init__(self):
|
self.__recTypeDict = {} # {recType:GameRecTypeMgr, ...}
|
return
|
|
def GetRecTypeMgr(self, recType):
|
recTypeMgr = None
|
if recType in self.__recTypeDict:
|
recTypeMgr = self.__recTypeDict[recType]
|
else:
|
recTypeMgr = GameRecTypeMgr(recType)
|
self.__recTypeDict[recType] = recTypeMgr
|
return recTypeMgr
|
|
def GetRecTypeIDMgr(self, recType, recID):
|
recTypeMgr = self.GetRecTypeMgr(recType)
|
recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
|
if not recTypeIDMgr and False:
|
recTypeIDMgr = GameRecIDMgr(recType, recID)
|
return recTypeIDMgr
|
|
# ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup
|
def GetSaveData(self):
|
savaData = ""
|
cntData = ""
|
cnt = 0
|
|
for recType in self.__recTypeDict.keys():
|
recTypeMgr = self.GetRecTypeMgr(recType)
|
for recID in recTypeMgr.GetRecIDList():
|
recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
|
for index in range(recTypeIDMgr.GetCount()):
|
recData = recTypeIDMgr.At(index)
|
savaData += recData.GetBuffer()
|
cnt += 1
|
|
GameWorld.Log("Save DBGameRec count :%s len=%s" % (cnt, len(savaData)))
|
return CommFunc.WriteDWORD(cntData, cnt) + savaData
|
|
# ´ÓÊý¾Ý¿âÔØÈëÊý¾Ý
|
def LoadPyGameData(self, datas, pos, dataslen):
|
cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
GameWorld.Log("Load DBGameRec count :%s" % cnt)
|
|
for _ in xrange(cnt):
|
dbData = DBStruct.tagDBGameRec()
|
dbData.readData(datas, pos, dataslen)
|
recType = dbData.RecType
|
recID = dbData.RecID
|
recTypeIDMgr = self.GetRecTypeIDMgr(recType, recID)
|
recTypeIDMgr.InitRecDataInstance(dbData)
|
|
for recType in self.__recTypeDict.keys():
|
recTypeMgr = self.GetRecTypeMgr(recType)
|
for recID in recTypeMgr.GetRecIDList():
|
recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
|
recTypeIDMgr.SortByTime()
|
|
return pos
|
|
|
|
|