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