#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package DB.StructData.DBMail
|
#
|
# @todo:DBÓʼþ
|
# @author hxp
|
# @date 2025-05-14
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: DBÓʼþ
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2025-05-14 12:00"""
|
#-------------------------------------------------------------------------------
|
|
import DBStruct
|
import CommFunc
|
import ShareDefine
|
import GameWorld
|
|
class MailItem():
|
## ÓʼþÎïÆ· - ¸öÈË¡¢È«·þÓʼþͨÓÃ
|
|
def __init__(self, dbData=None):
|
self.__dbData = DBStruct.tagDBMailItem() if not dbData else dbData
|
return
|
|
def GetGUID(self): return self.__dbData.GUID
|
def GetItemID(self): return self.__dbData.ItemID
|
def GetCount(self): return self.__dbData.Count
|
def GetIsBind(self): return self.__dbData.IsBind
|
def GetUserData(self): return self.__dbData.UserData
|
def GetBuffer(self): return self.__dbData.getBuffer()
|
|
class ServerMail():
|
## È«·þÓʼþ
|
|
def __init__(self, dbData=None):
|
self.__dbData = DBStruct.tagDBMailServer() if not dbData else dbData
|
return
|
|
def GetGUID(self): return self.__dbData.GUID
|
def GetType(self): return self.__dbData.Type
|
def GetCreateTime(self): return self.__dbData.CreateTime
|
def GetLimitDays(self): return self.__dbData.LimitDays
|
def GetTitle(self): return self.__dbData.Title
|
def GetText(self): return self.__dbData.Text
|
def GetLimitLV(self): return self.__dbData.LimitLV # ÏÞÖÆ¿ÉÁìµÄ×îµÍÍæ¼ÒµÈ¼¶
|
def SetLimitLV(self, limitLV): self.__dbData.LimitLV = limitLV
|
def GetLimitLVType(self): return self.__dbData.LimitLVType # Éý¼¶´ïµ½µÈ¼¶Ìõ¼þºóÊÇ·ñ¿ÉÁ죻0-²»¿É£¬1-¿ÉÒÔ
|
def SetLimitLVType(self, limitLVType): self.__dbData.LimitLVType = limitLVType
|
def GetCheckState(self): return self.__dbData.CheckState # ÐèÒªÉóºË״̬£º0-ÒÑÉóºË£»1-δÉóºË
|
def SetCheckState(self, checkState): self.__dbData.CheckState = checkState
|
def GetBuffer(self): return self.__dbData.getBuffer()
|
|
class PersonalMail():
|
## ¸öÈËÓʼþ
|
|
def __init__(self, dbData=None):
|
self.__dbData = DBStruct.tagDBMailPersonal() if not dbData else dbData
|
return
|
|
def GetPlayerID(self): return self.__dbData.PlayerID
|
def GetGUID(self): return self.__dbData.GUID
|
def GetType(self): return self.__dbData.Type
|
def GetCreateTime(self): return self.__dbData.CreateTime
|
def GetLimitDays(self): return self.__dbData.LimitDays
|
def GetTitle(self): return self.__dbData.Title
|
def GetText(self): return self.__dbData.Text
|
def GetMailState(self): return self.__dbData.MailState
|
def SetMailState(self, mailState): self.__dbData.MailState = mailState
|
def GetBuffer(self): return self.__dbData.getBuffer()
|
|
class MailMgr():
|
|
def __init__(self):
|
self.__personalMailDict = {} # ¸öÈËÓʼþ {playerID:{GUID:PersonalMail, ...}, ...}
|
self.__mailItemDict = {} # ÓʼþÎïÆ· {GUID:[MailItem, ...], ...}
|
self.__serverMailDict = {} # È«·þÓʼþ {GUID:ServerMail, ...}
|
self.__serverMailPlayerStateDict = {} # È«·þÓʼþÍæ¼Ò״̬ {GUID:{playerID:mailState, ...}, ...}
|
return
|
|
def __InitPersonalMailInstance(self, dbData):
|
'''³õʼ»¯¹¦ÄÜÊý¾ÝʵÀý£¬´´½¨»ò¼ÓÔØÊý¾ÝʱͨÓ㬹¦ÄÜÒ»°ã²»µ÷ÓÃ
|
@param dbData: ʵÀý¶ÔÓ¦°ó¶¨µÄdbData
|
@return: ³É¹¦·µ»ØÊµÀý¶ÔÏó£¬Ê§°Ü·µ»ØNone
|
'''
|
mailObj = PersonalMail(dbData)
|
playerID = mailObj.GetPlayerID()
|
if playerID not in self.__personalMailDict:
|
self.__personalMailDict[playerID] = {}
|
mailDict = self.__personalMailDict[playerID]
|
mailDict[mailObj.GetGUID()] = mailObj
|
return mailObj
|
|
def __InitServerMailInstance(self, dbData):
|
'''³õʼ»¯¹¦ÄÜÊý¾ÝʵÀý£¬´´½¨»ò¼ÓÔØÊý¾ÝʱͨÓ㬹¦ÄÜÒ»°ã²»µ÷ÓÃ
|
@param dbData: ʵÀý¶ÔÓ¦°ó¶¨µÄdbData
|
@return: ³É¹¦·µ»ØÊµÀý¶ÔÏó£¬Ê§°Ü·µ»ØNone
|
'''
|
mailObj = ServerMail(dbData)
|
guid = mailObj.GetGUID()
|
self.__serverMailDict[guid] = mailObj
|
return mailObj
|
|
def __InitMailItemInstance(self, dbData):
|
'''³õʼ»¯¹¦ÄÜÊý¾ÝʵÀý£¬´´½¨»ò¼ÓÔØÊý¾ÝʱͨÓ㬹¦ÄÜÒ»°ã²»µ÷ÓÃ
|
@param dbData: ʵÀý¶ÔÓ¦°ó¶¨µÄdbData
|
@return: ³É¹¦·µ»ØÊµÀý¶ÔÏó£¬Ê§°Ü·µ»ØNone
|
'''
|
mailItem = MailItem(dbData)
|
guid = mailItem.GetGUID()
|
if guid not in self.__mailItemDict:
|
self.__mailItemDict[guid] = []
|
mailItemList = self.__mailItemDict[guid]
|
mailItemList.append(mailItem)
|
return mailItem
|
|
def __AddMailItem(self, guid, itemList):
|
'''Ìí¼ÓÓʼþÎïÆ·£¬È«·þ¡¢¸öÈËÓʼþͨÓã¬ÓʼþÎïÆ·Ö»¹ØÁªguid£¬¹¦ÄÜʹÓò㼶µ¥·âÓʼþÎïÆ·ÉÏÏÞ²»ÏÞ£¬µ«ÊÇÓʼþϵͳµ¥·âÓÐÄÚÖÃÉÏÏÞ
|
@param itemList: ÔªËØÖ§³Ö×Öµä{k:v, ...} »òÁбí [itemID, itemCount, ¿ÉÑ¡ÊÇ·ñÅÄÆ·, ÎïÆ·UserData]
|
'''
|
if not itemList:
|
return
|
self.__mailItemDict.pop(guid, None) # ·ÀÖ¹ÖØ¸´Ìí¼ÓÓʼþÎïÆ·£¬ÏÈÒÆ³ý
|
|
# ¼ì²éÕûºÏºÏ²¢ÎïÆ·£¬²¢È·±£ÎïÆ·Ë³Ðò
|
itemRankList = []
|
itemDict = {}
|
for itemInfo in itemList:
|
if isinstance(itemInfo, dict):
|
itemID = itemInfo.get("ItemID", 0)
|
itemCount = itemInfo.get("Count", 0)
|
isBind = itemInfo.get("IsBind", 0)
|
userData = itemInfo.get("UserData", "")
|
elif (isinstance(itemInfo, list) or isinstance(itemInfo, tuple)) and len(itemInfo) >= 2:
|
itemID, itemCount = itemInfo[:2]
|
isBind = itemInfo[2] if len(itemInfo) > 2 else 0
|
userData = itemInfo[3] if len(itemInfo) > 3 else ""
|
else:
|
continue
|
itemID = min(GameWorld.ToIntDef(itemID, 0), ShareDefine.Def_UpperLimit_DWord)
|
itemCount = min(GameWorld.ToIntDef(itemCount, 0), ShareDefine.Def_UpperLimit_DWord)
|
isBind = 1 if isBind else 0
|
if not itemID or not itemCount:
|
continue
|
|
if userData:
|
itemRankList.append([itemID, itemCount, isBind, userData])
|
else:
|
key = (itemID, isBind)
|
if key not in itemDict:
|
itemDict[key] = 0
|
itemRankList.append(key)
|
itemDict[key] = itemDict[key] + itemCount
|
|
giveItemList = []
|
for itemInfo in itemRankList:
|
if len(itemInfo) == 4:
|
itemID, itemCount, isBind, userData = itemInfo
|
else:
|
userData = ""
|
itemID, isBind = itemInfo
|
itemCount = itemDict.get(itemInfo, 0)
|
giveItemList.append([itemID, itemCount, isBind, userData])
|
|
Max_MailItem = 20
|
if len(giveItemList) > Max_MailItem:
|
GameWorld.SendGameErrorEx("MailItemMultiError", "%s|%s|%s|%s" % (guid, len(giveItemList), itemList, giveItemList))
|
#giveItemList = giveItemList[:Max_MailItem] ÔÝʱ»¹ÊÇÈ÷¢£¬ÏÈ×öϺǫ́Óʼþ¾¯¸æ¼´¿É
|
|
for itemID, itemCount, isBind, userData in giveItemList:
|
dbData = DBStruct.tagDBMailItem()
|
dbData.GUID = guid
|
dbData.ItemID = itemID
|
dbData.Count = itemCount
|
dbData.IsBind = isBind
|
dbData.UserData = userData
|
dbData.UserDataLen = len(dbData.UserData)
|
self.__InitMailItemInstance(dbData)
|
|
return
|
|
def AddPersonalMail(self, playerID, title, text, itemList, limitDays=7, mailType=0):
|
'''Ìí¼Ó¸öÈËÓʼþ
|
@param itemList: ÔªËØÖ§³Ö×Öµä{k:v, ...} »òÁбí [itemID, itemCount, ¿ÉÑ¡ÊÇ·ñÅÄÆ·, ÎïÆ·UserData]
|
'''
|
guid = GameWorld.GetGUID()
|
dbData = DBStruct.tagDBMailPersonal()
|
dbData.PlayerID = playerID
|
dbData.GUID = guid
|
dbData.Type = mailType
|
dbData.CreateTime = GameWorld.GetCurrentDataTimeStr()
|
dbData.LimitDays = limitDays
|
dbData.Title = title
|
dbData.TitleLen = len(dbData.Title)
|
dbData.Text = text
|
dbData.TextLen = len(dbData.Text)
|
dbData.MailState = ShareDefine.MailState_UnRead # ¸öÈËÓʼþĬÈÏδ¶Á
|
self.__AddMailItem(guid, itemList)
|
mailObj = self.__InitPersonalMailInstance(dbData)
|
return mailObj
|
|
def GetAllPersonalMailDict(self): return self.__personalMailDict
|
|
def GetPersonalMailCount(self, playerID):
|
## »ñÈ¡Íæ¼Ò¸öÈËÓʼþ×ÜÊý
|
if playerID not in self.__personalMailDict:
|
return 0
|
return len(self.__personalMailDict[playerID])
|
|
def GetPersonalMailGuids(self, playerID):
|
## »ñÈ¡Íæ¼ÒËùÓиöÈËÓʼþguidÁбí
|
if playerID not in self.__personalMailDict:
|
return []
|
mailDict = self.__personalMailDict[playerID]
|
return mailDict.keys()
|
|
def GetPersonalMails(self, playerID):
|
## »ñÈ¡Íæ¼ÒËùÓиöÈËÓʼþʵÀýÁбí
|
if playerID not in self.__personalMailDict:
|
return []
|
mailDict = self.__personalMailDict[playerID]
|
return mailDict.values()
|
|
def GetPersonalMail(self, playerID, guid):
|
## »ñÈ¡Íæ¼Ò¸öÈËÓʼþ
|
mailObj = None
|
if playerID not in self.__personalMailDict:
|
self.__personalMailDict[playerID] = {}
|
mailDict = self.__personalMailDict[playerID]
|
if guid in mailDict:
|
mailObj = mailDict[guid]
|
elif False:
|
mailObj = PersonalMail()
|
return mailObj
|
|
def GetMailItemCount(self, guid):
|
## »ñÈ¡ÓʼþÎïÆ·¸öÊý£¬È«·þÓʼþ¡¢¸öÈËÓʼþͨÓÃ
|
if guid not in self.__mailItemDict:
|
return 0
|
return len(self.__mailItemDict[guid])
|
|
def GetMailItemAt(self, guid, index):
|
## »ñÈ¡Óʼþij¸öÎïÆ·
|
itemObj = None
|
if guid in self.__mailItemDict:
|
itemObjList = self.__mailItemDict[guid]
|
if 0 <= index < len(itemObjList):
|
itemObj = itemObjList[index]
|
if not itemObj and False:
|
itemObj = MailItem()
|
return itemObj
|
|
def AddServerMail(self, guid, title, text, itemList, limitDays=7, mailType=0):
|
'''Ìí¼Ó¸öÈËÓʼþ
|
@param guid: Ö¸¶¨µÄÓʼþguid£¬Îª¿Õʱ×Ô¶¯Éú³ÉÐÂguid
|
@param itemList: ÔªËØÖ§³Ö×Öµä{k:v, ...} »òÁбí [itemID, itemCount, ¿ÉÑ¡ÊÇ·ñÅÄÆ·, ÎïÆ·UserData]
|
'''
|
if not guid:
|
guid = GameWorld.GetGUID()
|
dbData = DBStruct.tagDBMailServer()
|
dbData.GUID = guid
|
dbData.Type = mailType
|
dbData.CreateTime = GameWorld.GetCurrentDataTimeStr()
|
dbData.LimitDays = limitDays
|
dbData.Title = title
|
dbData.TitleLen = len(dbData.Title)
|
dbData.Text = text
|
dbData.TextLen = len(dbData.Text)
|
self.__AddMailItem(guid, itemList)
|
mailObj = self.__InitServerMailInstance(dbData)
|
return mailObj
|
|
def GetServerMail(self, guid):
|
## »ñȡȫ·þÓʼþ
|
mailObj = None
|
if guid in self.__serverMailDict:
|
mailObj = self.__serverMailDict[guid]
|
elif False:
|
mailObj = ServerMail()
|
return mailObj
|
|
def GetServerMailGuids(self):
|
## »ñÈ¡ËùÓÐÈ«·þÓʼþguidÁбí
|
return self.__serverMailDict.keys()
|
|
def GetPlayerMailState(self, guid, playerID):
|
## »ñÈ¡Íæ¼Òij¸öÓʼþ״̬£¬¸öÈË¡¢È«·þÓʼþͨÓÃ
|
personalMail = self.GetPersonalMail(playerID, guid)
|
if personalMail:
|
return personalMail.GetMailState()
|
if guid not in self.__serverMailPlayerStateDict:
|
return ShareDefine.MailState_Unknown
|
playerStateDict = self.__serverMailPlayerStateDict[guid]
|
if playerID not in playerStateDict:
|
return ShareDefine.MailState_Unknown
|
return playerStateDict[playerID]
|
|
def SetPlayerMailState(self, guid, playerID, mailState):
|
## ÉèÖÃÍæ¼Òij¸öÓʼþ״̬£¬¸öÈË¡¢È«·þÓʼþͨÓÃ
|
# @return: ·µ»ØÉèÖõÄÓʼþ״̬
|
personalMail = self.GetPersonalMail(playerID, guid)
|
if personalMail:
|
if mailState >= ShareDefine.MailState_Del:
|
self.DelPersonalMail(playerID, guid)
|
return ShareDefine.MailState_Del
|
personalMail.SetMailState(mailState)
|
return mailState
|
if guid not in self.__serverMailPlayerStateDict:
|
self.__serverMailPlayerStateDict[guid] = {}
|
playerStateDict = self.__serverMailPlayerStateDict[guid]
|
playerStateDict[playerID] = mailState
|
return mailState
|
|
def DelPersonalMail(self, playerID, guid):
|
## ɾ³ý¸öÈËÓʼþ
|
self.__mailItemDict.pop(guid, None)
|
if playerID in self.__personalMailDict:
|
mailDict = self.__personalMailDict[playerID]
|
mailDict.pop(guid, None)
|
return
|
|
def DelServerMail(self, guid):
|
## ɾ³ýij¸öÈ«·þÓʼþ
|
self.__mailItemDict.pop(guid, None)
|
self.__serverMailDict.pop(guid, None)
|
playerStateDict = self.__serverMailPlayerStateDict.pop(guid, {})
|
return playerStateDict
|
|
def DelAllMail(self):
|
self.__personalMailDict = {}
|
self.__mailItemDict = {}
|
self.__serverMailDict = {}
|
self.__serverMailPlayerStateDict = {}
|
return
|
|
# ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup
|
def GetSaveData(self):
|
saveData = ""
|
|
# È«·þÓʼþ
|
serverMailCnt, serverMailSavaData = 0, ""
|
for mailObj in self.__serverMailDict.values():
|
serverMailCnt += 1
|
serverMailSavaData += mailObj.GetBuffer()
|
saveData += CommFunc.WriteDWORD("", serverMailCnt) + serverMailSavaData
|
GameWorld.Log("Save DBMailServer count :%s len=%s" % (serverMailCnt, len(serverMailSavaData)))
|
|
# È«·þÓʼþÍæ¼Ò״̬
|
dbData = DBStruct.tagDBMailPlayerRec()
|
playerStateCnt, playerStateSaveData = 0, ""
|
for guid, playerStateDict in self.__serverMailPlayerStateDict.items():
|
for playerID, mailState in playerStateDict.items():
|
dbData.clear()
|
dbData.GUID = guid
|
dbData.PlayerID = playerID
|
dbData.MailState = mailState
|
playerStateCnt += 1
|
playerStateSaveData += dbData.getBuffer()
|
saveData += CommFunc.WriteDWORD("", playerStateCnt) + playerStateSaveData
|
GameWorld.Log("Save DBMailPlayerRec count :%s len=%s" % (playerStateCnt, len(playerStateSaveData)))
|
|
# ¸öÈËÓʼþ
|
personalMailCnt, personalMailSavaData = 0, ""
|
for mailDict in self.__personalMailDict.values():
|
for mailObj in mailDict.values():
|
personalMailCnt += 1
|
personalMailSavaData += mailObj.GetBuffer()
|
saveData += CommFunc.WriteDWORD("", personalMailCnt) + personalMailSavaData
|
GameWorld.Log("Save DBMailPersonal count :%s len=%s" % (personalMailCnt, len(personalMailSavaData)))
|
|
# ÓʼþÎïÆ·
|
mailItemCnt, mailItemSavaData = 0, ""
|
for itemList in self.__mailItemDict.values():
|
for itemObj in itemList:
|
mailItemCnt += 1
|
mailItemSavaData += itemObj.GetBuffer()
|
saveData += CommFunc.WriteDWORD("", mailItemCnt) + mailItemSavaData
|
GameWorld.Log("Save DBMailItem count :%s len=%s" % (mailItemCnt, len(mailItemSavaData)))
|
|
return saveData
|
|
# ´ÓÊý¾Ý¿âÔØÈëÊý¾Ý
|
def LoadPyGameData(self, datas, pos, dataslen):
|
if pos >= dataslen:
|
return
|
|
# È«·þÓʼþ
|
cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
GameWorld.Log("Load DBMailServer count :%s" % cnt)
|
for _ in xrange(cnt):
|
dbData = DBStruct.tagDBMailServer()
|
pos += dbData.readData(datas, pos, dataslen)
|
self.__InitServerMailInstance(dbData)
|
|
# È«·þÓʼþÍæ¼Ò״̬
|
cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
GameWorld.Log("Load DBMailPlayerRec count :%s" % cnt)
|
dbData = DBStruct.tagDBMailPlayerRec()
|
for _ in xrange(cnt):
|
dbData.clear()
|
pos += dbData.readData(datas, pos, dataslen)
|
self.SetPlayerMailState(dbData.GUID, dbData.PlayerID, dbData.MailState)
|
|
# ¸öÈËÓʼþ
|
cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
GameWorld.Log("Load DBMailPersonal count :%s" % cnt)
|
for _ in xrange(cnt):
|
dbData = DBStruct.tagDBMailPersonal()
|
pos += dbData.readData(datas, pos, dataslen)
|
self.__InitPersonalMailInstance(dbData)
|
|
# ÓʼþÎïÆ·
|
cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
GameWorld.Log("Load DBMailItem count :%s" % cnt)
|
for _ in xrange(cnt):
|
dbData = DBStruct.tagDBMailItem()
|
pos += dbData.readData(datas, pos, dataslen)
|
self.__InitMailItemInstance(dbData)
|
|
return pos
|
|
|