| | |
| | | PacketSubCMD_6=0x08
|
| | | PacketCallFunc_6=OnItemTimeout
|
| | |
|
| | | ;邮件
|
| | | [PlayerMail]
|
| | | ScriptName = Player\PlayerMail.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 1
|
| | |
|
| | | PacketCMD_1=0xA5
|
| | | PacketSubCMD_1=0x37
|
| | | PacketCallFunc_1=OnRequestMail
|
| | |
|
| | | ;法器
|
| | | [PlayerFaQi]
|
| | | ScriptName = Player\PlayerFaQi.py
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A5 37 请求邮件操作 #tagCMRequestMail
|
| | |
|
| | | class tagCMRequestMail(Structure):
|
| | | Head = tagHead()
|
| | | GUID = "" #(char GUID[36])//邮件GUID,可传空,默认针对个人邮件的批量处理,如批量领取、批量删除已领邮件等;全服邮件暂时限制只能单封邮件处理
|
| | | ReqType = 0 #(BYTE ReqType)//0-设置已读,1-领取邮件,2-删除邮件
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xA5
|
| | | self.Head.SubCmd = 0x37
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.GUID,_pos = CommFunc.ReadString(_lpData, _pos,36)
|
| | | self.ReqType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xA5
|
| | | self.Head.SubCmd = 0x37
|
| | | self.GUID = ""
|
| | | self.ReqType = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 36
|
| | | length += 1
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteString(data, 36, self.GUID)
|
| | | data = CommFunc.WriteBYTE(data, self.ReqType)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | GUID:%s,
|
| | | ReqType:%d
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.GUID,
|
| | | self.ReqType
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMRequestMail=tagCMRequestMail()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMRequestMail.Head.Cmd,m_NAtagCMRequestMail.Head.SubCmd))] = m_NAtagCMRequestMail
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A5 68 请求寻宝 #tagCMRequestTreasure
|
| | |
|
| | | class tagCMRequestTreasure(Structure):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A3 62 邮件列表 #tagMCMailList
|
| | |
|
| | | class tagMCMailItem(Structure):
|
| | | ItemID = 0 #(DWORD ItemID)//物品ID
|
| | | Count = 0 #(DWORD Count)//数量
|
| | | IsBind = 0 #(BYTE IsBind)//是否绑定
|
| | | UserDataLen = 0 #(WORD UserDataLen)
|
| | | UserData = "" #(String UserData)//自定义数据 |
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.ItemID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Count,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.IsBind,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.UserDataLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.UserData,_pos = CommFunc.ReadString(_lpData, _pos,self.UserDataLen)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.ItemID = 0
|
| | | self.Count = 0
|
| | | self.IsBind = 0
|
| | | self.UserDataLen = 0
|
| | | self.UserData = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 4
|
| | | length += 4
|
| | | length += 1
|
| | | length += 2
|
| | | length += len(self.UserData)
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteDWORD(data, self.ItemID)
|
| | | data = CommFunc.WriteDWORD(data, self.Count)
|
| | | data = CommFunc.WriteBYTE(data, self.IsBind)
|
| | | data = CommFunc.WriteWORD(data, self.UserDataLen)
|
| | | data = CommFunc.WriteString(data, self.UserDataLen, self.UserData)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | ItemID:%d,
|
| | | Count:%d,
|
| | | IsBind:%d,
|
| | | UserDataLen:%d,
|
| | | UserData:%s
|
| | | '''\
|
| | | %(
|
| | | self.ItemID,
|
| | | self.Count,
|
| | | self.IsBind,
|
| | | self.UserDataLen,
|
| | | self.UserData
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCMail(Structure):
|
| | | GUID = "" #(char GUID[36])//邮件GUID
|
| | | Type = 0 #(BYTE Type)//邮件类型,暂时默认0
|
| | | CreateTime = "" #(char CreateTime[30])//创建时间
|
| | | LimitDays = 0 #(BYTE LimitDays)//有效天数
|
| | | TitleLen = 0 #(BYTE TitleLen)
|
| | | Title = "" #(String Title)//标题
|
| | | TextLen = 0 #(WORD TextLen)
|
| | | Text = "" #(String Text)//内容
|
| | | MailState = 0 #(BYTE MailState)//邮件状态: 0-未知;1-未读;2-已读;3-已领;
|
| | | Count = 0 #(BYTE Count)//物品数
|
| | | Items = list() #(vector<tagMCMailItem> Items)//物品信息
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.GUID,_pos = CommFunc.ReadString(_lpData, _pos,36)
|
| | | self.Type,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.CreateTime,_pos = CommFunc.ReadString(_lpData, _pos,30)
|
| | | self.LimitDays,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.TitleLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Title,_pos = CommFunc.ReadString(_lpData, _pos,self.TitleLen)
|
| | | self.TextLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.Text,_pos = CommFunc.ReadString(_lpData, _pos,self.TextLen)
|
| | | self.MailState,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.Count):
|
| | | temItems = tagMCMailItem()
|
| | | _pos = temItems.ReadData(_lpData, _pos)
|
| | | self.Items.append(temItems)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.GUID = ""
|
| | | self.Type = 0
|
| | | self.CreateTime = ""
|
| | | self.LimitDays = 0
|
| | | self.TitleLen = 0
|
| | | self.Title = ""
|
| | | self.TextLen = 0
|
| | | self.Text = ""
|
| | | self.MailState = 0
|
| | | self.Count = 0
|
| | | self.Items = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 36
|
| | | length += 1
|
| | | length += 30
|
| | | length += 1
|
| | | length += 1
|
| | | length += len(self.Title)
|
| | | length += 2
|
| | | length += len(self.Text)
|
| | | length += 1
|
| | | length += 1
|
| | | for i in range(self.Count):
|
| | | length += self.Items[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, 36, self.GUID)
|
| | | data = CommFunc.WriteBYTE(data, self.Type)
|
| | | data = CommFunc.WriteString(data, 30, self.CreateTime)
|
| | | data = CommFunc.WriteBYTE(data, self.LimitDays)
|
| | | data = CommFunc.WriteBYTE(data, self.TitleLen)
|
| | | data = CommFunc.WriteString(data, self.TitleLen, self.Title)
|
| | | data = CommFunc.WriteWORD(data, self.TextLen)
|
| | | data = CommFunc.WriteString(data, self.TextLen, self.Text)
|
| | | data = CommFunc.WriteBYTE(data, self.MailState)
|
| | | data = CommFunc.WriteBYTE(data, self.Count)
|
| | | for i in range(self.Count):
|
| | | data = CommFunc.WriteString(data, self.Items[i].GetLength(), self.Items[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | GUID:%s,
|
| | | Type:%d,
|
| | | CreateTime:%s,
|
| | | LimitDays:%d,
|
| | | TitleLen:%d,
|
| | | Title:%s,
|
| | | TextLen:%d,
|
| | | Text:%s,
|
| | | MailState:%d,
|
| | | Count:%d,
|
| | | Items:%s
|
| | | '''\
|
| | | %(
|
| | | self.GUID,
|
| | | self.Type,
|
| | | self.CreateTime,
|
| | | self.LimitDays,
|
| | | self.TitleLen,
|
| | | self.Title,
|
| | | self.TextLen,
|
| | | self.Text,
|
| | | self.MailState,
|
| | | self.Count,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCMailList(Structure):
|
| | | Head = tagHead()
|
| | | IsServerMail = 0 #(BYTE IsServerMail)//是否全服邮件,如公告、维护、更新、补偿等重要邮件
|
| | | Count = 0 #(WORD Count)
|
| | | MailList = list() #(vector<tagMCMail> MailList)//邮件列表
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xA3
|
| | | self.Head.SubCmd = 0x62
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.IsServerMail,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | for i in range(self.Count):
|
| | | temMailList = tagMCMail()
|
| | | _pos = temMailList.ReadData(_lpData, _pos)
|
| | | self.MailList.append(temMailList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xA3
|
| | | self.Head.SubCmd = 0x62
|
| | | self.IsServerMail = 0
|
| | | self.Count = 0
|
| | | self.MailList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 2
|
| | | for i in range(self.Count):
|
| | | length += self.MailList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.IsServerMail)
|
| | | data = CommFunc.WriteWORD(data, self.Count)
|
| | | for i in range(self.Count):
|
| | | data = CommFunc.WriteString(data, self.MailList[i].GetLength(), self.MailList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | IsServerMail:%d,
|
| | | Count:%d,
|
| | | MailList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.IsServerMail,
|
| | | self.Count,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCMailList=tagMCMailList()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCMailList.Head.Cmd,m_NAtagMCMailList.Head.SubCmd))] = m_NAtagMCMailList
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A3 63 邮件状态变更 #tagMCMailStateChange
|
| | |
|
| | | class tagMCMailState(Structure):
|
| | | GUID = "" #(char GUID[36])//邮件GUID
|
| | | MailState = 0 #(BYTE MailState)//邮件状态: 0-未知;1-未读;2-已读;3-已领;4-已删
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.GUID,_pos = CommFunc.ReadString(_lpData, _pos,36)
|
| | | self.MailState,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.GUID = ""
|
| | | self.MailState = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 36
|
| | | length += 1
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, 36, self.GUID)
|
| | | data = CommFunc.WriteBYTE(data, self.MailState)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | GUID:%s,
|
| | | MailState:%d
|
| | | '''\
|
| | | %(
|
| | | self.GUID,
|
| | | self.MailState
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCMailStateChange(Structure):
|
| | | Head = tagHead()
|
| | | Count = 0 #(WORD Count)
|
| | | MailList = list() #(vector<tagMCMailState> MailList)//邮件列表
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xA3
|
| | | self.Head.SubCmd = 0x63
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | for i in range(self.Count):
|
| | | temMailList = tagMCMailState()
|
| | | _pos = temMailList.ReadData(_lpData, _pos)
|
| | | self.MailList.append(temMailList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xA3
|
| | | self.Head.SubCmd = 0x63
|
| | | self.Count = 0
|
| | | self.MailList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 2
|
| | | for i in range(self.Count):
|
| | | length += self.MailList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteWORD(data, self.Count)
|
| | | for i in range(self.Count):
|
| | | data = CommFunc.WriteString(data, self.MailList[i].GetLength(), self.MailList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | Count:%d,
|
| | | MailList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.Count,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCMailStateChange=tagMCMailStateChange()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCMailStateChange.Head.Cmd,m_NAtagMCMailStateChange.Head.SubCmd))] = m_NAtagMCMailStateChange
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A3 46 大师经验信息 #tagMCGreatMasterExp
|
| | |
|
| | | class tagMCGreatMasterExp(Structure):
|
| | |
| | | import PyGameData
|
| | | import DBPlayerViewCache
|
| | | import DBFamily
|
| | | import DBMail
|
| | |
|
| | | import binascii
|
| | | import time
|
| | |
| | | def OnServerClose():
|
| | | return
|
| | |
|
| | | def OnMinute(curMinute):
|
| | | def OnMinute(curTime):
|
| | | curMinute = curTime.minute
|
| | | ServerDataBackup()
|
| | | DBFamily.OnMinute(curMinute)
|
| | | return
|
| | |
|
| | | def OnDayEx():
|
| | | return
|
| | |
|
| | | #------------------------------------------- 备档 ---------------------------------------------------
|
| | |
| | | def __init__(self):
|
| | | self.PlayerViewCacheMgr = DBPlayerViewCache.PlayerViewCacheMgr()
|
| | | self.FamilyMgr = DBFamily.FamilyMgr()
|
| | | self.MailMgr = DBMail.MailMgr()
|
| | | return
|
| | |
|
| | | def GetSaveData(self):
|
| | | buff = ""
|
| | | buff += self.PlayerViewCacheMgr.GetSaveData()
|
| | | buff += self.FamilyMgr.GetSaveData()
|
| | | buff += self.MailMgr.GetSaveData()
|
| | | return buff
|
| | |
|
| | | def LoadGameData(self, gameBuffer, pos):
|
| | | pos = self.PlayerViewCacheMgr.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | | pos = self.FamilyMgr.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | | dataslen = len(gameBuffer)
|
| | | pos = self.PlayerViewCacheMgr.LoadPyGameData(gameBuffer, pos, dataslen)
|
| | | pos = self.FamilyMgr.LoadPyGameData(gameBuffer, pos, dataslen)
|
| | | pos = self.MailMgr.LoadPyGameData(gameBuffer, pos, dataslen)
|
| | | return pos
|
| | |
|
| | | def GetDBDataMgr():
|
| | |
| | | ## 家族Action数据管理器
|
| | | return GetFamilyMgr().GetFamilyActionMgr()
|
| | |
|
| | | def GetMailMgr():
|
| | | ## 邮件数据管理器
|
| | | dbDataMgr = GetDBDataMgr()
|
| | | return dbDataMgr.MailMgr
|
| | |
|
| | |
| | | else:
|
| | | self.FamilyName = Str[:33]
|
| | |
|
| | |
|
| | | # 邮件个人邮件表 #tagDBMailPersonal
|
| | | class tagDBMailPersonal(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ('PlayerID', ctypes.c_ulong),
|
| | | ('GUID', ctypes.c_char * 36),
|
| | | ('Type', ctypes.c_ubyte),
|
| | | ('CreateTime', ctypes.c_char * 30),
|
| | | ('LimitDays', ctypes.c_ubyte),
|
| | | ('TitleLen', ctypes.c_ubyte),
|
| | | ('Title', ctypes.c_char_p),
|
| | | ('TextLen', ctypes.c_ushort),
|
| | | ('Text', ctypes.c_char_p),
|
| | | ('MailState', ctypes.c_ubyte),
|
| | | ('ADOResult', ctypes.c_ulong),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | Structure.__init__(self)
|
| | | self.clear()
|
| | |
|
| | | def clear(self):
|
| | | self.PlayerID = 0
|
| | | self.GUID = ''
|
| | | self.Type = 0
|
| | | self.CreateTime = ''
|
| | | self.LimitDays = 0
|
| | | self.TitleLen = 0
|
| | | self.Title = ''
|
| | | self.TextLen = 0
|
| | | self.Text = ''
|
| | | self.MailState = 0
|
| | |
|
| | | def readData(self, buf, pos = 0, length = 0):
|
| | | if not pos <= length:
|
| | | return -1
|
| | | if len(buf) < pos + self.getLength():
|
| | | return -1
|
| | | self.clear()
|
| | | self.PlayerID, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.GUID, pos = CommFunc.ReadString(buf, pos, 36)
|
| | | self.Type, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | self.CreateTime, pos = CommFunc.ReadString(buf, pos, 30)
|
| | | self.LimitDays, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | self.TitleLen, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.TitleLen)
|
| | | self.Title = ctypes.c_char_p(tmp)
|
| | | self.TextLen, pos = CommFunc.ReadWORD(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.TextLen)
|
| | | self.Text = ctypes.c_char_p(tmp)
|
| | | self.MailState, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | return self.getLength()
|
| | |
|
| | | def getBuffer(self):
|
| | | buf = ''
|
| | | buf = CommFunc.WriteDWORD(buf, self.PlayerID)
|
| | | buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 36, self.GUID)
|
| | | buf = CommFunc.WriteBYTE(buf, self.Type)
|
| | | buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 30, self.CreateTime)
|
| | | buf = CommFunc.WriteBYTE(buf, self.LimitDays)
|
| | | buf = CommFunc.WriteBYTE(buf, self.TitleLen)
|
| | | buf = CommFunc.WriteString(buf, self.TitleLen, self.Title)
|
| | | buf = CommFunc.WriteWORD(buf, self.TextLen)
|
| | | buf = CommFunc.WriteString(buf, self.TextLen, self.Text)
|
| | | buf = CommFunc.WriteBYTE(buf, self.MailState)
|
| | | return buf
|
| | |
|
| | | def getLength(self):
|
| | | length = 0
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_char) * 36
|
| | | length += sizeof(ctypes.c_ubyte)
|
| | | length += sizeof(ctypes.c_char) * 30
|
| | | length += sizeof(ctypes.c_ubyte)
|
| | | length += sizeof(ctypes.c_ubyte)
|
| | | length += self.TitleLen
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | length += self.TextLen
|
| | | length += sizeof(ctypes.c_ubyte)
|
| | | return length
|
| | |
|
| | | def outputString(self):
|
| | | output = '''// 邮件个人邮件表 #tagDBMailPersonal:
|
| | | PlayerID = %s,
|
| | | GUID = %s,
|
| | | Type = %s,
|
| | | CreateTime = %s,
|
| | | LimitDays = %s,
|
| | | TitleLen = %s,
|
| | | Title = %s,
|
| | | TextLen = %s,
|
| | | Text = %s,
|
| | | MailState = %s,
|
| | | ADOResult = %s,
|
| | | '''%(
|
| | | self.PlayerID,
|
| | | self.GUID,
|
| | | self.Type,
|
| | | self.CreateTime,
|
| | | self.LimitDays,
|
| | | self.TitleLen,
|
| | | self.Title,
|
| | | self.TextLen,
|
| | | self.Text,
|
| | | self.MailState,
|
| | | self.ADOResult,
|
| | | )
|
| | | return output
|
| | |
|
| | | #Char数组类型Set接口,使用该接口对此类型数据赋值,防止赋值的数据过长报错
|
| | | def SetGUID(self,Str):
|
| | | if len(Str)<=36:
|
| | | self.GUID = Str
|
| | | else:
|
| | | self.GUID = Str[:36]
|
| | | |
| | | def SetCreateTime(self,Str):
|
| | | if len(Str)<=30:
|
| | | self.CreateTime = Str
|
| | | else:
|
| | | self.CreateTime = Str[:30]
|
| | | |
| | |
|
| | | # 邮件全服邮件表 #tagDBMailServer
|
| | | class tagDBMailServer(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ('GUID', ctypes.c_char * 36),
|
| | | ('Type', ctypes.c_ubyte),
|
| | | ('CreateTime', ctypes.c_char * 30),
|
| | | ('LimitDays', ctypes.c_ubyte),
|
| | | ('TitleLen', ctypes.c_ubyte),
|
| | | ('Title', ctypes.c_char_p),
|
| | | ('TextLen', ctypes.c_ushort),
|
| | | ('Text', ctypes.c_char_p),
|
| | | ('LimitLV', ctypes.c_ushort),
|
| | | ('LimitLVType', ctypes.c_ubyte),
|
| | | ('CheckState', ctypes.c_ubyte),
|
| | | ('ADOResult', ctypes.c_ulong),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | Structure.__init__(self)
|
| | | self.clear()
|
| | |
|
| | | def clear(self):
|
| | | self.GUID = ''
|
| | | self.Type = 0
|
| | | self.CreateTime = ''
|
| | | self.LimitDays = 0
|
| | | self.TitleLen = 0
|
| | | self.Title = ''
|
| | | self.TextLen = 0
|
| | | self.Text = ''
|
| | | self.LimitLV = 0
|
| | | self.LimitLVType = 0
|
| | | self.CheckState = 0
|
| | |
|
| | | def readData(self, buf, pos = 0, length = 0):
|
| | | if not pos <= length:
|
| | | return -1
|
| | | if len(buf) < pos + self.getLength():
|
| | | return -1
|
| | | self.clear()
|
| | | self.GUID, pos = CommFunc.ReadString(buf, pos, 36)
|
| | | self.Type, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | self.CreateTime, pos = CommFunc.ReadString(buf, pos, 30)
|
| | | self.LimitDays, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | self.TitleLen, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.TitleLen)
|
| | | self.Title = ctypes.c_char_p(tmp)
|
| | | self.TextLen, pos = CommFunc.ReadWORD(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.TextLen)
|
| | | self.Text = ctypes.c_char_p(tmp)
|
| | | self.LimitLV, pos = CommFunc.ReadWORD(buf, pos)
|
| | | self.LimitLVType, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | self.CheckState, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | return self.getLength()
|
| | |
|
| | | def getBuffer(self):
|
| | | buf = ''
|
| | | buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 36, self.GUID)
|
| | | buf = CommFunc.WriteBYTE(buf, self.Type)
|
| | | buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 30, self.CreateTime)
|
| | | buf = CommFunc.WriteBYTE(buf, self.LimitDays)
|
| | | buf = CommFunc.WriteBYTE(buf, self.TitleLen)
|
| | | buf = CommFunc.WriteString(buf, self.TitleLen, self.Title)
|
| | | buf = CommFunc.WriteWORD(buf, self.TextLen)
|
| | | buf = CommFunc.WriteString(buf, self.TextLen, self.Text)
|
| | | buf = CommFunc.WriteWORD(buf, self.LimitLV)
|
| | | buf = CommFunc.WriteBYTE(buf, self.LimitLVType)
|
| | | buf = CommFunc.WriteBYTE(buf, self.CheckState)
|
| | | return buf
|
| | |
|
| | | def getLength(self):
|
| | | length = 0
|
| | | length += sizeof(ctypes.c_char) * 36
|
| | | length += sizeof(ctypes.c_ubyte)
|
| | | length += sizeof(ctypes.c_char) * 30
|
| | | length += sizeof(ctypes.c_ubyte)
|
| | | length += sizeof(ctypes.c_ubyte)
|
| | | length += self.TitleLen
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | length += self.TextLen
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | length += sizeof(ctypes.c_ubyte)
|
| | | length += sizeof(ctypes.c_ubyte)
|
| | | return length
|
| | |
|
| | | def outputString(self):
|
| | | output = '''// 邮件全服邮件表 #tagDBMailServer:
|
| | | GUID = %s,
|
| | | Type = %s,
|
| | | CreateTime = %s,
|
| | | LimitDays = %s,
|
| | | TitleLen = %s,
|
| | | Title = %s,
|
| | | TextLen = %s,
|
| | | Text = %s,
|
| | | LimitLV = %s,
|
| | | LimitLVType = %s,
|
| | | CheckState = %s,
|
| | | ADOResult = %s,
|
| | | '''%(
|
| | | self.GUID,
|
| | | self.Type,
|
| | | self.CreateTime,
|
| | | self.LimitDays,
|
| | | self.TitleLen,
|
| | | self.Title,
|
| | | self.TextLen,
|
| | | self.Text,
|
| | | self.LimitLV,
|
| | | self.LimitLVType,
|
| | | self.CheckState,
|
| | | self.ADOResult,
|
| | | )
|
| | | return output
|
| | |
|
| | | #Char数组类型Set接口,使用该接口对此类型数据赋值,防止赋值的数据过长报错
|
| | | def SetGUID(self,Str):
|
| | | if len(Str)<=36:
|
| | | self.GUID = Str
|
| | | else:
|
| | | self.GUID = Str[:36]
|
| | | |
| | | def SetCreateTime(self,Str):
|
| | | if len(Str)<=30:
|
| | | self.CreateTime = Str
|
| | | else:
|
| | | self.CreateTime = Str[:30]
|
| | | |
| | | |
| | |
|
| | | # 邮件物品表 #tagDBMailItem
|
| | | class tagDBMailItem(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ('GUID', ctypes.c_char * 36),
|
| | | ('ItemID', ctypes.c_ulong),
|
| | | ('Count', ctypes.c_ulong),
|
| | | ('IsBind', ctypes.c_ubyte),
|
| | | ('UserDataLen', ctypes.c_ushort),
|
| | | ('UserData', ctypes.c_char_p),
|
| | | ('ADOResult', ctypes.c_ulong),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | Structure.__init__(self)
|
| | | self.clear()
|
| | |
|
| | | def clear(self):
|
| | | self.GUID = ''
|
| | | self.ItemID = 0
|
| | | self.Count = 0
|
| | | self.IsBind = 0
|
| | | self.UserDataLen = 0
|
| | | self.UserData = ''
|
| | |
|
| | | def readData(self, buf, pos = 0, length = 0):
|
| | | if not pos <= length:
|
| | | return -1
|
| | | if len(buf) < pos + self.getLength():
|
| | | return -1
|
| | | self.clear()
|
| | | self.GUID, pos = CommFunc.ReadString(buf, pos, 36)
|
| | | self.ItemID, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Count, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.IsBind, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | self.UserDataLen, pos = CommFunc.ReadWORD(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.UserDataLen)
|
| | | self.UserData = ctypes.c_char_p(tmp)
|
| | | return self.getLength()
|
| | |
|
| | | def getBuffer(self):
|
| | | buf = ''
|
| | | buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 36, self.GUID)
|
| | | buf = CommFunc.WriteDWORD(buf, self.ItemID)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Count)
|
| | | buf = CommFunc.WriteBYTE(buf, self.IsBind)
|
| | | buf = CommFunc.WriteWORD(buf, self.UserDataLen)
|
| | | buf = CommFunc.WriteString(buf, self.UserDataLen, self.UserData)
|
| | | return buf
|
| | |
|
| | | def getLength(self):
|
| | | length = 0
|
| | | length += sizeof(ctypes.c_char) * 36
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ubyte)
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | length += self.UserDataLen
|
| | | return length
|
| | |
|
| | | def outputString(self):
|
| | | output = '''// 邮件物品表 #tagDBMailItem:
|
| | | GUID = %s,
|
| | | ItemID = %s,
|
| | | Count = %s,
|
| | | IsBind = %s,
|
| | | UserDataLen = %s,
|
| | | UserData = %s,
|
| | | ADOResult = %s,
|
| | | '''%(
|
| | | self.GUID,
|
| | | self.ItemID,
|
| | | self.Count,
|
| | | self.IsBind,
|
| | | self.UserDataLen,
|
| | | self.UserData,
|
| | | self.ADOResult,
|
| | | )
|
| | | return output
|
| | |
|
| | | #Char数组类型Set接口,使用该接口对此类型数据赋值,防止赋值的数据过长报错
|
| | | def SetGUID(self,Str):
|
| | | if len(Str)<=36:
|
| | | self.GUID = Str
|
| | | else:
|
| | | self.GUID = Str[:36]
|
| | | |
| | |
|
| | | # 邮件全服记录表 #tagDBMailPlayerRec
|
| | | class tagDBMailPlayerRec(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ('PlayerID', ctypes.c_ulong),
|
| | | ('GUID', ctypes.c_char * 36),
|
| | | ('MailState', ctypes.c_ubyte),
|
| | | ('ADOResult', ctypes.c_ulong),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | Structure.__init__(self)
|
| | | self.clear()
|
| | |
|
| | |
|
| | | def clear(self):
|
| | | memset(addressof(self), 0, self.getLength())
|
| | |
|
| | | def readData(self, buf, pos = 0, length = 0):
|
| | | if not pos <= length:
|
| | | return -1
|
| | | if len(buf) < pos + self.getLength():
|
| | | return -1
|
| | | self.clear()
|
| | | self.PlayerID, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.GUID, pos = CommFunc.ReadString(buf, pos, 36)
|
| | | self.MailState, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | return self.getLength()
|
| | |
|
| | |
|
| | | def getBuffer(self):
|
| | | buf = create_string_buffer(self.getLength())
|
| | | memmove(addressof(buf), addressof(self), self.getLength())
|
| | | return string_at(addressof(buf), self.getLength())
|
| | |
|
| | | def getLength(self):
|
| | | return sizeof(tagDBMailPlayerRec)
|
| | |
|
| | | def outputString(self):
|
| | | output = '''// 邮件全服记录表 #tagDBMailPlayerRec:
|
| | | PlayerID = %s,
|
| | | GUID = %s,
|
| | | MailState = %s,
|
| | | ADOResult = %s,
|
| | | '''%(
|
| | | self.PlayerID,
|
| | | self.GUID,
|
| | | self.MailState,
|
| | | self.ADOResult,
|
| | | )
|
| | | return output
|
| | |
|
| | | #Char数组类型Set接口,使用该接口对此类型数据赋值,防止赋值的数据过长报错
|
| | | def SetGUID(self,Str):
|
| | | if len(Str)<=36:
|
| | | self.GUID = Str
|
| | | else:
|
| | | self.GUID = Str[:36]
|
| | | |
| | |
| | | def RefrshFightPowerTotal(self, checkChange=False):
|
| | | ## 刷新总战力
|
| | | if checkChange and self.__memFightPowerChange == False: # 默认None,首次必刷新
|
| | | GameWorld.DebugLog("没有成员战力变化可不刷新仙盟总战力! familyID=%s" % self.GetID())
|
| | | #GameWorld.DebugLog("没有成员战力变化可不刷新仙盟总战力! familyID=%s" % self.GetID())
|
| | | return
|
| | | familyFightPowerTotal = 0
|
| | | for index in range(self.GetCount()):
|
| | |
| | | family = self.FindFamily(familyID)
|
| | | if not family:
|
| | | continue
|
| | | member = family.InitMemberInstance(dbData)
|
| | | GameWorld.Log(" member:%s,familyID=%s" % (member.GetPlayerID(), familyID))
|
| | | family.InitMemberInstance(dbData)
|
| | |
|
| | | # 行为
|
| | | cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
New file |
| | |
| | | #!/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
|
| | | |
| | | mailItemCount = 0
|
| | | for itemInfo in itemRankList:
|
| | | if len(itemInfo) == 4:
|
| | | itemID, itemCount, isBind, userData = itemInfo
|
| | | else:
|
| | | userData = ""
|
| | | itemID, isBind = itemInfo
|
| | | itemCount = itemDict.get(itemInfo, 0)
|
| | | |
| | | 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)
|
| | | |
| | | mailItemCount += 1
|
| | | if mailItemCount >= 20:
|
| | | #防范某些异常情况,内置单封邮件物品上限,做下限制,并做后台邮件警告
|
| | | GameWorld.SendGameErrorEx("MailItemMultiError", "%s|%s" % (guid, itemList))
|
| | | break
|
| | | |
| | | 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):
|
| | | ## 获取邮件某个物品
|
| | | 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):
|
| | | ## 获取玩家某个邮件状态,个人、全服邮件通用
|
| | | 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):
|
| | | ## 设置玩家某个邮件状态,个人、全服邮件通用
|
| | | # @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):
|
| | | ## 删除某个全服邮件
|
| | | self.__mailItemDict.pop(guid, None)
|
| | | self.__serverMailDict.pop(guid, None)
|
| | | playerStateDict = self.__serverMailPlayerStateDict.pop(guid, {})
|
| | | return playerStateDict
|
| | | |
| | | # 保存数据 存数据库和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.SetServerMailPlayerState(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
|
| | |
|
| | | |
| | |
| | | 'AccID':curPlayer.GetAccID(), 'dayIndex':dayIndex, 'point':point}
|
| | | #发送封包
|
| | | SendEventPack("FeastWeekPartyPoint", dataDict, curPlayer)
|
| | | return |
| | | return
|
| | |
|
| | | def DR_MailSend(playerID, GUID, addDict={}):
|
| | | ## 邮件发送流向
|
| | | dataDict = {'PlayerID':playerID, 'GUID':GUID} |
| | | dataDict.update(addDict)
|
| | | #发送封包
|
| | | SendEventPack("MailSend", dataDict)
|
| | | return |
| | |
|
| | | def DR_MailGiveSuccess(playerID, GUID):
|
| | | ## 邮件领取流向
|
| | | dataDict = {'PlayerID':playerID, 'GUID':GUID} |
| | | #发送封包
|
| | | SendEventPack("MailGiveSuccess", dataDict)
|
| | | return
|
| | |
|
| | | def DR_MailDel(playerID, GUID, eventName):
|
| | | ## 邮件删除流向
|
| | | dataDict = {'PlayerID':playerID, 'GUID':GUID, 'eventName':eventName}
|
| | | #发送封包
|
| | | SendEventPack("MailDel", dataDict)
|
| | | return |
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GM.Commands.Mail
|
| | | #
|
| | | # @todo:邮件
|
| | | # @author hxp
|
| | | # @date 2025-05-14
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 邮件
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2025-05-14 12:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import PlayerMail
|
| | | import ShareDefine
|
| | | import DataRecordPack
|
| | | import DBDataMgr
|
| | | import random
|
| | |
|
| | | ## 执行逻辑
|
| | | # @param curPlayer 当前玩家
|
| | | # @param gmList []
|
| | | # @return None
|
| | | def OnExec(curPlayer, gmList):
|
| | | |
| | | if not gmList:
|
| | | GameWorld.DebugAnswer(curPlayer, "清空邮件: Mail 0")
|
| | | GameWorld.DebugAnswer(curPlayer, "发送邮件: Mail 几封 物品数 [模板key 参数1 ...]")
|
| | | GameWorld.DebugAnswer(curPlayer, "输出邮件: Mail p")
|
| | | return
|
| | | |
| | | value = gmList[0]
|
| | | |
| | | if value == 0:
|
| | | ClearMail(curPlayer)
|
| | | return
|
| | | |
| | | if value == "p":
|
| | | PrintPlayerMail(curPlayer)
|
| | | return
|
| | | |
| | | if value > 0:
|
| | | SendPlayerMail(curPlayer, gmList)
|
| | | return
|
| | | |
| | | return
|
| | |
|
| | | def SendPlayerMail(curPlayer, gmList):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | sendCnt = gmList[0]
|
| | | mailItemCnt = gmList[1] if len(gmList) > 1 else 5
|
| | | mailTypeKey = gmList[2] if len(gmList) > 2 else ""
|
| | | paramList = gmList[3:]
|
| | | |
| | | itemIDList = range(3501, 3530 + 1)
|
| | | moneyIDList = [20, 30]
|
| | | |
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | mailCntBef = mailMgr.GetPersonalMailCount(playerID)
|
| | | |
| | | isBind = 0
|
| | | for _ in range(sendCnt):
|
| | | |
| | | itemList = []
|
| | | if mailItemCnt:
|
| | | for moneyID in moneyIDList:
|
| | | itemCount = random.choice([100, 1000, 10000, 20000, 50000, 100000, 200000, 300000, 500000])
|
| | | itemList.append([moneyID, itemCount, isBind])
|
| | | if len(itemList) >= mailItemCnt:
|
| | | break
|
| | | |
| | | random.shuffle(itemIDList)
|
| | | for i in range(mailItemCnt):
|
| | | itemID = itemIDList[i]
|
| | | itemCount = random.randint(1, 100000)
|
| | | itemList.append([itemID, itemCount, isBind])
|
| | | if len(itemList) >= mailItemCnt:
|
| | | break
|
| | | |
| | | PlayerMail.SendMailByKey(mailTypeKey, playerID, itemList, paramList)
|
| | | |
| | | mailCntAft = mailMgr.GetPersonalMailCount(playerID)
|
| | | GameWorld.DebugAnswer(curPlayer, "发送个人邮件OK:%s, %s~%s" % (sendCnt, mailCntBef, mailCntAft))
|
| | | return
|
| | |
|
| | | def ClearMail(curPlayer):
|
| | | notifyGUIDState = {}
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | mailMgr = DBDataMgr.GetMailMgr() |
| | | guidList = mailMgr.GetPersonalMailGuids(playerID)
|
| | | for guid in guidList:
|
| | | mailMgr.DelPersonalMail(playerID, guid)
|
| | | DataRecordPack.DR_MailDel(playerID, guid, "GMDel")
|
| | | notifyGUIDState[guid] = ShareDefine.MailState_Del
|
| | | GameWorld.DebugAnswer(curPlayer, "删除个人邮件:%s" % len(guidList))
|
| | | |
| | | guidList = mailMgr.GetServerMailGuids()
|
| | | for guid in guidList:
|
| | | playerStateDict = mailMgr.DelServerMail(guid)
|
| | | if playerID in playerStateDict and playerStateDict[playerID] < ShareDefine.MailState_Del:
|
| | | notifyGUIDState[guid] = ShareDefine.MailState_Del
|
| | | if len(guidList):
|
| | | GameWorld.DebugAnswer(curPlayer, "删除全服邮件:%s" % len(guidList))
|
| | | PlayerMail.Sync_PlayerMailState(curPlayer, notifyGUIDState)
|
| | | return
|
| | |
|
| | | def PrintPlayerMail(curPlayer):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | mailMgr = DBDataMgr.GetMailMgr() |
| | | guidList = mailMgr.GetPersonalMailGuids(playerID)
|
| | | GameWorld.DebugAnswer(curPlayer, "个人邮件数:%s" % len(guidList))
|
| | | for num, guid in enumerate(guidList, 1):
|
| | | mailObj = mailMgr.GetPersonalMail(playerID, guid)
|
| | | __printMailLog(curPlayer, mailMgr, mailObj, num, False)
|
| | | |
| | | guidList = mailMgr.GetServerMailGuids()
|
| | | GameWorld.DebugAnswer(curPlayer, "全服邮件数:%s" % len(guidList))
|
| | | for num, guid in enumerate(guidList, 1):
|
| | | mailObj = mailMgr.GetServerMail(guid)
|
| | | __printMailLog(curPlayer, mailMgr, mailObj, num, True)
|
| | | |
| | | GameWorld.DebugAnswer(curPlayer, "邮件明细详见地图日志")
|
| | | return
|
| | |
|
| | | def __printMailLog(curPlayer, mailMgr, mailObj, num, isServerMail):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GUID = mailObj.GetGUID()
|
| | | Title = mailObj.GetTitle()
|
| | | Text = mailObj.GetText()
|
| | | CreateTime = mailObj.GetCreateTime()
|
| | | LimitDays = mailObj.GetLimitDays()
|
| | | mailState = mailMgr.GetPlayerMailState(GUID, playerID)
|
| | | mailItemCount = mailMgr.GetMailItemCount(GUID)
|
| | | GameWorld.DebugLog("%s,%s,mailState=%s,mailItemCount=%s" % (num, GUID, mailState, mailItemCount), playerID)
|
| | | GameWorld.DebugLog(" CreateTime=%s,LimitDays=%s,Title=%s,Text=%s" % (CreateTime, LimitDays, Title, Text), playerID)
|
| | | if isServerMail:
|
| | | LimitLV = mailObj.GetLimitLV()
|
| | | LimitLVType = mailObj.GetLimitLVType()
|
| | | CheckState = mailObj.GetCheckState()
|
| | | GameWorld.DebugLog(" LimitLV=%s,升级可领=%s,需要审核=%s" % (LimitLV, LimitLVType, CheckState), playerID)
|
| | | |
| | | itemList = []
|
| | | for index in range(mailItemCount):
|
| | | mailItem = mailMgr.GetMailItemAt(GUID, index)
|
| | | itemID = mailItem.GetItemID()
|
| | | itemCount = mailItem.GetCount()
|
| | | isBind = mailItem.GetIsBind()
|
| | | userData = mailItem.GetUserData()
|
| | | itemList.append([itemID, itemCount, isBind, userData])
|
| | | if itemList:
|
| | | GameWorld.DebugLog(" %s,itemList=%s" % (mailItemCount, itemList), playerID)
|
| | | return
|
| | |
|
| | |
| | | import PyGameData
|
| | | import urllib
|
| | | import md5
|
| | | import uuid
|
| | | #---------------------------------------------------------------------
|
| | | #设置允许的最大迭代数目, 默认1000
|
| | | #在NPCAI中, 可能超过1000, 所以要设定为2000
|
| | |
| | | ChannelCodeDict = ReadChConfig.GetEvalChConfig("ChannelCode")
|
| | | return ChannelCodeDict.get(codeNum, "")
|
| | |
|
| | | def GetGUID(): return str(uuid.uuid1())
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##大额度金钱记录
|
| | | # @param tradeGold 物品售价金子
|
| | |
| | | # return
|
| | | #===========================================================================
|
| | |
|
| | | DebugLog(text)
|
| | | DebugLog(text, curPlayer.GetPlayerID())
|
| | | text = text.decode(ShareDefine.Def_Game_Character_Encoding).encode(GetCharacterEncoding())
|
| | | curPlayer.DebugAnswer(text)
|
| | | return
|
| | |
| | |
|
| | | def SendGameErrorEx(errType, msgInfo="", playerID=0):
|
| | | ErrLog("SendGameErrorEx: %s -> %s" % (errType, msgInfo), playerID)
|
| | | SendGameError(errType, msgInfo)
|
| | | if GetGameWorld().GetDebugLevel():
|
| | | raise Exception("%s -> %s" % (errType, msgInfo))
|
| | | else:
|
| | | SendGameError(errType, msgInfo)
|
| | | return
|
| | |
|
| | | def SendGameError(errType, msgInfo=""):
|
| | |
| | | if curMinute == PyGameData.g_mapLastProcess_Minute:
|
| | | return
|
| | | if PyGameData.g_initGame:
|
| | | DBDataMgr.OnMinute(curMinute)
|
| | | DBDataMgr.OnMinute(curTime)
|
| | | PyGameData.g_mapLastProcess_Minute = curMinute
|
| | | PlayerTeam.OnCheckTeamPlayerDisconnectTimeout(tick)
|
| | |
|
| | |
| | | import PlayerActFamilyGCZ
|
| | | import PlayerActYunshi
|
| | | import PlayerActTask
|
| | | import PlayerMail
|
| | |
|
| | | import datetime
|
| | | import time
|
| | |
| | | pass
|
| | |
|
| | | else:
|
| | | PlayerMail.OnPlayerLogin(curPlayer)
|
| | | PlayerChatBox.OnPlayerLogin(curPlayer)
|
| | | PlayerFace.OnPlayerLogin(curPlayer)
|
| | | PlayerXiangong.OnPlayerLogin(curPlayer)
|
| | |
| | | import PlayerXiangong
|
| | | import PlayerFuncTeam
|
| | | import PlayerMineArea
|
| | | import PlayerMail
|
| | | import DBDataMgr
|
| | |
|
| | | import datetime
|
| | | import time
|
| | |
| | | def __Func_GameServer_OnDayEx(tick):
|
| | | GameWorld.Log("MapServer -> OnDayEx!")
|
| | |
|
| | | DBDataMgr.OnDayEx()
|
| | | PlayerMail.OnDayEx()
|
| | | PlayerControl.RemoveTimeoutLeaveServerPlayerInfo(tick)
|
| | |
|
| | | playerManager = GameWorld.GetPlayerManager()
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.PlayerMail
|
| | | #
|
| | | # @todo:邮件
|
| | | # @author hxp
|
| | | # @date 2025-05-14
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 邮件
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2025-05-14 12:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import ItemCommon
|
| | | import PlayerControl
|
| | | import IPY_GameWorld
|
| | | import DataRecordPack
|
| | | import ChPyNetSendPack
|
| | | import IpyGameDataPY
|
| | | import ItemControler
|
| | | import NetPackCommon
|
| | | import ShareDefine
|
| | | import DBDataMgr
|
| | | import ChConfig
|
| | |
|
| | | import json
|
| | | import time
|
| | |
|
| | | def OnPlayerLogin(curPlayer):
|
| | | Sync_PlayerServerMail(curPlayer)
|
| | | Sync_PersonalMail(curPlayer)
|
| | | return
|
| | |
|
| | | def OnDayEx():
|
| | | curTime = int(time.time())
|
| | | DelTimeoutServerMail(curTime)
|
| | | DelTimeoutPersonalMail(curTime)
|
| | | return
|
| | |
|
| | | def DelTimeoutServerMail(curTime):
|
| | | ## 清理超时全服邮件, 全服邮件分两部处理:1. 邮件接收的有效时间,后台设置,2. 邮件删除时间为接收有效时间再延长30天
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | serverMailGuids = mailMgr.GetServerMailGuids()
|
| | | for guid in serverMailGuids:
|
| | | mailObj = mailMgr.GetServerMail(guid)
|
| | | if not mailObj:
|
| | | continue
|
| | | createTime = GameWorld.ChangeTimeStrToNum(mailObj.GetCreateTime())
|
| | | limitTime = createTime + (mailObj.GetLimitDays() + 7) * 3600 * 24
|
| | | if curTime < limitTime:
|
| | | #GameWorld.DebugLog("全服邮件未超时,不删除! %s,createTime=%s,limitTime=%s" % (guid, mailObj.GetCreateTime(), GameWorld.ChangeTimeNumToStr(limitTime)))
|
| | | continue
|
| | | |
| | | DelServerMail(guid)
|
| | | |
| | | return
|
| | |
|
| | | def DelServerMail(guid):
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | playerStateDict = mailMgr.DelServerMail(guid)
|
| | | if not playerStateDict:
|
| | | return
|
| | | playerMgr = GameWorld.GetPlayerManager()
|
| | | clientPack = __packMailStateChange({guid:ShareDefine.MailState_Del})
|
| | | for playerID, mailState in playerStateDict.items():
|
| | | if mailState >= ShareDefine.MailState_Del:
|
| | | continue
|
| | | curPlayer = playerMgr.FindPlayerByID(playerID)
|
| | | if curPlayer:
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
|
| | | def DelTimeoutPersonalMail(curTime):
|
| | | ## 清理超时个人邮件
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | personalMailDict = mailMgr.GetAllPersonalMailDict()
|
| | | for playerID, mailDict in personalMailDict.items():
|
| | | notifyGUIDState = {}
|
| | | for guid, mailObj in mailDict.items():
|
| | | createTime = GameWorld.ChangeTimeStrToNum(mailObj.GetCreateTime())
|
| | | limitTime = createTime + (mailObj.GetLimitDays() + 0) * 3600 * 24
|
| | | if curTime < limitTime:
|
| | | #GameWorld.DebugLog("个人邮件未超时,不删除! %s,createTime=%s,limitTime=%s" % (guid, mailObj.GetCreateTime(), GameWorld.ChangeTimeNumToStr(limitTime)), playerID)
|
| | | continue
|
| | | |
| | | mailState = mailObj.GetMailState()
|
| | | mailItemCount = mailMgr.GetMailItemCount(guid)
|
| | | if mailItemCount and mailState != ShareDefine.MailState_Got:
|
| | | #GameWorld.DebugLog("个人邮件有物品邮件未领取不删除! %s" % guid, playerID)
|
| | | continue
|
| | | |
| | | mailMgr.DelPersonalMail(playerID, guid)
|
| | | DataRecordPack.DR_MailDel(playerID, guid, "Timeout")
|
| | | notifyGUIDState[guid] = ShareDefine.MailState_Del
|
| | | |
| | | if not notifyGUIDState:
|
| | | continue
|
| | | |
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if curPlayer:
|
| | | Sync_PlayerMailState(curPlayer, notifyGUIDState)
|
| | | return
|
| | |
|
| | | def SendMailByKey(mailTypeKey, playerID, itemList, paramList=[], limitDays=7):
|
| | | ## 发送个人邮件魔板
|
| | | if not mailTypeKey:
|
| | | mailTypeKey = ShareDefine.DefaultLackSpaceMailType
|
| | | title = "<T>%s</T>" % mailTypeKey
|
| | | text = "%s" % json.dumps(paramList, ensure_ascii=False)
|
| | | SendMail(playerID, title, text, itemList, limitDays)
|
| | | return
|
| | |
|
| | | def SendMail(playerID, title, text, itemList=None, limitDays=7, mailType=0):
|
| | | ## 发送个人邮件
|
| | | if itemList == None:
|
| | | itemList = []
|
| | | |
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | mailMax = IpyGameDataPY.GetFuncCfg("PersonalMail", 1)
|
| | | mailCnt = mailMgr.GetPersonalMailCount(playerID)
|
| | | if mailCnt >= mailMax:
|
| | | mailList = mailMgr.GetPersonalMails(playerID)
|
| | | mailList.sort(key=lambda m: (-m.GetMailState(), m.GetCreateTime())) # 按邮件状态倒序、创建时间升序排
|
| | | oneDelCnt = max(1, mailMax / 10) # 一次性删除最大数量的1/10封邮件
|
| | | isStop = False
|
| | | delCnt = 0
|
| | | notifyGUIDState = {}
|
| | | while delCnt < oneDelCnt and mailList and not isStop:
|
| | | mailObj = mailList.pop(0) # 该列表是copy,可直接pop
|
| | | if not mailObj:
|
| | | continue
|
| | | guid = mailObj.GetGUID()
|
| | | mailState = mailObj.GetMailState()
|
| | | # 已经删到未读或未领取的邮件,则强制停止,不再删除
|
| | | if mailState == ShareDefine.MailState_UnRead or (mailState == ShareDefine.MailState_Read and mailMgr.GetMailItemCount(guid)):
|
| | | isStop = True
|
| | | if delCnt > 0:
|
| | | # 已经有删过了本封可不删
|
| | | break
|
| | | |
| | | #至少要删1封
|
| | | delCnt += 1
|
| | | GameWorld.DebugLog("系统自动删除邮件: playerID=%s,guid=%s,mailState=%s,isStop=%s" % (playerID, guid, mailState, isStop))
|
| | | mailMgr.DelPersonalMail(playerID, guid)
|
| | | DataRecordPack.DR_MailDel(playerID, guid, "MaxCountLimiit")
|
| | | notifyGUIDState[guid] = ShareDefine.MailState_Del
|
| | | |
| | | if notifyGUIDState:
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if curPlayer:
|
| | | Sync_PlayerMailState(curPlayer, notifyGUIDState)
|
| | | |
| | | mailObj = mailMgr.AddPersonalMail(playerID, title, text, itemList, limitDays, mailType)
|
| | | CreateTime = mailObj.GetCreateTime()
|
| | | GUID = mailObj.GetGUID()
|
| | | |
| | | #添加流向
|
| | | addDict = {"CreateTime":CreateTime, "Title":title, "Text":text, "LimitDays":limitDays, |
| | | "ItemList":itemList, "ItemListLen":len(itemList)}
|
| | | DataRecordPack.DR_MailSend(playerID, GUID, addDict)
|
| | | |
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if curPlayer:
|
| | | Sync_PersonalMail(curPlayer, [mailObj.GetGUID()])
|
| | | return
|
| | |
|
| | | def SendSeverMail(guid, title, text, itemList=None, limitDays=7, mailType=0, limitLV=0, limitLVType=0, checkState=0):
|
| | | '''发送全服邮件
|
| | | @param limitLV: 限制可领的最低等级
|
| | | @param limitLVType: 等级达到后是否可领,默认不可
|
| | | @param checkState: 是否需要审核,默认不需要
|
| | | '''
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | mailObj = mailMgr.AddServerMail(guid, title, text, itemList, limitDays, mailType)
|
| | | mailObj.SetLimitLV(limitLV)
|
| | | mailObj.SetLimitLVType(limitLVType)
|
| | | mailObj.SetCheckState(checkState)
|
| | | if not checkState:
|
| | | Sync_ServerMail(mailObj.GetGUID())
|
| | | return
|
| | |
|
| | | def CheckServerMailResult(guid, isOK):
|
| | | ## 审核全服邮件结果
|
| | | # @param isOK: 是否通过审核
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | mailObj = mailMgr.GetServerMail(guid)
|
| | | if not mailObj:
|
| | | return
|
| | | if not isOK:
|
| | | return
|
| | | mailObj.SetCheckState(0) # 设置为0,不需要审核了,即通过
|
| | | Sync_ServerMail(guid)
|
| | | return
|
| | |
|
| | | #// A5 37 请求邮件操作 #tagCMRequestMail
|
| | | #
|
| | | #struct tagCMRequestMail
|
| | | #{
|
| | | # tagHead Head;
|
| | | # char GUID[36]; //邮件GUID,可传空,默认针对个人邮件的批量处理,如批量领取、批量删除已领邮件等;全服邮件暂时限制只能单封邮件处理
|
| | | # BYTE ReqType; //0-设置已读,1-领取邮件,2-删除邮件
|
| | | #};
|
| | | def OnRequestMail(index, curPackData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | guid = curPackData.GUID
|
| | | reqType = curPackData.ReqType
|
| | | |
| | | if reqType == 2:
|
| | | doMailDel(curPlayer, guid)
|
| | | elif reqType == 1:
|
| | | doMailGetAward(curPlayer, guid)
|
| | | else:
|
| | | doMailRead(curPlayer, guid)
|
| | | |
| | | return
|
| | |
|
| | | def doMailRead(curPlayer, guid):
|
| | | ## 执行邮件已读
|
| | | if not guid:
|
| | | return
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | mailState = mailMgr.GetPlayerMailState(guid, playerID)
|
| | | if mailState == ShareDefine.MailState_UnRead:
|
| | | mailState = mailMgr.SetPlayerMailState(guid, playerID, ShareDefine.MailState_Read)
|
| | | Sync_PlayerMailState(curPlayer, {guid:mailState})
|
| | | return
|
| | |
|
| | | def doMailGetAward(curPlayer, guid):
|
| | | ## 执行邮件领取,支持批量
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | |
| | | # 批量处理,仅针对个人邮件
|
| | | if not guid:
|
| | | guidList = mailMgr.GetPersonalMailGuids(playerID)
|
| | | else:
|
| | | guidList = [guid]
|
| | | |
| | | statItemList = []
|
| | | statItemDict = {} # 统计累计
|
| | | isPackSpaceEnough = True
|
| | | notifyGUIDState = {}
|
| | | for guid in guidList:
|
| | | mailState = mailMgr.GetPlayerMailState(guid, playerID)
|
| | | if mailState == ShareDefine.MailState_Unknown or mailState >= ShareDefine.MailState_Got:
|
| | | GameWorld.DebugLog("邮件状态已领取或不能领取! mailState=%s,%s" % (mailState, guid), playerID)
|
| | | continue
|
| | | |
| | | mailItemCount = mailMgr.GetMailItemCount(guid)
|
| | | if not mailItemCount:
|
| | | GameWorld.DebugLog("邮件没有物品可领取! %s" % (guid), playerID)
|
| | | continue
|
| | | |
| | | needPackSpaceDict = {}
|
| | | for index in range(mailItemCount):
|
| | | mailItem = mailMgr.GetMailItemAt(guid, index)
|
| | | itemID = mailItem.GetItemID()
|
| | | itemCount = mailItem.GetCount()
|
| | | isBind = mailItem.GetIsBind()
|
| | | userData = mailItem.GetUserData()
|
| | | |
| | | curItemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
|
| | | if not curItemData:
|
| | | continue
|
| | | |
| | | packType = ChConfig.GetItemPackType(curItemData)
|
| | | if userData:
|
| | | statItemList.append([itemID, itemCount, isBind, userData])
|
| | | needSpace = 1
|
| | | else:
|
| | | key = (itemID, isBind)
|
| | | if key not in statItemDict:
|
| | | statItemDict[key] = 0
|
| | | statItemList.append(key)
|
| | | statItemDict[key] = statItemDict[key] + itemCount
|
| | | |
| | | needSpace = ItemControler.GetItemNeedPackCount(packType, curItemData, itemCount, isBind)
|
| | | needPackSpaceDict[packType] = needPackSpaceDict.get(packType, 0) + needSpace
|
| | | |
| | | GameWorld.DebugLog(" guid=%s,needPackSpaceDict=%s" % (guid, needPackSpaceDict))
|
| | | |
| | | for packType, needSpace in needPackSpaceDict.items():
|
| | | if needSpace > ItemCommon.GetItemPackSpace(curPlayer, packType, needSpace):
|
| | | PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_676165", [packType])
|
| | | isPackSpaceEnough = False
|
| | | break
|
| | | |
| | | if not isPackSpaceEnough:
|
| | | break
|
| | | |
| | | notifyGUIDState[guid] = mailMgr.SetPlayerMailState(guid, playerID, ShareDefine.MailState_Got)
|
| | | |
| | | for index in range(mailItemCount):
|
| | | mailItem = mailMgr.GetMailItemAt(guid, index)
|
| | | itemID = mailItem.GetItemID()
|
| | | itemCount = mailItem.GetCount()
|
| | | isBind = mailItem.GetIsBind()
|
| | | userData = mailItem.GetUserData()
|
| | | #setAttrDict = {} if not userData else eval(userData) 之后扩展有指定属性的,可参考砍树版本
|
| | | if not ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isBind, [IPY_GameWorld.rptItem], |
| | | event=[ChConfig.ItemGive_Mail, False, {"MailGUID":guid}]):
|
| | | continue
|
| | | |
| | | DataRecordPack.DR_MailGiveSuccess(playerID, guid)
|
| | | |
| | | giveItemInfo = []
|
| | | for statItem in statItemList:
|
| | | if len(statItem) == 2:
|
| | | itemID, isBind = statItem
|
| | | itemCount = statItemDict.get(statItem, 0)
|
| | | giveItemInfo.append([itemID, itemCount, isBind])
|
| | | else:
|
| | | giveItemInfo.append(statItem)
|
| | | if giveItemInfo:
|
| | | ItemControler.NotifyGiveAwardInfo(curPlayer, giveItemInfo, "Mail")
|
| | | |
| | | Sync_PlayerMailState(curPlayer, notifyGUIDState)
|
| | | return
|
| | |
|
| | | def doMailDel(curPlayer, guid, isGM=False):
|
| | | ## 执行邮件删除
|
| | | # @param isGM: 是否GM删除,无视物品是否已领取,强制删除
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | |
| | | # 批量处理,仅针对个人邮件
|
| | | if not guid:
|
| | | guidList = mailMgr.GetPersonalMailGuids(playerID)
|
| | | else:
|
| | | guidList = [guid]
|
| | | |
| | | notifyGUIDState = {}
|
| | | for guid in guidList:
|
| | | mailState = mailMgr.GetPlayerMailState(guid, playerID)
|
| | | if mailState >= ShareDefine.MailState_Del:
|
| | | continue
|
| | | if not isGM:
|
| | | mailItemCount = mailMgr.GetMailItemCount(guid)
|
| | | if mailItemCount and mailState != ShareDefine.MailState_Got:
|
| | | GameWorld.DebugLog("有物品邮件未领取不能删除! %s" % guid, playerID)
|
| | | continue
|
| | | if not mailItemCount and mailState != ShareDefine.MailState_Read:
|
| | | GameWorld.DebugLog("无物品邮件未读不能删除! %s" % guid, playerID)
|
| | | continue
|
| | | |
| | | notifyGUIDState[guid] = mailMgr.SetPlayerMailState(guid, playerID, ShareDefine.MailState_Del)
|
| | | if isGM:
|
| | | DataRecordPack.DR_MailDel(playerID, guid, "GMDel")
|
| | | # 这里玩家主动删除的可不记录流向,因为未读未领取不允许主动删除,已领取的已有领取记录,所以可不记录
|
| | | |
| | | Sync_PlayerMailState(curPlayer, notifyGUIDState)
|
| | | return
|
| | |
|
| | | def Sync_ServerMail(guid):
|
| | | ## 通知全服邮件
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | serverMail = mailMgr.GetServerMail(guid)
|
| | | if not serverMail:
|
| | | return
|
| | | packMail = __packMailObj(serverMail)
|
| | | |
| | | clientPack = ChPyNetSendPack.tagMCMailList()
|
| | | clientPack.IsServerMail = 1
|
| | | clientPack.MailList = [packMail]
|
| | | clientPack.Count = len(clientPack.MailList)
|
| | | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in range(playerManager.OnlineCount()):
|
| | | curPlayer = playerManager.OnlineAt(i)
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | |
| | | mailState = CheckPlayerServerMailState(curPlayer, serverMail)
|
| | | if mailState == ShareDefine.MailState_Unknown or mailState >= ShareDefine.MailState_Del:
|
| | | continue
|
| | | |
| | | packMail.MailState = mailState
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | |
| | | return
|
| | |
|
| | | def Sync_PlayerServerMail(curPlayer):
|
| | | ## 通知玩家相关的全服邮件
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | guidList = mailMgr.GetServerMailGuids()
|
| | | if not guidList:
|
| | | return
|
| | | |
| | | mailList = []
|
| | | for guid in guidList:
|
| | | mailObj = mailMgr.GetServerMail(guid)
|
| | | if not mailObj:
|
| | | continue
|
| | | |
| | | mailState = CheckPlayerServerMailState(curPlayer, mailObj)
|
| | | if mailState == ShareDefine.MailState_Unknown or mailState >= ShareDefine.MailState_Del:
|
| | | continue
|
| | | |
| | | mail = __packMailObj(mailObj)
|
| | | mail.MailState = mailState
|
| | | mailList.append(mail)
|
| | | |
| | | if not mailList:
|
| | | return
|
| | | |
| | | clientPack = ChPyNetSendPack.tagMCMailList()
|
| | | clientPack.MailList = mailList
|
| | | clientPack.Count = len(clientPack.MailList)
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
|
| | | def CheckPlayerServerMailState(curPlayer, serverMail):
|
| | | ## 检查处理玩家全服邮件状态
|
| | | # @return: 玩家该全服邮件的状态
|
| | | |
| | | if not serverMail or serverMail.GetCheckState():
|
| | | # 需要审核的,直接返回
|
| | | return ShareDefine.MailState_Unknown
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | guid = serverMail.GetGUID()
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | mailState = mailMgr.GetPlayerMailState(guid, playerID)
|
| | | if mailState != ShareDefine.MailState_Unknown:
|
| | | return mailState
|
| | | |
| | | mailState = ShareDefine.MailState_Unknown
|
| | | limitLV = serverMail.GetLimitLV()
|
| | | limitLVType = serverMail.GetLimitLVType()
|
| | | playerLV = curPlayer.GetLV()
|
| | | if playerLV < limitLV:
|
| | | if not limitLVType:
|
| | | return mailMgr.SetPlayerMailState(guid, playerID, ShareDefine.MailState_Limit)
|
| | | return ShareDefine.MailState_Unknown
|
| | | |
| | | return mailMgr.SetPlayerMailState(guid, playerID, ShareDefine.MailState_UnRead)
|
| | |
|
| | | def Sync_PersonalMail(curPlayer, guidList=None):
|
| | | ## 通知玩家个人邮件
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | if not guidList:
|
| | | guidList = mailMgr.GetPersonalMailGuids(playerID)
|
| | | |
| | | if not guidList:
|
| | | return
|
| | | |
| | | clientPack = ChPyNetSendPack.tagMCMailList()
|
| | | clientPack.MailList = []
|
| | | for guid in guidList:
|
| | | mailObj = mailMgr.GetPersonalMail(playerID, guid)
|
| | | if not mailObj:
|
| | | continue
|
| | | mail = __packMailObj(mailObj)
|
| | | mail.MailState = mailObj.GetMailState()
|
| | | clientPack.MailList.append(mail)
|
| | | clientPack.Count = len(clientPack.MailList)
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
|
| | | def __packMailObj(mailObj):
|
| | | ## 打包通知的邮件
|
| | | guid = mailObj.GetGUID()
|
| | | mail = ChPyNetSendPack.tagMCMail()
|
| | | mail.GUID = guid
|
| | | mail.Type = mailObj.GetType()
|
| | | mail.CreateTime = mailObj.GetCreateTime()
|
| | | mail.LimitDays = mailObj.GetLimitDays()
|
| | | mail.Title = mailObj.GetTitle()
|
| | | mail.TitleLen = len(mail.Title)
|
| | | mail.Text = mailObj.GetText()
|
| | | mail.TextLen = len(mail.Text)
|
| | | |
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | mailItemCount = mailMgr.GetMailItemCount(guid)
|
| | | for index in range(mailItemCount):
|
| | | mailItem = mailMgr.GetMailItemAt(guid, index)
|
| | | if not mailItem:
|
| | | continue
|
| | | item = ChPyNetSendPack.tagMCMailItem()
|
| | | item.ItemID = mailItem.GetItemID()
|
| | | item.Count = mailItem.GetCount()
|
| | | item.IsBind = mailItem.GetIsBind()
|
| | | item.UserData = mailItem.GetUserData()
|
| | | item.UserDataLen = len(item.UserData)
|
| | | mail.Items.append(item)
|
| | | mail.Count = len(mail.Items)
|
| | | return mail
|
| | |
|
| | | def __packMailStateChange(notifyGUIDState):
|
| | | clientPack = ChPyNetSendPack.tagMCMailStateChange()
|
| | | clientPack.MailList = []
|
| | | for guid, mailState in notifyGUIDState.items():
|
| | | mail = ChPyNetSendPack.tagMCMailState()
|
| | | mail.GUID = guid
|
| | | mail.MailState = mailState
|
| | | clientPack.MailList.append(mail)
|
| | | clientPack.Count = len(clientPack.MailList)
|
| | | return clientPack
|
| | |
|
| | | def Sync_PlayerMailState(curPlayer, notifyGUIDState):
|
| | | ## 通知邮件状态变更
|
| | | if not notifyGUIDState:
|
| | | return
|
| | | NetPackCommon.SendFakePack(curPlayer, __packMailStateChange(notifyGUIDState))
|
| | | return
|
| | |
| | | DefaultLackSpaceMailType = "DefaultLackSpace" # 背包空间不足时发放物品的默认邮件模板
|
| | | Def_Space = "<Space=1>" # <Space=空格数>
|
| | |
|
| | | # 邮件状态定义,每封邮件只能有一种状态,状态只升不降
|
| | | MailStateList = (
|
| | | MailState_Unknown, # δ֪ 0
|
| | | MailState_UnRead, # 未读 1
|
| | | MailState_Read, # 已读 2
|
| | | MailState_Got, # 已领取 3
|
| | | MailState_Del, # 已删除,全服邮件会用到 4
|
| | | MailState_Limit, # 限制接收邮件,全服邮件会用到 5
|
| | | ) = range(6)
|
| | |
|
| | |
|
| | | # 手游不使用C++定义 enum RoleEquipType
|
| | | # 装备位定义
|
| | | RoleEquipType = (
|