#!/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()