#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package PlayerRecData # # @todo:Íæ¼Ò¼Ç¼ # @author hxp # @date 2024-07-02 # @version 1.0 # # ÏêϸÃèÊö: Íæ¼Ò¼Ç¼£¬Çø±ðÓëͨÓüǼ£¬Í¨ÓüǼ×Ö·û³¤¶È¼Ç¼ÓÐÏÞ£¬ÇÒÕë¶ÔÍæ¼ÒµÄ¼Ç¼²éÕÒÿ´ÎÐèÒª±éÀú£¬Ð§Âʲ»¸ß # #------------------------------------------------------------------------------- #"""Version = 2024-07-02 16:30""" #------------------------------------------------------------------------------- import ChConfig import ShareDefine import PyDataManager import PyGameDataStruct import ChPyNetSendPack import NetPackCommon import GameWorld import CommFunc import time class PlayerRecData(): def __init__(self, dbRecData=None): if not dbRecData: dbRecData = PyGameDataStruct.tagDBPlayerRecData() self.dbRecData = dbRecData self.__userDataDict = None self.__userDataChange = False return def clear(self): self.dbRecData.clear() self.__userDataDict = None self.__userDataChange = False return def GetPlayerID(self): return self.dbRecData.PlayerID def SetPlayerID(self, playerID): self.dbRecData.PlayerID = playerID def GetRecType(self): return self.dbRecData.RecType def SetRecType(self, recType): self.dbRecData.RecType = recType 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 {"PlayerID":self.GetPlayerID(), "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(), "UserData":self.GetUserData() } 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) return class DBPlayerRecDataManager(): ## Íæ¼Ò¼Ç¼¹ÜÀí def __init__(self): self.Clear() return def Clear(self): self.recTypeDict = {} # {recType:{playerID:[PlayerRecData, ...], ...}} return def DelRecDataByType(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)) return delCount def DelRecDataByTypePlayer(self, recType, delPlayerID): ## ɾ³ýÍæ¼Òij¸öÀàÐͼǼ if recType not in self.recTypeDict: return 0 playerRecDataDict = self.recTypeDict[recType] recDataList = playerRecDataDict.pop(delPlayerID, None) delCount = len(recDataList) if recDataList else 0 GameWorld.DebugLog("ɾ³ýij¸öÍæ¼ÒÖ¸¶¨¼Ç¼ÀàÐÍ: recType=%s,delPlayerID=%s,delCount=%s" % (recType, delPlayerID, delCount)) return delCount def DelRecDataByTypeValue(self, recType, valueList, delPlayerID=None): ## ɾ³ýij¸ö¼Ç¼ÀàÐÍÆ¥ÅäValueÖµÁбíµÄ¼Ç¼ # @param valueList: [value1, value2, ...] valueΪNoneʱ²»ÅжϸÃÖµ # @param delPlayerID: ¿ÉÖ¸¶¨Ö»É¾³ýij¸öÍæ¼ÒµÄ¼Ç¼ if not valueList: return 0 if recType not in self.recTypeDict: return 0 delCountTotal = 0 recDict = self.recTypeDict[recType] for playerID, recDataList in recDict.items(): if delPlayerID and playerID != delPlayerID: continue delCount = 0 for recData in recDataList[::-1]: # µ¹Ðò´¦Àíɾ³ý if recData.IsMatchValue(valueList): recDataList.remove(recData) delCount += 1 if delCount: delCountTotal += delCount GameWorld.DebugLog("ɾ³ýij¸ö¼Ç¼ÀàÐÍËùÓÐValue1Æ¥ÅäÖµµÄ¼Ç¼: recType=%s,valueList=%s,delPlayerID=%s,delCount=%s" % (recType, valueList, playerID, delCount)) return delCountTotal def DelRecData(self, recData): ## ɾ³ýÖ¸¶¨¼Ç¼ playerID = recData.GetPlayerID() recType = recData.GetRecType() if recType not in self.recTypeDict: return 0 playerRecDataDict = self.recTypeDict[recType] if playerID not in playerRecDataDict: return 0 playerRecDataList = playerRecDataDict[playerID] if recData in playerRecDataList: playerRecDataList.remove(recData) return 1 def AddPlayerRecData(self, recType, playerID): ## Ìí¼ÓÍæ¼Ò¼Ç¼ recData = PlayerRecData() recData.clear() recData.SetPlayerID(playerID) recData.SetRecType(recType) recData.SetTime(int(time.time())) self.__AddRecData(recData) return recData def AddPlayerRecDataByDict(self, attrDict): ## Ò»°ãÊÇ¿ç·þͬ²½¹ýÀ´Êý¾ÝÌí¼ÓÓà recData = PlayerRecData() recData.SetAttr(attrDict, True) self.__AddRecData(recData) return recData def __AddRecData(self, recData): playerID = recData.GetPlayerID() recType = recData.GetRecType() if recType not in self.recTypeDict: self.recTypeDict[recType] = {} playerRecDataDict = self.recTypeDict[recType] if playerID not in playerRecDataDict: playerRecDataDict[playerID] = [] playerRecDataList = playerRecDataDict[playerID] playerRecDataList.append(recData) return def GetPlayerRecDataFirst(self, recType, playerID): ## »ñÈ¡Íæ¼Ò¼Ç¼ÀàÐͶÔÓ¦µÄµÚÒ»Ìõ¼Ç¼£¬ÊÊÓÃÓÚ½öÐèÒ»ÌõµÄ¼Ç¼ÀàÐÍ recDataList = self.GetPlayerRecDataList(recType, playerID) if recDataList: recData = recDataList[0] else: recData = self.AddPlayerRecData(recType, playerID) return recData def GetPlayerRecData(self, recType, playerID, valueList): ## »ñÈ¡Íæ¼Ò¼Ç¼ÀàÐͶÔÓ¦µÄijÌõ¼Ç¼ # @param valueList: [value1, value2, ...] valueΪNoneʱ²»ÅжϸÃÖµ recDataList = self.GetPlayerRecDataList(recType, playerID) if not recDataList: return for recData in recDataList: if recData.IsMatchValue(valueList): return recData return def GetPlayerRecDataList(self, recType, playerID): ## »ñÈ¡Íæ¼Ò¼Ç¼ÀàÐͶÔÓ¦¼Ç¼Áбí [recData, ...] if recType not in self.recTypeDict: self.recTypeDict[recType] = {} playerRecDataDict = self.recTypeDict[recType] if playerID not in playerRecDataDict: playerRecDataDict[playerID] = [] playerRecDataList = playerRecDataDict[playerID] return playerRecDataList def GetPlayerRecDataDict(self, recType): ## »ñÈ¡¼Ç¼ÀàÐͶÔÓ¦ËùÓÐÍæ¼ÒµÄ¼Ç¼×Öµä {playerID:[recData, ...], ...} if recType not in self.recTypeDict: return {} return self.recTypeDict[recType] def SortRecDataList(self, recDataList): recDataList.sort(key=lambda r: (r.GetTime()), reverse=False) return # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup def GetSaveData(self): savaData = "" cntData = "" cnt = 0 for playerRecDataDict in self.recTypeDict.values(): for recDataList in playerRecDataDict.values(): for recData in recDataList: cnt += 1 recData.SaveUserData() savaData += recData.dbRecData.getBuffer() GameWorld.Log("Save DBPlayerRecData 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 DBPlayerRecData count :%s" % cnt) self.Clear() for _ in xrange(cnt): recData = PyGameDataStruct.tagDBPlayerRecData() recData.clear() pos += recData.readData(datas, pos, dataslen) self.__AddRecData(PlayerRecData(recData)) return pos PlayerRecDataTemp = PlayerRecData() def OnPlayerLogin(curPlayer): playerID = curPlayer.GetPlayerID() playerRecMgr = PyDataManager.GetDBPlayerRecDataManager() for recType in ChConfig.Def_PlayerRecLoginNotifyList: recDataList = playerRecMgr.GetPlayerRecDataList(recType, playerID) if not recDataList: continue SyncPlayerRecInfo(curPlayer, recType, recDataList) return def MapServer_AddPlayerRec(curPlayer, recType, valueList, userData="", notifyType=0): ''' @todo: Ìí¼ÓÍæ¼Ò¼Ç¼ @param recType: ͨÓüǼÀàÐÍ, ¶ÔÓ¦ ShareDefine.Def_PlayerRecTypeList @param valueList: ÊýÖµÁбí[value1, value2, ...], °´Ë³Ðò, Ö§³Övalue1 ~ value8 @param userData: ×Ô¶¨Òå×Ö·ûÐÅÏ¢ @param notifyType: 0-²»Í¨Öª; 1-֪ͨµ¥Ìõ; 2-֪ͨȫ²¿ ''' playerID = curPlayer.GetPlayerID() if recType not in ShareDefine.Def_PlayerRecTypeList: GameWorld.ErrLog("Íæ¼Ò¼Ç¼ÀàÐÍ´íÎó: recType=%s" % recType, playerID) return playerRecMgr = PyDataManager.GetDBPlayerRecDataManager() recDataList = playerRecMgr.GetPlayerRecDataList(recType, playerID) if recDataList and len(recDataList) >= ChConfig.Def_PlayerRecCountDict.get(recType, 50): playerRecMgr.SortRecDataList(recDataList) recDataList.pop(0) # ɾ³ýµÚÒ»¸ö recData = playerRecMgr.AddPlayerRecData(recType, playerID) for num, value in enumerate(valueList, 1): if num > 8: break getattr(recData, "SetValue%s" % num)(min(ChConfig.Def_UpperLimit_DWord, value)) if userData: recData.SetUserData(userData) if notifyType == 1: SyncPlayerRecInfo(curPlayer, recType, [recData]) elif notifyType == 2: SyncPlayerRecInfo(curPlayer, recType, recDataList) return recData def SyncPlayerRecInfo(curPlayer, recType, recDataList): if not recDataList: return playerRecList = [] for recData in recDataList: if not recData: continue rec = ChPyNetSendPack.tagGCPlayerRec() rec.Time = recData.GetTime() rec.Value1 = recData.GetValue1() rec.Value2 = recData.GetValue2() rec.Value3 = recData.GetValue3() rec.Value4 = recData.GetValue4() rec.Value5 = recData.GetValue5() rec.Value6 = recData.GetValue6() rec.Value7 = recData.GetValue7() rec.Value8 = recData.GetValue8() rec.UserData = recData.GetUserData() rec.UserDataLen = len(rec.UserData) playerRecList.append(rec) clientPack = ChPyNetSendPack.tagGCPlayerRecInfo() clientPack.Clear() clientPack.Type = recType clientPack.PlayerRecList = playerRecList clientPack.Count = len(clientPack.PlayerRecList) NetPackCommon.SendFakePack(curPlayer, clientPack) return