|  |  | 
 |  |  | import NetPackCommon
 | 
 |  |  | import CommFunc
 | 
 |  |  | import ChPyNetSendPack
 | 
 |  |  | import PyGameDataStruct
 | 
 |  |  | import CrossRealmMsg
 | 
 |  |  | import DataRecordPack
 | 
 |  |  | import ReadChConfig
 | 
 |  |  | import PlayerDBOper
 | 
 |  |  | import EventReport
 | 
 |  |  | import IpyGameDataPY
 | 
 |  |  | import PlayerControl
 | 
 |  |  | import PyDataManager
 | 
 |  |  | import PyGameData
 | 
 |  |  | import datetime
 | 
 |  |  | import uuid
 | 
 |  |  | import math
 | 
 |  |  | import json
 | 
 |  |  | #领取状态  个位数标识 (可领取即已通知过玩家该封邮件,需要在邮件发生时和上线时设置状态
 | 
 |  |  | #0 未通知,1 不可领取, 2 可领取, 3 已领取
 | 
 |  |  | #0 未通知,1 不可领取, 2 可领取, 3 已领取,4 已删除
 | 
 |  |  | (
 | 
 |  |  | Unknown_State,
 | 
 |  |  | Disable_State,
 | 
 |  |  | Enable_State,
 | 
 |  |  | Yet_State
 | 
 |  |  | ) = range(4)
 | 
 |  |  | Yet_State,
 | 
 |  |  | Del_State
 | 
 |  |  | ) = range(5)
 | 
 |  |  | 
 | 
 |  |  | CheckState_OK = 0 # 已审核
 | 
 |  |  | CheckState_No = 1 # 未审核
 | 
 |  |  | 
 |  |  | 
 | 
 |  |  | Def_RequestState = "CompensationRequestState"
 | 
 |  |  | 
 | 
 |  |  | #==================================================================================================
 | 
 |  |  | class CrossPersonalCompensationManager(object):
 | 
 |  |  |     ## 跨服邮件管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
 | 
 |  |  |      | 
 |  |  |     def __init__(self):
 | 
 |  |  |         self.playerMailDict = {} # 玩家补偿列表 {playerID:{GUID:tagDBCrossPersonalCompensation, ...}, ...}
 | 
 |  |  |         return
 | 
 |  |  |      | 
 |  |  |     # 保存数据 存数据库和realtimebackup
 | 
 |  |  |     def GetSaveData(self):
 | 
 |  |  |         savaData = ""
 | 
 |  |  |         cntData = ""
 | 
 |  |  |         cnt = 0
 | 
 |  |  |         for mailDict in self.playerMailDict.values():
 | 
 |  |  |             for mailObj in mailDict.values():
 | 
 |  |  |                 cnt += 1
 | 
 |  |  |                 savaData += mailObj.getBuffer()
 | 
 |  |  |                  | 
 |  |  |         GameWorld.Log("Save DBCrossPersonalCompensation 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 DBCrossPersonalCompensation count :%s" % cnt)
 | 
 |  |  |          | 
 |  |  |         for _ in xrange(cnt):
 | 
 |  |  |             mailObj = PyGameDataStruct.tagDBCrossPersonalCompensation()
 | 
 |  |  |             mailObj.clear()
 | 
 |  |  |             pos += mailObj.readData(datas, pos, dataslen)
 | 
 |  |  |              | 
 |  |  |             playerID = mailObj.PlayerID
 | 
 |  |  |             guid = mailObj.GUID
 | 
 |  |  |             if playerID not in self.playerMailDict:
 | 
 |  |  |                 self.playerMailDict[playerID] = {}
 | 
 |  |  |             mailDict = self.playerMailDict[playerID]
 | 
 |  |  |             mailDict[guid] = mailObj
 | 
 |  |  |              | 
 |  |  |         return pos
 | 
 |  |  |      | 
 |  |  | def Sync_CrossMailPlayerIDToClientServer(serverGroupID=0):
 | 
 |  |  |     ''' 同步有跨服邮件的玩家ID到子服
 | 
 |  |  |     @param serverGroupID: 为0时同步所有子服
 | 
 |  |  |     '''
 | 
 |  |  |     crossMailMgr = PyDataManager.GetCrossPersonalCompensationManager()
 | 
 |  |  |     addMailPlayerIDList = crossMailMgr.playerMailDict.keys()
 | 
 |  |  |     if not addMailPlayerIDList:
 | 
 |  |  |         return
 | 
 |  |  |     # 同步子服务器
 | 
 |  |  |     serverGroupIDList = [serverGroupID] if serverGroupID else []
 | 
 |  |  |     dataMsg = {"IDType":"Add", "PlayerIDList":addMailPlayerIDList}
 | 
 |  |  |     CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_MailPlayerIDList, dataMsg, serverGroupIDList)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def CrossServerMsg_MailPlayerIDList(dataMsg):
 | 
 |  |  |     ## 收到跨服服务器同步有跨服邮件的玩家ID列表
 | 
 |  |  |     idType = dataMsg["IDType"]
 | 
 |  |  |     playerIDList = dataMsg["PlayerIDList"]
 | 
 |  |  |     for playerID in playerIDList:
 | 
 |  |  |         if idType == "Del":
 | 
 |  |  |             if playerID in PyGameData.g_crossMailPlayerDict:
 | 
 |  |  |                 PyGameData.g_crossMailPlayerDict.pop(playerID)
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         if idType == "Add":
 | 
 |  |  |             if playerID in PyGameData.g_crossMailPlayerDict:
 | 
 |  |  |                 continue
 | 
 |  |  |             PyGameData.g_crossMailPlayerDict[playerID] = 0
 | 
 |  |  |              | 
 |  |  |             player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
 | 
 |  |  |             if not player or not player.GetInitOK():
 | 
 |  |  |                 continue
 | 
 |  |  |             RequestToGetCrossMail(player)
 | 
 |  |  |              | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def RequestToGetCrossMail(curPlayer):
 | 
 |  |  |     ## 请求同步跨服邮件内容
 | 
 |  |  |     playerID = curPlayer.GetPlayerID()
 | 
 |  |  |     if playerID not in PyGameData.g_crossMailPlayerDict:
 | 
 |  |  |         return
 | 
 |  |  |     lastTick = PyGameData.g_crossMailPlayerDict[playerID]
 | 
 |  |  |     tick = GameWorld.GetGameWorld().GetTick()
 | 
 |  |  |     if tick - lastTick <= 30000:
 | 
 |  |  |         return
 | 
 |  |  |     PyGameData.g_crossMailPlayerDict[playerID] = tick
 | 
 |  |  |     dataMsg = {"CMD":"Get", "PlayerID":playerID}
 | 
 |  |  |     CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_MailContent, dataMsg)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def ClientServerMsg_MailContent(serverGroupID, msgData, tick):
 | 
 |  |  |     ## 收到子服玩家请求同步跨服邮件
 | 
 |  |  |      | 
 |  |  |     GameWorld.Log("收到子服玩家同步个人邮件命令: serverGroupID=%s, %s" % (serverGroupID, msgData))
 | 
 |  |  |      | 
 |  |  |     reqCMD = msgData["CMD"]
 | 
 |  |  |     playerID = msgData["PlayerID"]
 | 
 |  |  |     guidList = msgData.get("GuidList", [])
 | 
 |  |  |     crossMailMgr = PyDataManager.GetCrossPersonalCompensationManager()
 | 
 |  |  |     if playerID not in crossMailMgr.playerMailDict:
 | 
 |  |  |         return
 | 
 |  |  |     playerMailDict = crossMailMgr.playerMailDict[playerID]
 | 
 |  |  |      | 
 |  |  |     if reqCMD == "Get":
 | 
 |  |  |         SyncTickAttrKey = "SyncTick"
 | 
 |  |  |         getMailList = []
 | 
 |  |  |         for guid, mailObj in playerMailDict.items():
 | 
 |  |  |             if hasattr(mailObj, SyncTickAttrKey):
 | 
 |  |  |                 getTick = getattr(mailObj, SyncTickAttrKey)
 | 
 |  |  |                 if tick - getTick <= 30000:
 | 
 |  |  |                     GameWorld.DebugLog("短时间内重复请求领取的邮件不同步,防止重复发放! GUID=%s" % guid)
 | 
 |  |  |                     continue
 | 
 |  |  |             setattr(mailObj, SyncTickAttrKey, tick)
 | 
 |  |  |             crossMailDict = {"PlayerID":mailObj.PlayerID, "GUID":mailObj.GUID, "LimitTime":mailObj.LimitTime,
 | 
 |  |  |                              "Text":mailObj.Text, "ItemInfo":mailObj.ItemInfo, "Detail":mailObj.Detail,
 | 
 |  |  |                              "Gold":mailObj.Gold, "GoldPaper":mailObj.GoldPaper, "Silver":mailObj.Silver,
 | 
 |  |  |                              "MoneySource":mailObj.MoneySource
 | 
 |  |  |                              }
 | 
 |  |  |             getMailList.append(crossMailDict)
 | 
 |  |  |              | 
 |  |  |         if getMailList:
 | 
 |  |  |             CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_MailContent, getMailList, [serverGroupID])
 | 
 |  |  |              | 
 |  |  |     elif reqCMD == "GetOK":
 | 
 |  |  |          | 
 |  |  |         for guid in guidList:
 | 
 |  |  |             playerMailDict.pop(guid, None)
 | 
 |  |  |             DataRecordPack.DR_GiveCompensationSuccess(playerID, guid)
 | 
 |  |  |              | 
 |  |  |         if not playerMailDict:
 | 
 |  |  |             crossMailMgr.playerMailDict.pop(playerID, None)
 | 
 |  |  |             dataMsg = {"IDType":"Del", "PlayerIDList":[playerID]}
 | 
 |  |  |             CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_MailPlayerIDList, dataMsg, [serverGroupID])
 | 
 |  |  |              | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def CrossServerMsg_MailContent(getMailList):
 | 
 |  |  |     ## 收到跨服服务器同步的待发送邮件内容
 | 
 |  |  |      | 
 |  |  |     playerGetGUIDInfo = {}
 | 
 |  |  |     for mailDict in getMailList:
 | 
 |  |  |         GUID = mailDict.get("GUID", "")
 | 
 |  |  |         playerID = mailDict.get("PlayerID", 0)
 | 
 |  |  |         if not GUID or not playerID:
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         GameWorld.Log("收到跨服个人邮件内容:%s" % mailDict, playerID)
 | 
 |  |  |          | 
 |  |  |         addItemDictList = eval(mailDict.get("ItemInfo", "[]"))
 | 
 |  |  |         LimitTime = mailDict.get("LimitTime", "")
 | 
 |  |  |         Text = mailDict.get("Text", "")
 | 
 |  |  |         gold = GameWorld.ToIntDef(mailDict.get("Gold"))
 | 
 |  |  |         goldPaper = GameWorld.ToIntDef(mailDict.get("GoldPaper"))
 | 
 |  |  |         silver = GameWorld.ToIntDef(mailDict.get("Silver"))
 | 
 |  |  |         moneySource = GameWorld.ToIntDef(mailDict.get("MoneySource"), ChConfig.Def_GiveMoney_Mail)
 | 
 |  |  |         detail = mailDict.get("Detail", "")
 | 
 |  |  |          | 
 |  |  |         AddPersonalItem(GUID, addItemDictList, [playerID], LimitTime, Text, gold, goldPaper, silver, detail, moneySource)
 | 
 |  |  |          | 
 |  |  |         if playerID not in playerGetGUIDInfo:
 | 
 |  |  |             playerGetGUIDInfo[playerID] = []
 | 
 |  |  |         guidList = playerGetGUIDInfo[playerID]
 | 
 |  |  |         guidList.append(GUID)
 | 
 |  |  |          | 
 |  |  |     for playerID, guidList in playerGetGUIDInfo.items():
 | 
 |  |  |         dataMsg = {"CMD":"GetOK", "PlayerID":playerID, "GuidList":guidList}
 | 
 |  |  |         CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_MailContent, dataMsg)
 | 
 |  |  |          | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def __AddPlayerCrossMail(addItemDictList, PlayerIDList, LimitTime, Text, gold, goldPaper, silver, detail, moneySource):
 | 
 |  |  |     ## 添加跨服玩家个人补偿邮件
 | 
 |  |  |      | 
 |  |  |     addMailPlayerIDList = []
 | 
 |  |  |     crossMailMgr = PyDataManager.GetCrossPersonalCompensationManager()
 | 
 |  |  |     for playerID in PlayerIDList:
 | 
 |  |  |         GUID = str(uuid.uuid1()) # 由于跨服邮件由每个玩家独自同步个人邮件,所以插入时每个人的邮件单独GUID,防止批量发送同内容邮件时重复插入奖励物品
 | 
 |  |  |         mailObj = PyGameDataStruct.tagDBCrossPersonalCompensation()
 | 
 |  |  |         mailObj.PlayerID = playerID
 | 
 |  |  |         mailObj.GUID = GUID
 | 
 |  |  |         mailObj.LimitTime = LimitTime
 | 
 |  |  |         mailObj.Text = Text
 | 
 |  |  |         mailObj.TextLen = len(mailObj.Text)
 | 
 |  |  |         mailObj.Gold = gold
 | 
 |  |  |         mailObj.GoldPaper = goldPaper
 | 
 |  |  |         mailObj.Silver = silver
 | 
 |  |  |         mailObj.ItemInfo = json.dumps(addItemDictList, ensure_ascii=False)
 | 
 |  |  |         mailObj.ItemLen = len(mailObj.ItemInfo)
 | 
 |  |  |         mailObj.Detail = detail
 | 
 |  |  |         mailObj.DetailLen = len(mailObj.Detail)
 | 
 |  |  |         mailObj.MoneySource = moneySource
 | 
 |  |  |          | 
 |  |  |         if playerID not in crossMailMgr.playerMailDict:
 | 
 |  |  |             crossMailMgr.playerMailDict[playerID] = {}
 | 
 |  |  |             addMailPlayerIDList.append(playerID)
 | 
 |  |  |         playerMailDict = crossMailMgr.playerMailDict[playerID]
 | 
 |  |  |         playerMailDict[GUID] = mailObj
 | 
 |  |  |          | 
 |  |  |         #添加流向
 | 
 |  |  |         addDict = {"LimitTime":LimitTime, "Text":Text, "Gold":gold, "GoldPaper":goldPaper, "Silver":silver,  | 
 |  |  |                    "ItemListLen":len(addItemDictList), "Detail":detail, "MoneySource":moneySource, "CrossMail":True}
 | 
 |  |  |         DataRecordPack.DR_AddPersonalCompensation(PlayerIDList, GUID, addItemDictList, addDict)
 | 
 |  |  |      | 
 |  |  |     if addMailPlayerIDList:
 | 
 |  |  |         dataMsg = {"IDType":"Add", "PlayerIDList":addMailPlayerIDList}
 | 
 |  |  |         CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_MailPlayerIDList, dataMsg)
 | 
 |  |  |          | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | #==================================================================================================
 | 
 |  |  | ## 根据物品信息字典,生成补偿物品实例,用于GM工具添加补偿
 | 
 |  |  | #  @param curItemDict 
 | 
 |  |  | #  @return IpyCompensationItem
 | 
 |  |  | def MakeCompensationItem(curItemDict):
 | 
 |  |  |     if not __checkMailItemDict(curItemDict):
 | 
 |  |  |         return
 | 
 |  |  |     curItemData = IPY_GameServer.IpyCompensationItem()
 | 
 |  |  |     #curItemData.GUID = curItemDict['GUID']
 | 
 |  |  |     curItemData.ItemID = curItemDict['ItemID']
 | 
 |  |  |     curItemData.Count = curItemDict['Count']
 | 
 |  |  |     curItemData.IsBind = curItemDict.get('IsBind',0)
 | 
 |  |  |     #curItemData.IsBind = curItemDict.get('IsBind',0)
 | 
 |  |  |     curItemData.IsBind = curItemDict.get('IsAuctionItem',0)
 | 
 |  |  |     curItemData.UserData = curItemDict.get('UserData', '')
 | 
 |  |  |     return curItemData
 | 
 |  |  | 
 | 
 |  |  | #  此处货币playerIDList发放统一,如根据玩家不同而变,则应需修改
 | 
 |  |  | ## 功能发放物品补偿/奖励邮件
 | 
 |  |  | #  @param addItemList [(itemID, itemCnt, isBind), {或物品信息字典}, ...]
 | 
 |  |  | #  @param addItemList [(itemID, itemCnt, 是否拍品), {或物品信息字典}, ...]
 | 
 |  |  | #  @return GUID
 | 
 |  |  | def SendPersonalItemMailEx(title, content, getDays, playerIDList, addItemList,  | 
 |  |  |                            gold = 0, goldPaper = 0, silver = 0, sourceType = ChConfig.Mail_Type_Default, detail=""):
 | 
 |  |  | def SendPersonalItemMailEx(title, content, getDays, playerIDList, addItemList, gold = 0, goldPaper = 0, silver = 0,  | 
 |  |  |                            detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
 | 
 |  |  |     limitTime = str(GameWorld.GetDatetimeByDiffDays(getDays))
 | 
 |  |  |     limitTime = limitTime.split(".")[0]
 | 
 |  |  |     return SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList,  | 
 |  |  |                                 gold, goldPaper, silver, sourceType, detail=detail)
 | 
 |  |  |     return SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail)
 | 
 |  |  |     
 | 
 |  |  | def SendPersonalItemMailBatch(batchMailInfoList):
 | 
 |  |  |     ## 批量发送邮件
 | 
 |  |  |     mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver, batchDetail = batchMailInfoList
 | 
 |  |  |     mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver, batchDetail, moneySource, crossMail = batchMailInfoList
 | 
 |  |  |     
 | 
 |  |  |     lenPlayerID = len(batchPlayerIDList)
 | 
 |  |  |     lenItem = len(batchAddItemList)
 | 
 |  |  | 
 |  |  |     limitTime = limitTime.split(".")[0]
 | 
 |  |  |     
 | 
 |  |  |     for i, playerIDList in enumerate(batchPlayerIDList):
 | 
 |  |  |         if not playerIDList:
 | 
 |  |  |             continue
 | 
 |  |  |         addItemList = batchAddItemList[i] if lenItem == lenPlayerID else []
 | 
 |  |  |         paramList = batchParamList[i] if lenParam == lenPlayerID else []
 | 
 |  |  |         gold = batchGold[i] if lenGold == lenPlayerID else 0
 | 
 |  |  | 
 |  |  |         silver = batchSilver[i] if lenSilver == lenPlayerID else 0
 | 
 |  |  |         detail = batchDetail[i] if lenDetail == lenPlayerID else ""
 | 
 |  |  |         content = "<MailTemplate>%s</MailTemplate>%s" % (mailTypeKey, str(paramList))
 | 
 |  |  |         SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold, goldPaper, silver, detail=detail)
 | 
 |  |  |         SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold, goldPaper, silver, detail=detail, moneySource=moneySource, crossMail=crossMail)
 | 
 |  |  |         
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def SendMailByKey(mailTypeKey, playerIDList, addItemList, paramList=[], gold=0, goldPaper=0, silver=0, detail=""):
 | 
 |  |  | def SendMailByKey(mailTypeKey, playerIDList, addItemList, paramList=[], gold=0, goldPaper=0, silver=0,  | 
 |  |  |                   detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
 | 
 |  |  |     if not mailTypeKey:
 | 
 |  |  |         mailTypeKey = ShareDefine.DefaultLackSpaceMailType
 | 
 |  |  |     GameWorld.DebugLog("SendMailByKey %s, playerIDList=%s, addItemList=%s, paramList=%s, gold=%s, goldPaper=%s, silver=%s"  | 
 |  |  |                        % (mailTypeKey, playerIDList, addItemList, paramList, gold, goldPaper, silver))
 | 
 |  |  |     GameWorld.DebugLog("SendMailByKey %s, playerIDList=%s, addItemList=%s, paramList=%s, gold=%s, goldPaper=%s, silver=%s, moneySource=%s"  | 
 |  |  |                        % (mailTypeKey, playerIDList, addItemList, paramList, gold, goldPaper, silver, moneySource))
 | 
 |  |  |     title = ""
 | 
 |  |  |     content = "<MailTemplate>%s</MailTemplate>%s" % (mailTypeKey, json.dumps(paramList, ensure_ascii=False))
 | 
 |  |  |     return SendPersonalItemMailEx(title, content, 30, playerIDList, addItemList, gold, goldPaper, silver, detail=detail)
 | 
 |  |  |     return SendPersonalItemMailEx(title, content, 30, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail)
 | 
 |  |  | 
 | 
 |  |  | def CrossServerMsg_SendMail(msgData):
 | 
 |  |  |     ## 收到跨服服务器同步的发送邮件
 | 
 |  |  |     mailTypeKey = msgData["MailTypeKey"]
 | 
 |  |  |     playerIDList = msgData["Player"]
 | 
 |  |  |     addItemList = msgData.get("Item", [])
 | 
 |  |  |     paramList = msgData.get("Param", [])
 | 
 |  |  |     SendMailByKey(mailTypeKey, playerIDList, addItemList, paramList)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def __checkMailItemIDCount(itemID, itemCount, isAuctionItem):
 | 
 |  |  |     ## 检查是否合法的邮件物品ID Count 数据
 | 
 |  |  |     if not (isinstance(itemID, int) or isinstance(itemID, long)):
 | 
 |  |  |         return
 | 
 |  |  |     if not (isinstance(itemCount, int) or isinstance(itemCount, long)):
 | 
 |  |  |         return
 | 
 |  |  |     if not (isinstance(isAuctionItem, int) or isinstance(isAuctionItem, long) or isinstance(isAuctionItem, bool)):
 | 
 |  |  |         return
 | 
 |  |  |     if itemID > ShareDefine.Def_UpperLimit_DWord or itemCount > ShareDefine.Def_UpperLimit_DWord or isAuctionItem > 255:
 | 
 |  |  |         return
 | 
 |  |  |     return True
 | 
 |  |  | 
 | 
 |  |  | def __checkMailItemDict(curItemDict):
 | 
 |  |  |     ## 检查是否合法的邮件物品dict信息  {"ItemID":xxx, "Count":xxx, "IsAuctionItem":xxx}
 | 
 |  |  |     if not isinstance(curItemDict, dict):
 | 
 |  |  |         return
 | 
 |  |  |     if "ItemID" not in curItemDict or "Count" not in curItemDict:
 | 
 |  |  |         return
 | 
 |  |  |     itemID = curItemDict["ItemID"]
 | 
 |  |  |     itemCount = curItemDict["Count"]
 | 
 |  |  |     isAuctionItem = curItemDict.get("IsAuctionItem", 0)
 | 
 |  |  |     if not __checkMailItemIDCount(itemID, itemCount, isAuctionItem):
 | 
 |  |  |         return
 | 
 |  |  |     return curItemDict
 | 
 |  |  | 
 | 
 |  |  | def __checkMailItemList(addItemList):
 | 
 |  |  |     ## 检查是否合法的邮件物品列表
 | 
 |  |  |     addItemDictList = []
 | 
 |  |  |     for itemInfo in addItemList:
 | 
 |  |  |         if isinstance(itemInfo, dict):
 | 
 |  |  |             if not __checkMailItemDict(itemInfo):
 | 
 |  |  |                 return False, []
 | 
 |  |  |             addItemDictList.append(itemInfo)
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         if (isinstance(itemInfo, list) or isinstance(itemInfo, tuple)) and (len(itemInfo) == 3 or len(itemInfo) == 2):
 | 
 |  |  |             itemID, itemCount = itemInfo[:2]
 | 
 |  |  |             isAuctionItem = itemInfo[2] if len(itemInfo) > 2 else 0
 | 
 |  |  |             if not __checkMailItemIDCount(itemID, itemCount, isAuctionItem):
 | 
 |  |  |                 return False, []
 | 
 |  |  |             addItemDict = {}
 | 
 |  |  |             addItemDict['ItemID'] = itemID
 | 
 |  |  |             addItemDict['Count'] = itemCount
 | 
 |  |  |             addItemDict['IsAuctionItem'] = isAuctionItem
 | 
 |  |  |             addItemDictList.append(addItemDict)
 | 
 |  |  |         else:
 | 
 |  |  |             return False, []
 | 
 |  |  |     return True, addItemDictList
 | 
 |  |  | 
 | 
 |  |  | #  此处货币playerIDList发放统一,如根据玩家不同而变,则应需修改
 | 
 |  |  | ## 功能发放物品补偿/奖励邮件
 | 
 |  |  | #  @param addItemList [(itemID, itemCnt, isBind), {或物品信息字典}, ...]
 | 
 |  |  | #  @param addItemList [(itemID, itemCnt, 是否拍品), {或物品信息字典}, ...]
 | 
 |  |  | #  @return GUID
 | 
 |  |  | #  @remarks addItemList支持append字典
 | 
 |  |  | def SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList,
 | 
 |  |  |                          gold = 0, goldPaper = 0, silver = 0, sourceType = ChConfig.Mail_Type_Default, detail=""):
 | 
 |  |  | def SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold = 0, goldPaper = 0, silver = 0,  | 
 |  |  |                          detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False, mailType=0):
 | 
 |  |  |     if not playerIDList:
 | 
 |  |  |         return ""
 | 
 |  |  |     
 | 
 |  |  | 
 |  |  |     if not curServerTime or curServerTime >= limitTime:
 | 
 |  |  |         GameWorld.DebugLog("功能发放物品补偿/奖励邮件,领取时间已超时,默认不添加!LimitTime=%s" % limitTime)
 | 
 |  |  |         return ""
 | 
 |  |  |     isOK, addItemDictList = __checkMailItemList(addItemList)
 | 
 |  |  |     if not isOK:
 | 
 |  |  |         GameWorld.ErrLog("发送个人邮件错误: title=%s,content=%s,playerIDList=%s,addItemList=%s,gold=%s,goldPaper=%s,silver=%s,detail=%s,moneySource=%s,crossMail=%s"  | 
 |  |  |                          % (title, content, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail))
 | 
 |  |  |         return
 | 
 |  |  |     
 | 
 |  |  |     addItemDictList = []
 | 
 |  |  |     for itemInfo in addItemList:
 | 
 |  |  |         if isinstance(itemInfo, dict):
 | 
 |  |  |             addItemDictList.append(itemInfo)
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |          | 
 |  |  |         if len(itemInfo) == 3:
 | 
 |  |  |             itemID, itemCnt, isBind = itemInfo
 | 
 |  |  |         else:
 | 
 |  |  |             continue
 | 
 |  |  |              | 
 |  |  |         addItemDict = {}
 | 
 |  |  |         addItemDict['ItemID'] = itemID
 | 
 |  |  |         addItemDict['Count'] = itemCnt
 | 
 |  |  |         addItemDict['IsBind'] = isBind
 | 
 |  |  |         addItemDictList.append(addItemDict)
 | 
 |  |  |          | 
 |  |  |     gold = min(gold, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |     goldPaper = min(goldPaper, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |     silver = min(silver, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |      | 
 |  |  |     perMailItemCnt = IpyGameDataPY.GetFuncCfg("MailMaxItemCnt")
 | 
 |  |  |     mailCnt = max(1, int(math.ceil(len(addItemDictList)/float(perMailItemCnt)))) # 一封邮件最多5个物品
 | 
 |  |  |     for i in xrange(mailCnt):
 | 
 |  |  |         if i != 0:
 | 
 |  |  |             gold, goldPaper, silver = 0, 0, 0 # 拆分后非第一封的邮件货币归零,防止重复给货币奖励
 | 
 |  |  |         startIndex = i*perMailItemCnt
 | 
 |  |  |         GUID = str(uuid.uuid1())
 | 
 |  |  |         AddPersonalItem(GUID, addItemDictList[startIndex:startIndex + perMailItemCnt], playerIDList, 
 | 
 |  |  |                                            limitTime, "%s<$_$>%s<$_$>%s" % (ChConfig.Def_Mail_SenderSys, title, content),
 | 
 |  |  |                                            gold, goldPaper, silver, sourceType, detail)
 | 
 |  |  |                                            limitTime, GetMailText(title, content, mailType),
 | 
 |  |  |                                            gold, goldPaper, silver, detail, moneySource, crossMail)
 | 
 |  |  |     return GUID
 | 
 |  |  | 
 | 
 |  |  | ## 发送纯文字个人补偿
 | 
 |  |  | #  @param limitTime 可以传空
 | 
 |  |  | #  @param sourceType 查看 Mail_Type_Default 相关定义
 | 
 |  |  | #  @return None
 | 
 |  |  | def SendPersonalAsTextMail(PlayerID, title, content, limitTime, sourceType = ChConfig.Mail_Type_Default):
 | 
 |  |  | def SendPersonalAsTextMail(PlayerID, title, content, limitTime, mailType=0):
 | 
 |  |  |     if GameWorld.IsCrossServer():
 | 
 |  |  |         return
 | 
 |  |  |     GUID = str(uuid.uuid1())
 | 
 |  |  |     PyAddPersonalCompensation(GUID, PlayerID, GameWorld.GetCurrentDataTimeStr(), limitTime, 
 | 
 |  |  |                               "%s<$_$>%s<$_$>%s" % (ChConfig.Def_Mail_SenderSys,title, content), sourceType)
 | 
 |  |  |                               GetMailText(title, content, mailType))
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def GetMailText(title, content, mailType=0, sender=ChConfig.Def_Mail_SenderSys):
 | 
 |  |  |     ## 获取邮件字段 Text 内容
 | 
 |  |  |     return "%s<$_$>%s<$_$>%s<$_$>%s" % (sender, title, content, mailType)
 | 
 |  |  | 
 | 
 |  |  | def GetEntireCompensationInfo(checkState, limitLVType, limitLV):
 | 
 |  |  |     return checkState * 1000000 + limitLVType * 100000 + limitLV
 | 
 |  |  | 
 |  |  |     limitLVType = (mailInfo - checkState * 1000000) / 100000
 | 
 |  |  |     return checkState, limitLVType, limitLV
 | 
 |  |  | 
 | 
 |  |  | def QueryCompensationPersonalInfo(playerID):
 | 
 |  |  |     '''个人补偿邮件查询
 | 
 |  |  |     '''
 | 
 |  |  |          | 
 |  |  |     retList = []
 | 
 |  |  |     compensationMgr = GameWorld.GetCompensationMgr()
 | 
 |  |  |      | 
 |  |  |     tempSign = "<MailTemplate>"
 | 
 |  |  |     tempSignEnd = "</MailTemplate>"
 | 
 |  |  |     curPersonalCount = compensationMgr.GetPersonalCompensationCount(playerID)
 | 
 |  |  |     GameWorld.DebugLog("QueryCompensationPersonalInfo %s" % curPersonalCount)
 | 
 |  |  |     for i in xrange(curPersonalCount):
 | 
 |  |  |         compensation = compensationMgr.PersonalCompensationAt(playerID, i)
 | 
 |  |  |          | 
 |  |  |         contentList = compensation.Text.split("<$_$>")
 | 
 |  |  |         if len(contentList) < 3:
 | 
 |  |  |             continue
 | 
 |  |  |         sender, title, content = contentList[:3]
 | 
 |  |  |         mailType = GameWorld.ToIntDef(contentList[3]) if len(contentList) > 3 else 0
 | 
 |  |  |          | 
 |  |  |         if tempSign in content and tempSignEnd in content:
 | 
 |  |  |             title = content[content.index(tempSign) + len(tempSign):content.index(tempSignEnd)]
 | 
 |  |  |             content = ""
 | 
 |  |  |              | 
 |  |  |         GUID = compensation.GUID
 | 
 |  |  |         itemList = []
 | 
 |  |  |         curGUIDItemCount = compensationMgr.FindItemCount(GUID)
 | 
 |  |  |         for i in xrange(curGUIDItemCount):
 | 
 |  |  |             curItem = compensationMgr.FindItemAt(GUID, i)
 | 
 |  |  |             itemID = curItem.ItemID
 | 
 |  |  |             if not itemID:
 | 
 |  |  |                 continue
 | 
 |  |  |             itemList.append([itemID, curItem.Count, curItem.IsBind, curItem.UserData])
 | 
 |  |  |              | 
 |  |  |         recState = compensationMgr.FindPlayerRecState(playerID, GUID)
 | 
 |  |  |          | 
 |  |  |         infoDict = {"GUID":GUID, "Gold":compensation.Gold, "GoldPaper":compensation.GoldPaper, "Silver":compensation.Silver,
 | 
 |  |  |                     "Sender":sender, "Title":title, "Content":content, "RecState":recState, "MailType":mailType,
 | 
 |  |  |                     "CreateTime":compensation.CreateTime, "LimitTime":compensation.LimitTime, "ItemList":itemList}
 | 
 |  |  |          | 
 |  |  |         retList.append(infoDict)
 | 
 |  |  |          | 
 |  |  |     return retList
 | 
 |  |  | 
 | 
 |  |  | def QueryCompensationInfo(fromDate, toDate, guid, searchTitle, searchContent, searchState=None, maxCount=10):
 | 
 |  |  |     '''补偿邮件查询
 | 
 |  |  |     '''全服补偿邮件查询
 | 
 |  |  |     '''
 | 
 |  |  |     
 | 
 |  |  |     compensationMgr = GameWorld.GetCompensationMgr()
 | 
 |  |  | 
 |  |  |         return
 | 
 |  |  |     
 | 
 |  |  |     contentList = compensation.Text.split("<$_$>")
 | 
 |  |  |     if len(contentList) != 3:
 | 
 |  |  |     if len(contentList) < 3:
 | 
 |  |  |         return
 | 
 |  |  |     sender, title, content = contentList
 | 
 |  |  |     sender, title, content = contentList[:3]
 | 
 |  |  |     mailType = GameWorld.ToIntDef(contentList[3]) if len(contentList) > 3 else 0
 | 
 |  |  |     
 | 
 |  |  |     if searchTitle and searchTitle not in title:
 | 
 |  |  |         return
 | 
 |  |  | 
 |  |  |             continue
 | 
 |  |  |         itemList.append([itemID, curItem.Count, curItem.IsBind, curItem.UserData])
 | 
 |  |  |         
 | 
 |  |  |     compensationDict = {"GUID":GUID, "CheckState":checkState, "LimitLVType":limitLVType, "LimitLV":limitLV,
 | 
 |  |  |     compensationDict = {"GUID":GUID, "CheckState":checkState, "LimitLVType":limitLVType, "LimitLV":limitLV, "MailType":mailType,
 | 
 |  |  |                         "Gold":compensation.Gold, "GoldPaper":compensation.GoldPaper, "Silver":compensation.Silver,
 | 
 |  |  |                         "PlayerJob":compensation.PlayerJob, "Sender":sender, "Title":title, "Content":content,
 | 
 |  |  |                         "PlayerJob":compensation.PlayerJob, "Sender":sender, "Title":title, "Content":content, "OnlyServerID":compensation.ServerID,
 | 
 |  |  |                         "CreateTime":compensation.CreateTime, "LimitTime":compensation.LimitTime, "ItemList":itemList}
 | 
 |  |  |     return compensationDict
 | 
 |  |  | 
 | 
 |  |  | 
 |  |  |             
 | 
 |  |  |     return successGUIDList
 | 
 |  |  | 
 | 
 |  |  | def SendEntireMail(mailTypeKey, getDays, limitLV, limitLVType, addItemList=[], paramList=[], \
 | 
 |  |  |                    gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail, GUID="", mailType=0):
 | 
 |  |  |     ''' 发送全服邮件
 | 
 |  |  |     @param mailTypeKey: 邮件模板key
 | 
 |  |  |     @param getDays: 有效天数
 | 
 |  |  |     @param limitLV: 领取最低等级限制
 | 
 |  |  |     @param limitLVType: 等级不足的升级后是否可领 0-不可,1-可以
 | 
 |  |  |     '''
 | 
 |  |  |      | 
 |  |  |     if not mailTypeKey or getDays <= 0:
 | 
 |  |  |         return
 | 
 |  |  |      | 
 |  |  |     isOK, addItemDictList = __checkMailItemList(addItemList)
 | 
 |  |  |     if not isOK:
 | 
 |  |  |         GameWorld.ErrLog("发送全服邮件错误: mailTypeKey=%s,addItemList=%s,paramList=%s,gold=%s,goldPaper=%s,silver=%s,detail=%s,moneySource=%s"  | 
 |  |  |                      % (mailTypeKey, addItemList, paramList, gold, goldPaper, silver, detail, moneySource))
 | 
 |  |  |         return
 | 
 |  |  |      | 
 |  |  |     gold = min(gold, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |     goldPaper = min(goldPaper, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |     silver = min(silver, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |      | 
 |  |  |     if not GUID:
 | 
 |  |  |         GUID = str(uuid.uuid1())
 | 
 |  |  |          | 
 |  |  |     limitTime = str(GameWorld.GetDatetimeByDiffDays(getDays))
 | 
 |  |  |     limitTime = limitTime.split(".")[0]
 | 
 |  |  |      | 
 |  |  |     sender = ChConfig.Def_Mail_SenderSys
 | 
 |  |  |     title = ""
 | 
 |  |  |     content = "<MailTemplate>%s</MailTemplate>%s" % (mailTypeKey, json.dumps(paramList, ensure_ascii=False))
 | 
 |  |  |      | 
 |  |  |     checkState = 0 # 邮件审核状态,为兼容老邮件,默认0-已审核,1-未审核
 | 
 |  |  |     mailInfo = GetEntireCompensationInfo(checkState, limitLVType, limitLV)
 | 
 |  |  |     PlayerJob = 127 # 默认全职业可领
 | 
 |  |  |     serverID = 0 # 默认所有服务器ID
 | 
 |  |  |      | 
 |  |  |     AddEntireItem(GUID, addItemDictList, limitTime, mailInfo, PlayerJob, GetMailText(title, content, mailType, sender),  | 
 |  |  |                   gold, goldPaper, silver, detail, serverID)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | ## 添加全服补偿
 | 
 |  |  | #  @param addItemDictList, LimitTime, mailInfo, PlayerJob,  Text 
 | 
 |  |  | #  @return None
 | 
 |  |  | 
 |  |  |     #添加补偿包的所有物品
 | 
 |  |  |     for addItemDict in addItemDictList:
 | 
 |  |  |         curItemData = MakeCompensationItem(addItemDict)
 | 
 |  |  |         if not curItemData:
 | 
 |  |  |             return
 | 
 |  |  |         GameWorld.GetCompensationMgr().AddCompensationItem(GUID, curItemData)
 | 
 |  |  |         
 | 
 |  |  |     createTime = GameWorld.GetCurrentDataTimeStr()
 | 
 |  |  |     
 | 
 |  |  |     #添加全服领取补偿条件
 | 
 |  |  |     gold = min(gold, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |     goldPaper = min(goldPaper, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |     silver = min(silver, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |     GameWorld.GetCompensationMgr().AddEntireCompensationItem(GUID, createTime, LimitTime, mailInfo, 
 | 
 |  |  |                                                              PlayerJob, Text, gold, goldPaper, silver, serverID)
 | 
 |  |  |     checkState, limitLVType, limitLV = ParseEntireCompensationInfo(mailInfo)
 | 
 |  |  | 
 |  |  | 
 | 
 |  |  | # 检查邮件是否已达到保存上限,如超过则先删除旧邮件
 | 
 |  |  | # @param LimitTime 参数可传空,个人邮件不限制领取期限,只限制保存数量, 
 | 
 |  |  | def PyAddPersonalCompensation(GUID, PlayerID, CreateTime, LimitTime, Text, sourceType,  | 
 |  |  |                               gold = 0, goldPaper = 0, silver = 0):
 | 
 |  |  | def PyAddPersonalCompensation(GUID, PlayerID, CreateTime, LimitTime, Text, gold = 0, goldPaper = 0, silver = 0, moneySource=ChConfig.Def_GiveMoney_Mail):
 | 
 |  |  |     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(PlayerID)
 | 
 |  |  |     cnt = GameWorld.GetCompensationMgr().GetPersonalCompensationCountByType(PlayerID, sourceType)
 | 
 |  |  |     totalCount = GameWorld.GetCompensationMgr().GetPersonalCompensationCount(PlayerID)
 | 
 |  |  |     #待支持py读表
 | 
 |  |  |     tmpDict = {ChConfig.Mail_Type_Default:IpyGameDataPY.GetFuncCfg("MailDefaultCount"),  | 
 |  |  |                ChConfig.Mail_Type_Market:IpyGameDataPY.GetFuncCfg("MailMarketCount")}
 | 
 |  |  |      | 
 |  |  |     delcnt = cnt - tmpDict[sourceType] + 1
 | 
 |  |  |     #GameWorld.DebugLog("PyAddPersonalCompensation typecnt = %s-%s"%(cnt, delcnt))
 | 
 |  |  |     if delcnt > 0:
 | 
 |  |  |     maxMailCount = IpyGameDataPY.GetFuncCfg("MailDefaultCount")
 | 
 |  |  |     delCount = totalCount - maxMailCount + 1
 | 
 |  |  |     GameWorld.DebugLog("新增个人邮件: totalCount=%s,maxMailCount=%s" % (totalCount, maxMailCount), PlayerID)
 | 
 |  |  |     if delCount > 0:
 | 
 |  |  |         GameWorld.Log("个人邮件达到上限,需要删除!delCount=%s" % (delCount), PlayerID)
 | 
 |  |  |         delGUIDList = GetPlayerDelMailGUIDList(PlayerID)
 | 
 |  |  |         #先取得要删除的GUID
 | 
 |  |  |         delGUIDs = []
 | 
 |  |  |         for i in xrange(delcnt):
 | 
 |  |  |             tmpGuid = GameWorld.GetCompensationMgr().AtGUIDInPersonalTypesByType(PlayerID, sourceType, i)
 | 
 |  |  |             if not tmpGuid:
 | 
 |  |  |                 #GameWorld.DebugLog("PyAddPersonalCompensation not GUID = %s"%tmpGuid)
 | 
 |  |  |                 continue
 | 
 |  |  |             delGUIDs.append(tmpGuid)
 | 
 |  |  |          | 
 |  |  |         for guid in delGUIDs:     | 
 |  |  |             ClearPersonalCompensation(PlayerID, guid)
 | 
 |  |  |             #GameWorld.DebugLog("PyAddPersonalCompensation DeletePersonalCompensation GUID = %s"%guid)
 | 
 |  |  |         for _ in xrange(delCount):
 | 
 |  |  |             if not delGUIDList:
 | 
 |  |  |                 break
 | 
 |  |  |             delGUID = delGUIDList.pop(0)
 | 
 |  |  |             curIpyPersonalData = GameWorld.GetCompensationMgr().FindPersonalCompensation(PlayerID, delGUID)
 | 
 |  |  |             if curIpyPersonalData.GUID == delGUID:
 | 
 |  |  |                 delGUIDs.append(curIpyPersonalData.GUID)
 | 
 |  |  |              | 
 |  |  |         for guid in delGUIDs:
 | 
 |  |  |             ClearPersonalCompensation(PlayerID, guid, "MaxCountLimiit")
 | 
 |  |  |             GameWorld.Log("    DeletePersonalCompensation GUID = %s" % guid, PlayerID)
 | 
 |  |  |             
 | 
 |  |  |             if curPlayer:
 | 
 |  |  |                 NotifyCompensationResult(curPlayer, guid, 1)
 | 
 |  |  |             #未补流向
 | 
 |  |  |      | 
 |  |  |     #GameWorld.DebugLog("PyAddPersonalCompensation CreateTime %s"%CreateTime)
 | 
 |  |  |              | 
 |  |  |     #此处没有下发通知
 | 
 |  |  |     mailType = moneySource - ChConfig.Def_GiveMoney_Unknown # type类型为byte,存值时需要处理下
 | 
 |  |  |     gold = min(gold, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |     goldPaper = min(goldPaper, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |     silver = min(silver, ShareDefine.Def_UpperLimit_DWord)
 | 
 |  |  |     GameWorld.GetCompensationMgr().AddPersonalCompensation(GUID, PlayerID, CreateTime,
 | 
 |  |  |                                                            LimitTime, Text, sourceType, gold, goldPaper, silver)
 | 
 |  |  |                                                            LimitTime, Text, mailType, gold, goldPaper, silver)
 | 
 |  |  |     if PlayerID in PyGameData.g_playerDelMailGUIDDict:
 | 
 |  |  |         guidList = PyGameData.g_playerDelMailGUIDDict[PlayerID]
 | 
 |  |  |         guidList.append(GUID)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def GetPlayerDelMailGUIDList(playerID):
 | 
 |  |  |     ## 获取待删除的个人邮件GUID列表
 | 
 |  |  |     if playerID not in PyGameData.g_playerDelMailGUIDDict:
 | 
 |  |  |          | 
 |  |  |         timeGUIDList = []
 | 
 |  |  |         curPersonalCount = GameWorld.GetCompensationMgr().GetPersonalCompensationCount(playerID)
 | 
 |  |  |         for i in xrange(curPersonalCount):
 | 
 |  |  |             curMail = GameWorld.GetCompensationMgr().PersonalCompensationAt(playerID, i)
 | 
 |  |  |             timeGUIDList.append([curMail.CreateTime, curMail.GUID])
 | 
 |  |  |              | 
 |  |  |         timeGUIDList.sort() # 按创建时间升序排序
 | 
 |  |  |         delGUIDList = []
 | 
 |  |  |         for _, guid in timeGUIDList:
 | 
 |  |  |             if guid not in delGUIDList:
 | 
 |  |  |                 delGUIDList.append(guid)
 | 
 |  |  |         PyGameData.g_playerDelMailGUIDDict[playerID] = delGUIDList
 | 
 |  |  |          | 
 |  |  |     return PyGameData.g_playerDelMailGUIDDict[playerID]
 | 
 |  |  | 
 | 
 |  |  | #  此处货币playerIDList发放统一,如根据玩家不同而变,则应需修改
 | 
 |  |  | ## 添加个人补偿
 | 
 |  |  | #  @param addItemDict, PlayerIDList, LimitTime, Text 
 | 
 |  |  | #  @return None
 | 
 |  |  | def AddPersonalItem(GUID, addItemDictList, PlayerIDList, LimitTime, Text,  | 
 |  |  |                     gold = 0, goldPaper = 0, silver = 0, sourceType = ChConfig.Mail_Type_Default, detail=""):
 | 
 |  |  | def AddPersonalItem(GUID, addItemDictList, PlayerIDList, LimitTime, Text, gold = 0, goldPaper = 0, silver = 0,  | 
 |  |  |                     detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
 | 
 |  |  |     if GameWorld.IsCrossServer():
 | 
 |  |  |         if crossMail:
 | 
 |  |  |             __AddPlayerCrossMail(addItemDictList, PlayerIDList, LimitTime, Text, gold, goldPaper, silver, detail, moneySource)
 | 
 |  |  |         return
 | 
 |  |  |     GameWorld.DebugLog("Compensation### AddPersonalItem GUID:%s ItemDict:\n%s "%(GUID, addItemDictList))
 | 
 |  |  |     
 | 
 |  |  |     #添加补偿包的所有物品
 | 
 |  |  |     for addItemDict in addItemDictList:
 | 
 |  |  |         curItemData = MakeCompensationItem(addItemDict)
 | 
 |  |  |         if not curItemData:
 | 
 |  |  |             return
 | 
 |  |  |         GameWorld.GetCompensationMgr().AddCompensationItem(GUID, curItemData)
 | 
 |  |  |         
 | 
 |  |  |     #offlinePlayerIDList = []
 | 
 |  |  | 
 |  |  |     #批量添加玩家个人补偿领取表
 | 
 |  |  |     createTime = GameWorld.GetCurrentDataTimeStr()
 | 
 |  |  |     for PlayerID in PlayerIDList:
 | 
 |  |  |         PyAddPersonalCompensation(GUID, PlayerID, createTime, LimitTime,  | 
 |  |  |                                   Text, sourceType, gold, goldPaper, silver)
 | 
 |  |  |         PyAddPersonalCompensation(GUID, PlayerID, createTime, LimitTime, Text, gold, goldPaper, silver, moneySource)
 | 
 |  |  |         # 针对个人补偿,如果是在线玩家,则立即推送给客户端
 | 
 |  |  |         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(PlayerID)
 | 
 |  |  |         if curPlayer:
 | 
 |  |  | 
 |  |  |     
 | 
 |  |  |     #添加流向
 | 
 |  |  |     addDict = {"LimitTime":LimitTime, "Text":Text, "Gold":gold, "GoldPaper":goldPaper, "Silver":silver, 
 | 
 |  |  |                "ItemListLen":len(addItemDictList), "Detail":detail}
 | 
 |  |  |                "ItemListLen":len(addItemDictList), "Detail":detail, "MoneySource":moneySource}
 | 
 |  |  |     DataRecordPack.DR_AddPersonalCompensation(PlayerIDList, GUID, addItemDictList, addDict)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | 
 |  |  | 
 | 
 |  |  | # 提取接收邮件下发
 | 
 |  |  | def NotifyPlayerCompensation(curPlayer):
 | 
 |  |  |     RequestToGetCrossMail(curPlayer)
 | 
 |  |  |     notifyList = SeekPlayerCompensation(curPlayer)
 | 
 |  |  |     SyncQueryCompensationResult(curPlayer, notifyList)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | # 删除个人邮件表 状态表,同一个GUID 可以多人领取,不能同时删除物品
 | 
 |  |  | def ClearPersonalCompensation(curPlayerID, curGUID):
 | 
 |  |  | def ClearPersonalCompensation(curPlayerID, curGUID, eventName=""):
 | 
 |  |  |     GameWorld.GetCompensationMgr().DeletePersonalCompensation(curPlayerID, curGUID)
 | 
 |  |  |     GameWorld.GetCompensationMgr().DeletePlayerCompensationRec(curPlayerID, curGUID)
 | 
 |  |  |     
 | 
 |  |  |     #存在多人邮件的情况,故删除物品需检查是否最后一个领取者才可删除
 | 
 |  |  |     if GameWorld.GetCompensationMgr().GetPersonalCountByGUID(curGUID) == 0:
 | 
 |  |  |         GameWorld.GetCompensationMgr().DeleteCompensationItem(curGUID)
 | 
 |  |  |          | 
 |  |  |     if curPlayerID in PyGameData.g_playerDelMailGUIDDict:
 | 
 |  |  |         guidList = PyGameData.g_playerDelMailGUIDDict[curPlayerID]
 | 
 |  |  |         if curGUID in guidList:
 | 
 |  |  |             guidList.remove(curGUID)
 | 
 |  |  |     if eventName:
 | 
 |  |  |         # 有特殊操作删除的才记录,常规领取删除的默认无eventName,不记录
 | 
 |  |  |         DataRecordPack.DR_DelPersonalCompensation(curPlayerID, curGUID, eventName)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | # 设置领取状态
 | 
 |  |  | def SetPrizeState(curPlayerID, GUID, prizeState, readState):
 | 
 |  |  |     state = readState*10 + prizeState
 | 
 |  |  |     GameWorld.GetCompensationMgr().AddPlayerRec(curPlayerID, GUID, state)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def GetPrizeGetState(curPlayerID, GUID):
 | 
 |  |  |     ## 获取领取状态
 | 
 |  |  |     return GameWorld.GetCompensationMgr().FindPlayerRecState(curPlayerID, GUID) % 10
 | 
 |  |  | 
 | 
 |  |  | ##查找玩家可领取的补偿列表
 | 
 |  |  | #  @param curPlayer 
 | 
 |  |  | 
 |  |  |         states = GameWorld.GetCompensationMgr().FindPlayerRecState(curPlayerID, curRequire.GUID)
 | 
 |  |  |         readState = states/10    # 可读       
 | 
 |  |  |         curState = states%10    # 领取状态
 | 
 |  |  |         if curState in (Disable_State, Yet_State):
 | 
 |  |  |         if curState in (Disable_State, Del_State):
 | 
 |  |  |             #不可领 或 已领
 | 
 |  |  |              | 
 |  |  |             #GameWorld.DebugLog("该玩家当前全服邮件状态不下发: curState=%s,GUID=%s" % (curState, curRequire.GUID), curPlayerID)
 | 
 |  |  |             continue
 | 
 |  |  |         
 | 
 |  |  |         limitTime = datetime.datetime.strptime(curRequire.LimitTime, ChConfig.TYPE_Time_Format)
 | 
 |  |  | 
 |  |  |             SetPrizeState(curPlayerID, curRequire.GUID, Disable_State, readState)
 | 
 |  |  |             continue
 | 
 |  |  |         
 | 
 |  |  |         if limitLVType == LimitLVType_Not and curPlayer.GetCreateRoleTime() > curRequire.CreateTime:
 | 
 |  |  |             #GameWorld.DebugLog("升级后不可领取的邮件发送时间后创角的玩家默认不可领取! CreateRoleTime=%s > %s" % (curPlayer.GetCreateRoleTime(), curRequire.CreateTime))
 | 
 |  |  |             SetPrizeState(curPlayerID, curRequire.GUID, Disable_State, readState)
 | 
 |  |  |             continue
 | 
 |  |  | 
 | 
 |  |  |         if limitLV > curLV:
 | 
 |  |  |             #等级不足
 | 
 |  |  |             if limitLVType == LimitLVType_Not:
 | 
 |  |  | 
 |  |  |                 SetPrizeState(curPlayerID, curRequire.GUID, Disable_State, readState)
 | 
 |  |  |                 continue
 | 
 |  |  |             
 | 
 |  |  |         if curRequire.ServerID and curRequire.ServerID != GameWorld.GetPlayerServerID(curPlayer):
 | 
 |  |  |             # 指定服务器邮件
 | 
 |  |  |             SetPrizeState(curPlayerID, curRequire.GUID, Disable_State, readState)
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         #可以用的奖励
 | 
 |  |  |         if Enable_State != curState:
 | 
 |  |  |         if Enable_State != curState and curState != Yet_State:
 | 
 |  |  |             SetPrizeState(curPlayerID, curRequire.GUID, Enable_State, readState)
 | 
 |  |  |         allList.append((curRequire.GUID, curRequire.Text, curRequire.CreateTime,
 | 
 |  |  |                         curRequire.Gold, curRequire.GoldPaper, curRequire.Silver))
 | 
 |  |  | 
 |  |  |         subPack.Gold = gold
 | 
 |  |  |         subPack.GoldPaper = goldPaper
 | 
 |  |  |         subPack.Silver = silver 
 | 
 |  |  |         subPack.IsRead = GameWorld.GetCompensationMgr().FindPlayerRecState(curPlayer.GetPlayerID(), GUID)/10
 | 
 |  |  |         resState = GameWorld.GetCompensationMgr().FindPlayerRecState(curPlayer.GetPlayerID(), GUID)
 | 
 |  |  |         if resState % 10 == Yet_State:
 | 
 |  |  |             subPack.IsRead = Yet_State # 已领取
 | 
 |  |  |         else:
 | 
 |  |  |             subPack.IsRead = resState / 10 # 是否已读
 | 
 |  |  |         for index in xrange(curGUIDItemCount):
 | 
 |  |  |             curItem = GameWorld.GetCompensationMgr().FindItemAt(GUID, index)
 | 
 |  |  |             subPackItem = ChPyNetSendPack.tagGCCompensationItem()
 | 
 |  |  | 
 |  |  |         sendPack.PackList.append(subPack)
 | 
 |  |  |     sendPack.Count = len(sendPack.PackList)
 | 
 |  |  |     NetPackCommon.SendFakePack(curPlayer, sendPack)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | def SyncQueryCompensationResultByGUID(curPlayer, notifyGUIDList):
 | 
 |  |  |     curPlayerID = curPlayer.GetPlayerID()
 | 
 |  |  |     notifyList = []
 | 
 |  |  |     compensationMgr = GameWorld.GetCompensationMgr()
 | 
 |  |  |     for GUID in notifyGUIDList:
 | 
 |  |  |         findCompensation = compensationMgr.FindPersonalCompensation(curPlayerID, GUID)
 | 
 |  |  |         if findCompensation.PlayerID != curPlayerID:
 | 
 |  |  |             findCompensation = compensationMgr.FindEntireCompensation(GUID)
 | 
 |  |  |             if findCompensation.GUID != GUID:
 | 
 |  |  |                 # 找不到邮件
 | 
 |  |  |                 continue
 | 
 |  |  |         notifyList.append((findCompensation.GUID, findCompensation.Text, findCompensation.CreateTime,  | 
 |  |  |                            findCompensation.Gold, findCompensation.GoldPaper, findCompensation.Silver))
 | 
 |  |  |     if not notifyList:
 | 
 |  |  |         return
 | 
 |  |  |     SyncQueryCompensationResult(curPlayer, notifyList)
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | ##03 03 玩家请求领取补偿#tagMGRequestCompensation
 | 
 |  |  | 
 |  |  |     GameWorld.DebugLog("Compensation### OnMGRequestCompensation myPlayerID %s GUID %s"%(myPlayerID, GUID))
 | 
 |  |  |     
 | 
 |  |  |     compensationType, curEntireRequire = CheckRequestCompensation(curPlayer, GUID) 
 | 
 |  |  |     if compensationType == Unknow_CompensationType:
 | 
 |  |  |     if compensationType == Unknow_CompensationType or not curEntireRequire:
 | 
 |  |  |         #领取失败
 | 
 |  |  |         curPlayer.SetDict(Def_RequestState, 0)#解锁
 | 
 |  |  |         GameWorld.DebugLog("Compensation### OnMGRequestCompensation no found")
 | 
 |  |  |         return
 | 
 |  |  |     Text, gold, goldPaper, silver = curEntireRequire.Text, curEntireRequire.Gold, curEntireRequire.GoldPaper, curEntireRequire.Silver
 | 
 |  |  |     #校验背包剩余空间是否足够
 | 
 |  |  |     #===========================================================================
 | 
 |  |  |     # curCUIDItemCount = GameWorld.GetCompensationMgr().FindItemCount(GUID)
 | 
 |  |  | 
 |  |  |     #    return
 | 
 |  |  |     #===========================================================================
 | 
 |  |  |     #发送到MapServer给予奖励
 | 
 |  |  |     SendGMRequestCompensationResult(routeIndex, mapID, curPlayer, GUID, compensationType, Text, gold, goldPaper, silver)
 | 
 |  |  |     SendGMRequestCompensationResult(routeIndex, mapID, curPlayer, GUID, compensationType, curEntireRequire)
 | 
 |  |  |     GameWorld.DebugLog("Compensation### OnMGRequestCompensation out")
 | 
 |  |  |     
 | 
 |  |  | ##请求领取物品
 | 
 |  |  | 
 |  |  | #  @return CompensationType 补偿类型
 | 
 |  |  | def CheckRequestCompensation(curPlayer, GUID, isPersonnal = True):
 | 
 |  |  |     curPlayerID = curPlayer.GetID()
 | 
 |  |  |      | 
 |  |  |     states = GameWorld.GetCompensationMgr().FindPlayerRecState(curPlayerID, GUID)
 | 
 |  |  |     readState = states/10    # 可读        | 
 |  |  |     curState = states%10    # 领取状态
 | 
 |  |  |      | 
 |  |  |     if curState in (Disable_State, Yet_State, Del_State):
 | 
 |  |  |         #不可领 或 已领
 | 
 |  |  |         #GameWorld.DebugLog("当前邮件不可领取或已领: states=%s,curState=%s,GUID=%s" % (states, curState, GUID), curPlayerID)
 | 
 |  |  |         return Unknow_CompensationType, None
 | 
 |  |  |     
 | 
 |  |  |     if isPersonnal:
 | 
 |  |  |         #在个人补偿中
 | 
 |  |  | 
 |  |  |         
 | 
 |  |  |     #---------
 | 
 |  |  |     #在全服补偿中
 | 
 |  |  |     states = GameWorld.GetCompensationMgr().FindPlayerRecState(curPlayerID, GUID)
 | 
 |  |  |     readState = states/10    # 可读        | 
 |  |  |     curState = states%10    # 领取状态
 | 
 |  |  |      | 
 |  |  |     if curState in (Disable_State, Yet_State):
 | 
 |  |  |         #不可领 或 已领
 | 
 |  |  |         return Unknow_CompensationType, None
 | 
 |  |  |     curEntireRequire = GameWorld.GetCompensationMgr().FindEntireCompensation(GUID)
 | 
 |  |  |     if curEntireRequire.GUID != GUID:
 | 
 |  |  |         #不再全服补偿中,删除记录
 | 
 |  |  | 
 |  |  | ##发送封包 03 02 玩家领取补偿结果#tagGMRequestCompensationResult
 | 
 |  |  | #  @param routeIndex, mapID, curPlayer, curItem
 | 
 |  |  | #  @return None
 | 
 |  |  | def SendGMRequestCompensationResult(routeIndex, mapID, curPlayer, GUID, compensationType, Text,
 | 
 |  |  |                                     gold, goldPaper, silver):
 | 
 |  |  | def SendGMRequestCompensationResult(routeIndex, mapID, curPlayer, GUID, compensationType, curEntireRequire):
 | 
 |  |  |      | 
 |  |  |     Text, gold, goldPaper, silver, createTime = curEntireRequire.Text, curEntireRequire.Gold, \
 | 
 |  |  |         curEntireRequire.GoldPaper, curEntireRequire.Silver, curEntireRequire.CreateTime
 | 
 |  |  |     # 全服邮件没有 Type 字段
 | 
 |  |  |     moneySource = curEntireRequire.Type if compensationType == Personal_CompensationType else 0
 | 
 |  |  |      | 
 |  |  |     sendPack = ChGameToMapPyPack.tagGMRequestCompensationResult() 
 | 
 |  |  |     sendPack.PlayerID = curPlayer.GetID()
 | 
 |  |  |     sendPack.CompensationType = compensationType
 | 
 |  |  |     sendPack.GUID = GUID
 | 
 |  |  |     sendPack.CreateTime = createTime
 | 
 |  |  |     sendPack.Text = Text
 | 
 |  |  |     sendPack.TextLen = len(Text)
 | 
 |  |  |     sendPack.Gold = gold
 | 
 |  |  |     sendPack.GoldPaper = goldPaper
 | 
 |  |  |     sendPack.Silver = silver
 | 
 |  |  |     sendPack.MoneySource = moneySource
 | 
 |  |  |     curGUIDItemCount = GameWorld.GetCompensationMgr().FindItemCount(GUID)
 | 
 |  |  |     
 | 
 |  |  |     for i in xrange(curGUIDItemCount):
 | 
 |  |  | 
 |  |  | ##玩家领取补偿物品发放成功
 | 
 |  |  | #  @param curPlayer, GUID
 | 
 |  |  | #  @return None
 | 
 |  |  | def GiveCompensationSuccess(curPlayer, GUID, CompensationType):
 | 
 |  |  | def GiveCompensationSuccess(curPlayer, GUID, CompensationType, isDel=False):
 | 
 |  |  |     curPlayerID = curPlayer.GetID()
 | 
 |  |  |     NotifyCompensationResult(curPlayer, GUID, 1)
 | 
 |  |  |      | 
 |  |  |     SetPrizeState(curPlayerID, GUID, Yet_State, Read_State_Yes) # 设置为已领取
 | 
 |  |  |     #流向记录
 | 
 |  |  |     DataRecordPack.DR_GiveCompensationSuccess(curPlayerID, GUID)
 | 
 |  |  |     if not isDel:
 | 
 |  |  |         SyncQueryCompensationResultByGUID(curPlayer, [GUID])
 | 
 |  |  |         return
 | 
 |  |  |      | 
 |  |  |     NotifyCompensationResult(curPlayer, GUID, 1)
 | 
 |  |  |      | 
 |  |  |     #全服奖励领取记录变更为已领取
 | 
 |  |  |     if CompensationType == Entire_CompensationType:
 | 
 |  |  |         GameWorld.GetCompensationMgr().AddPlayerRec(curPlayerID, GUID, 10 + Yet_State)
 | 
 |  |  |         SetPrizeState(curPlayerID, GUID, Del_State, Read_State_Yes)
 | 
 |  |  |         return
 | 
 |  |  |     #个人奖励领取条目执行删除
 | 
 |  |  |     if CompensationType == Personal_CompensationType:
 | 
 |  |  | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | ##清理超时30天的个人邮件, 否则流失玩家在不断合服情况下数据会累积
 | 
 |  |  | # 个人邮件暂无过期时间设定,只有30天清理逻辑,以创建时间为准
 | 
 |  |  | #  @param None
 | 
 |  |  | #  @return None
 | 
 |  |  | def ClearUpPersonalCompensation():
 | 
 |  |  |     #校验过期补偿
 | 
 |  |  |     tempSign = "<MailTemplate>"
 | 
 |  |  |     tempSignEnd = "</MailTemplate>"
 | 
 |  |  |     curTime = datetime.datetime.today()
 | 
 |  |  |     needClearGUIDList = []
 | 
 |  |  |     allCnt = GameWorld.GetCompensationMgr().GetAllPersonalCompensationCount()
 | 
 |  |  |     for i in xrange(allCnt):
 | 
 |  |  |         curMail = GameWorld.GetCompensationMgr().AtAllPersonalCompensation(i)
 | 
 |  |  |          | 
 |  |  |         mailText = curMail.Text
 | 
 |  |  |         # 通知类模板邮件,过天可直接删除
 | 
 |  |  |         if tempSign in mailText and tempSignEnd in mailText and CheckCanDelCompensation(curMail, curMail.GUID, curMail.PlayerID):
 | 
 |  |  |             tempKey = mailText[mailText.index(tempSign) + len(tempSign):mailText.index(tempSignEnd)]
 | 
 |  |  |             notClearMailKeyList = IpyGameDataPY.GetFuncEvalCfg("MailSet", 1)
 | 
 |  |  |             if tempKey not in notClearMailKeyList:
 | 
 |  |  |                 #GameWorld.DebugLog("过天删除无附件通知类邮件模板! tempKey=%s %s, %s" % (tempKey, curMail.PlayerID, curMail.GUID))
 | 
 |  |  |                 needClearGUIDList.append([curMail.PlayerID, curMail.GUID])
 | 
 |  |  |                 player = GameWorld.GetPlayerManager().FindPlayerByID(curMail.PlayerID)
 | 
 |  |  |                 if player and player.GetInitOK():
 | 
 |  |  |                     NotifyCompensationResult(player, curMail.GUID, 1)
 | 
 |  |  |                 continue
 | 
 |  |  |          | 
 |  |  |         # 超过接收邮件30天则完全删除此邮件
 | 
 |  |  |         limitTime = datetime.datetime.strptime(curMail.CreateTime, ChConfig.TYPE_Time_Format) + datetime.timedelta(days = 30)
 | 
 |  |  |         if limitTime < curTime:
 | 
 |  |  |             needClearGUIDList.append([curMail.PlayerID, curMail.GUID])
 | 
 |  |  |      | 
 |  |  |     GameWorld.Log("ClearUpPersonalCompensation count=%s"%len(needClearGUIDList))
 | 
 |  |  |          | 
 |  |  |     #删除过期补偿信息, 没有主动通知在线玩家
 | 
 |  |  |     for playerID, GUID in needClearGUIDList:
 | 
 |  |  |         ClearPersonalCompensation(playerID, GUID, "Timeout")
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | ## 清理超时补偿, 个人邮件在超过上限后才会自动删除
 | 
 |  |  | #  @param None
 | 
 |  |  | #  @return None
 | 
 |  |  | def ClearUpTimeOutCompensation():
 | 
 |  |  |     
 | 
 |  |  |     ClearUpPersonalCompensation()
 | 
 |  |  |     ClearUpEntireCompensation()
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | 
 |  |  |     #在个人补偿中
 | 
 |  |  |     curPersonalCompensation = GameWorld.GetCompensationMgr().FindPersonalCompensation(curPlayerID, GUID)
 | 
 |  |  |     if curPersonalCompensation.PlayerID == curPlayerID:
 | 
 |  |  |         ClearPersonalCompensation(curPlayerID, GUID)
 | 
 |  |  |         if not CheckCanDelCompensation(curPersonalCompensation, GUID, curPlayerID):
 | 
 |  |  |             #有附件不可删除
 | 
 |  |  |             GameWorld.DebugLog("该个人邮件不可删除: %s" % GUID, curPlayerID)
 | 
 |  |  |             NotifyCompensationResult(curPlayer, GUID, 0)
 | 
 |  |  |             return
 | 
 |  |  |          | 
 |  |  |         ClearPersonalCompensation(curPlayerID, GUID, "ClientDel")
 | 
 |  |  |         NotifyCompensationResult(curPlayer, GUID, 1)
 | 
 |  |  |         #GameWorld.DebugLog("个人补偿中OnDelCompensation:%s"%GUID)
 | 
 |  |  |         return
 | 
 |  |  | 
 |  |  |     #全服邮件
 | 
 |  |  |     curEntireRequire = GameWorld.GetCompensationMgr().FindEntireCompensation(GUID)
 | 
 |  |  |     if curEntireRequire.GUID == GUID:
 | 
 |  |  |         SetPrizeState(curPlayerID, GUID, Disable_State, GameWorld.GetCompensationMgr().FindPlayerRecState(curPlayerID, GUID)/10)
 | 
 |  |  |         if not CheckCanDelCompensation(curEntireRequire, GUID, curPlayerID):
 | 
 |  |  |             #有附件不可删除
 | 
 |  |  |             GameWorld.DebugLog("该全服邮件不可删除: %s" % GUID, curPlayerID)
 | 
 |  |  |             NotifyCompensationResult(curPlayer, GUID, 0)
 | 
 |  |  |             return
 | 
 |  |  |          | 
 |  |  |         SetPrizeState(curPlayerID, GUID, Del_State, GameWorld.GetCompensationMgr().FindPlayerRecState(curPlayerID, GUID)/10)
 | 
 |  |  |         NotifyCompensationResult(curPlayer, GUID, 1)
 | 
 |  |  |         #GameWorld.DebugLog("全服邮件OnDelCompensation:%s"%GUID)
 | 
 |  |  |         return
 | 
 |  |  | 
 | 
 |  |  |     NotifyCompensationResult(curPlayer, GUID, 0)
 | 
 |  |  |         | 
 |  |  | # 有附件的情况玩家不可主动删除邮件,避免误操作;系统可删除不用调用此接口
 | 
 |  |  | def CheckCanDelCompensation(mailObj, GUID, playerID=0):
 | 
 |  |  |     if playerID:
 | 
 |  |  |         if GetPrizeGetState(playerID, GUID) == Yet_State:
 | 
 |  |  |             #GameWorld.DebugLog("已领取的邮件可删除: %s" % GUID, playerID)
 | 
 |  |  |             return True
 | 
 |  |  |          | 
 |  |  |     if mailObj.Gold or mailObj.GoldPaper or mailObj.Silver:
 | 
 |  |  |         # 有附加货币不可删除
 | 
 |  |  |         return False
 | 
 |  |  |      | 
 |  |  |     if GameWorld.GetCompensationMgr().FindItemCount(GUID):
 | 
 |  |  |         # 有附件物品不可删除
 | 
 |  |  |         return False
 | 
 |  |  |     return True
 | 
 |  |  |         
 | 
 |  |  | # 邮件删除情况   
 | 
 |  |  | def NotifyCompensationResult(curPlayer, GUID, result):    
 |