#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package GameRecData
|
#
|
# @todo:ͨÓüǼ±íÐÂ
|
# @author hxp
|
# @date 2024-09-04
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: ͨÓüǼ±íУ¬ÔͨÓüǼ×Ö·û³¤¶È¼Ç¼ÓÐÏÞ£¬ÇÒÕë¶Ôij¸ö¼Ç¼ÀàÐÍϵÄ×ÓÀàÐͲéÕÒÿ´ÎÐèÒª±éÀú£¬Ð§Âʲ»¸ß
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2024-09-04 16:30"""
|
#-------------------------------------------------------------------------------
|
|
import GameWorld
|
import PyGameDataStruct
|
import ShareDefine
|
import CommFunc
|
|
import time
|
|
class GameRecData():
|
|
def __init__(self, dbRecData=None):
|
if not dbRecData:
|
dbRecData = PyGameDataStruct.tagDBGameRec()
|
self.dbRecData = dbRecData
|
self.__userDataDict = None
|
self.__userDataChange = False
|
return
|
def clear(self):
|
self.dbRecData.clear()
|
self.__userDataDict = None
|
self.__userDataChange = False
|
return
|
def GetRecType(self): return self.dbRecData.RecType
|
def SetRecType(self, recType): self.dbRecData.RecType = recType
|
def GetRecID(self): return self.dbRecData.RecID
|
def SetRecID(self, recID): self.dbRecData.RecID = recID
|
def GetTime(self): return self.dbRecData.Time
|
def SetTime(self, sTime): self.dbRecData.Time = sTime
|
def GetValue1(self): return self.dbRecData.Value1
|
def SetValue1(self, value1): self.dbRecData.Value1 = value1
|
def GetValue2(self): return self.dbRecData.Value2
|
def SetValue2(self, value2): self.dbRecData.Value2 = value2
|
def GetValue3(self): return self.dbRecData.Value3
|
def SetValue3(self, value3): self.dbRecData.Value3 = value3
|
def GetValue4(self): return self.dbRecData.Value4
|
def SetValue4(self, value4): self.dbRecData.Value4 = value4
|
def GetValue5(self): return self.dbRecData.Value5
|
def SetValue5(self, value5): self.dbRecData.Value5 = value5
|
def GetValue6(self): return self.dbRecData.Value6
|
def SetValue6(self, value6): self.dbRecData.Value6 = value6
|
def GetValue7(self): return self.dbRecData.Value7
|
def SetValue7(self, value7): self.dbRecData.Value7 = value7
|
def GetValue8(self): return self.dbRecData.Value8
|
def SetValue8(self, value8): self.dbRecData.Value8 = value8
|
def __GetUserDataDict(self):
|
if self.__userDataDict == None:
|
try:
|
self.__userDataDict = eval(self.dbRecData.UserData)
|
except:
|
self.__userDataDict = {}
|
return self.__userDataDict
|
def GetUserDataByKey(self, key, defaultValue=None):
|
userDataDict = self.__GetUserDataDict()
|
if key in userDataDict:
|
return userDataDict[key]
|
return defaultValue
|
def SetUserDataByKey(self, key, value):
|
userDataDict = self.__GetUserDataDict()
|
userDataDict[key] = value
|
self.__userDataChange = True
|
return
|
def GetUserData(self):
|
if self.__userDataChange:
|
self.SaveUserData()
|
return self.dbRecData.UserData
|
def SetUserData(self, userData):
|
## Ö§³ÖÖ±½Ó±£´æÈÎÒâ¸ñʽÊý¾Ý£¬»òÕß°´×ֵ䷽ʽ¶ÁÈ¡kvÖµ
|
if type(userData) != str:
|
userData = str(userData)
|
self.dbRecData.UserData = userData.replace(" ", "")
|
self.dbRecData.UserDataLen = len(self.dbRecData.UserData)
|
self.__userDataDict = None
|
self.__userDataChange = False
|
return
|
def SaveUserData(self):
|
if self.__userDataChange:
|
self.SetUserData(self.__userDataDict)
|
return
|
|
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):
|
continue
|
curValue = getattr(self, "GetValue%s" % i)()
|
if curValue != value:
|
return False
|
return True
|
|
def GetString(self):
|
return {"RecID":self.GetRecID(), "RecType":self.GetRecType(), "Time":self.GetTime(),
|
"Value1":self.GetValue1(), "Value2":self.GetValue2(), "Value3":self.GetValue3(), "Value4":self.GetValue4(),
|
"Value5":self.GetValue5(), "Value6":self.GetValue6(), "Value7":self.GetValue7(), "Value8":self.GetValue8(),
|
"UserDataDict":self.__GetUserDataDict()
|
}
|
def SetAttr(self, attrDict, isClear=False):
|
if isClear:
|
self.clear()
|
for k, v in attrDict.items():
|
if hasattr(self, "Set%s" % k):
|
getattr(self, "Set%s" % k, v)(v)
|
elif k == "UserDataDict":
|
self.__userDataDict = v
|
return
|
|
class DBGameRecDataManager():
|
## ͨÓüǼ¹ÜÀí
|
|
def __init__(self):
|
self.Clear()
|
return
|
|
def Clear(self):
|
self.recTypeDict = {} # {recType:{recID:[GameRecData, ...], ...}}
|
self.recValueIndexDict = {} # {recType:{recID:{indexKey:[GameRecData, ...], ...}, ...}, ...}
|
return
|
|
def DelGameRecDataByType(self, recType):
|
## ɾ³ýij¸ö¼Ç¼ÀàÐÍËùÓмǼ
|
recDict = self.recTypeDict.pop(recType, {})
|
delCount = 0
|
for recList in recDict.values():
|
delCount += len(recList)
|
GameWorld.DebugLog("ɾ³ýÖ¸¶¨ÐÂͨÓüǼÀàÐÍËùÓмǼ: recType=%s,delCount=%s" % (recType, delCount))
|
self.recValueIndexDict.pop(recType, {})
|
return delCount
|
|
def DelGameRecDataByTypeID(self, recType, delRecID):
|
## ɾ³ýij¸öÀàÐͶÔÓ¦µÄID¼Ç¼
|
if recType not in self.recTypeDict:
|
return 0
|
recDataDict = self.recTypeDict[recType]
|
recDataList = recDataDict.pop(delRecID, None)
|
delCount = len(recDataList) if recDataList else 0
|
GameWorld.DebugLog("ɾ³ýÖ¸¶¨ÐÂͨÓüǼÀàÐÍij¸ö¼Ç¼IDËùÓмǼ: recType=%s,delRecID=%s,delCount=%s" % (recType, delRecID, delCount))
|
if recType in self.recValueIndexDict:
|
recIndexDataDict = self.recValueIndexDict[recType]
|
recIndexDataDict.pop(delRecID, None)
|
return delCount
|
|
def DelGameRecDataByTypeValue(self, recType, valueList, delRecID=None):
|
## ɾ³ýij¸ö¼Ç¼ÀàÐÍÆ¥ÅäValueÖµÁбíµÄ¼Ç¼
|
# @param valueList: [value1, value2, ...] valueΪNoneʱ²»ÅжϸÃÖµ
|
# @param delRecID: ¿ÉÖ¸¶¨Ö»É¾³ý¼Ç¼IDµÄ¼Ç¼
|
|
if not valueList:
|
return 0
|
if recType not in self.recTypeDict:
|
return 0
|
delCountTotal = 0
|
recDict = self.recTypeDict[recType]
|
for recID, recDataList in recDict.items():
|
if delRecID and recID != delRecID:
|
continue
|
delCount = 0
|
for recData in recDataList[::-1]: # µ¹Ðò´¦Àíɾ³ý
|
if recData.IsMatchValue(valueList):
|
delCount += self.DelGameRecData(recData)
|
|
if delCount:
|
delCountTotal += delCount
|
GameWorld.DebugLog("ɾ³ýij¸öÐÂͨÓüǼÀàÐÍËùÓÐValue1Æ¥ÅäÖµµÄ¼Ç¼: recType=%s,valueList=%s,delRecID=%s,delCount=%s"
|
% (recType, valueList, recID, delCount))
|
return delCountTotal
|
|
def DelGameRecData(self, recData):
|
## ɾ³ýÖ¸¶¨¼Ç¼
|
recID = recData.GetRecID()
|
recType = recData.GetRecType()
|
if recType not in self.recTypeDict:
|
return 0
|
recDataDict = self.recTypeDict[recType]
|
if recID not in recDataDict:
|
return 0
|
recDataList = recDataDict[recID]
|
if recData in recDataList:
|
recDataList.remove(recData)
|
|
keyStr = self.__GetValueIndexKey(recData)
|
if keyStr:
|
recIndexDataDict = self.recValueIndexDict.get(recType, {})
|
valueIndexDict = recIndexDataDict.get(recID, {})
|
recIndexDataList = valueIndexDict.get(keyStr, [])
|
if recData in recIndexDataList:
|
recIndexDataList.remove(recData)
|
return 1
|
|
def AddGameRecData(self, recType, recID, valueSetList=None, maxCount=0):
|
'''Ìí¼Ó¼Ç¼
|
@param recType: ¼Ç¼ÀàÐÍ
|
@param recID: ¼Ç¼ÀàÐͶÔÓ¦µÄ×ÓID£¬±ÈÈç¿ÉÒÔÊÇÍæ¼ÒID»òÕ߯äËû×Ô¶¨µÄID£¬¸ÃIDÔÚͬ¸ö¼Ç¼ÀàÐÍÖÐΨһ£¬²»Í¬¼Ç¼ÀàÐÍ¿ÉÖØ¸´
|
@param valueList: [value1, value2, ...] ÉèÖõÄValueÖµÁбí
|
@param maxCount: ÿÖּǼID×î´ó¿É±£´æ¼Ç¼ÌõÊý£¬Ä¬ÈÏ0²»ÏÞÖÆ
|
'''
|
recData = GameRecData()
|
recData.clear()
|
recData.SetRecType(recType)
|
recData.SetRecID(recID)
|
recData.SetTime(int(time.time()))
|
if valueSetList:
|
for num, v in enumerate(valueSetList, 1):
|
if not hasattr(recData, "SetValue%s" % num):
|
continue
|
getattr(recData, "SetValue%s" % num)(v)
|
recDataList = self.__AddGameRecData(recData)
|
|
doCount = len(recDataList)
|
while maxCount and len(recDataList) > maxCount and doCount > 0:
|
GameWorld.DebugLog("³¬¹ý¼Ç¼ÉÏÏÞɾ³ý¼Ç¼: recType=%s,recID=%s,recCount=%s,maxCount=%s" % (recType, recID, len(recDataList), maxCount))
|
doCount -= 1
|
self.DelGameRecData(recDataList[0]) # ³¬¹ý×î´óÉÏÏÞ£¬É¾³ýµÚÒ»¸ö
|
|
return recData
|
|
def AddGameRecDataByDict(self, attrDict):
|
## Ò»°ãÊÇ¿ç·þͬ²½¹ýÀ´Êý¾ÝÌí¼ÓÓÃ
|
recData = GameRecData()
|
recData.SetAttr(attrDict, True)
|
self.__AddGameRecData(recData)
|
return recData
|
|
def __AddGameRecData(self, recData):
|
recID = recData.GetRecID()
|
recType = recData.GetRecType()
|
if recType not in self.recTypeDict:
|
self.recTypeDict[recType] = {}
|
recDataDict = self.recTypeDict[recType]
|
if recID not in recDataDict:
|
recDataDict[recID] = []
|
recDataList = recDataDict[recID]
|
recDataList.append(recData)
|
|
keyStr = self.__GetValueIndexKey(recData)
|
if keyStr:
|
if recType not in self.recValueIndexDict:
|
self.recValueIndexDict[recType] = {}
|
recIndexDataDict = self.recValueIndexDict[recType]
|
if recID not in recIndexDataDict:
|
recIndexDataDict[recID] = {}
|
valueIndexDict = recIndexDataDict[recID]
|
if keyStr not in valueIndexDict:
|
valueIndexDict[keyStr] = []
|
recIndexDataList = valueIndexDict[keyStr]
|
recIndexDataList.append(recData)
|
return recDataList
|
|
def __GetValueIndexKey(self, recData):
|
## »ñÈ¡¼Ç¼¶ÔÏó¶ÔÓ¦×ÖµäkeyÖµ£¬Ä¬ÈÏʹÓÃvalue1
|
recType = recData.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(recData, "GetValue%s" % num):
|
return
|
if keyStr:
|
keyStr += "_"
|
keyStr += str(getattr(recData, "GetValue%s" % num)())
|
return keyStr
|
|
def GetGameRecDataMatch(self, recType, recID, valueList, findone=False):
|
'''»ñÈ¡¼Ç¼ÀàÐͶÔÓ¦µÄÆ¥ÅävalueÖµ¼Ç¼
|
@param recType: ¼Ç¼ÀàÐÍ
|
@param recID: ¼Ç¼ÀàÐͶÔÓ¦µÄ×ÓID
|
@param valueList: [value1, value2, ...] valueΪNoneʱ²»ÅжϸÃÖµ
|
@param findone: ÊÇ·ñֻƥÅäÒ»ÌõÂú×ãµÄ¼Ç¼
|
@return: recData or [recData, ...] or None
|
'''
|
|
# ÓÐÅäÖÃvalueË÷ÒýkeyµÄ£¬Ö±½Ó¿ìËÙ»ñÈ¡
|
if recType in ShareDefine.Def_GameRecValueKeyDict:
|
if recType not in self.recValueIndexDict:
|
return
|
recIndexDataDict = self.recValueIndexDict[recType]
|
if recID not in recIndexDataDict:
|
return
|
valueIndexDict = recIndexDataDict[recID]
|
keyStr = ""
|
for v in valueList:
|
if keyStr:
|
keyStr += "_"
|
keyStr += str(v)
|
if keyStr not in valueIndexDict:
|
return
|
recIndexDataList = valueIndexDict[keyStr]
|
if not recIndexDataList:
|
return
|
return recIndexDataList[0] if findone else recIndexDataList
|
|
# ûÓеÄÔò±éÀúÆ¥Åä
|
recDataList = self.GetGameRecDataList(recType, recID)
|
if not recDataList:
|
return
|
matchRecDataList = []
|
for recData in recDataList:
|
if not recData.IsMatchValue(valueList):
|
continue
|
if findone:
|
return recData
|
matchRecDataList.append(recData)
|
return matchRecDataList
|
|
def GetGameRecDataList(self, recType, recID):
|
## »ñÈ¡¼Ç¼ÀàÐͶÔÓ¦¼Ç¼Áбí [recData, ...]
|
if recType not in self.recTypeDict:
|
self.recTypeDict[recType] = {}
|
recDataDict = self.recTypeDict[recType]
|
if recID not in recDataDict:
|
recDataDict[recID] = []
|
recDataList = recDataDict[recID]
|
return recDataList
|
|
def GetGameRecDataDict(self, recType):
|
## »ñÈ¡¼Ç¼ÀàÐͶÔÓ¦ËùÓмǼ×Öµä {recID:[recData, ...], ...}
|
if recType not in self.recTypeDict:
|
return {}
|
return self.recTypeDict[recType]
|
|
def SortGameRecDataList(self, recDataList):
|
recDataList.sort(key=lambda r: (r.GetTime()), reverse=False)
|
return
|
|
# ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup
|
def GetSaveData(self):
|
savaData = ""
|
cntData = ""
|
cnt = 0
|
|
for recDataDict in self.recTypeDict.values():
|
for recDataList in recDataDict.values():
|
for recData in recDataList:
|
cnt += 1
|
recData.SaveUserData()
|
savaData += recData.dbRecData.getBuffer()
|
|
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)
|
|
self.Clear()
|
|
for _ in xrange(cnt):
|
recData = PyGameDataStruct.tagDBGameRec()
|
recData.clear()
|
pos += recData.readData(datas, pos, dataslen)
|
|
self.__AddGameRecData(GameRecData(recData))
|
|
# °´Ê±¼äÉýÐòÅÅÐòÏÂ
|
for recDataDict in self.recTypeDict.values():
|
for recDataList in recDataDict.values():
|
recDataList.sort(key=lambda d: (d.GetTime()))
|
return pos
|
|
GameRecDataTemp = GameRecData()
|
|
|