From d7b7ed5eff26ceb650ccbe3482a31bed773a3c8d Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 24 六月 2021 16:55:32 +0800
Subject: [PATCH] 8921 【主干】【BT2】【后端】H.活动-节日活动-垃圾分类(仙匣秘境限制最大层数99)
---
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py | 491 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 438 insertions(+), 53 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py
index 7f5901b..008819d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py
@@ -28,12 +28,16 @@
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
@@ -68,6 +72,216 @@
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
@@ -76,24 +290,24 @@
#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 = batchMailInfoList
lenPlayerID = len(batchPlayerIDList)
lenItem = len(batchAddItemList)
@@ -109,6 +323,8 @@
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
@@ -116,26 +332,36 @@
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)
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
# 此处货币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):
if not playerIDList:
return ""
@@ -156,36 +382,37 @@
if len(itemInfo) == 3:
- itemID, itemCnt, isBind = itemInfo
+ itemID, itemCnt, isAuctionItem = itemInfo
else:
continue
addItemDict = {}
addItemDict['ItemID'] = itemID
addItemDict['Count'] = itemCnt
- addItemDict['IsBind'] = isBind
+ addItemDict['IsAuctionItem'] = isAuctionItem
addItemDictList.append(addItemDict)
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)
+ 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):
if GameWorld.IsCrossServer():
return
GUID = str(uuid.uuid1())
PyAddPersonalCompensation(GUID, PlayerID, GameWorld.GetCurrentDataTimeStr(), limitTime,
- "%s<$_$>%s<$_$>%s" % (ChConfig.Def_Mail_SenderSys,title, content), sourceType)
+ "%s<$_$>%s<$_$>%s" % (ChConfig.Def_Mail_SenderSys,title, content))
return
def GetEntireCompensationInfo(checkState, limitLVType, limitLV):
@@ -196,8 +423,51 @@
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
+
+ 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,
+ "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()
@@ -264,7 +534,7 @@
compensationDict = {"GUID":GUID, "CheckState":checkState, "LimitLVType":limitLVType, "LimitLV":limitLV,
"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
@@ -326,6 +596,54 @@
return successGUIDList
+def SendEntireMail(mailTypeKey, getDays, limitLV, limitLVType, addItemList=[], paramList=[], \
+ gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail, GUID=""):
+ ''' 发送全服邮件
+ @param mailTypeKey: 邮件模板key
+ @param getDays: 有效天数
+ @param limitLV: 领取最低等级限制
+ @param limitLVType: 等级不足的升级后是否可领 0-不可,1-可以
+ '''
+
+ if not mailTypeKey or getDays <= 0:
+ return
+
+ addItemDictList = []
+ for itemInfo in addItemList:
+ if isinstance(itemInfo, dict):
+ addItemDictList.append(itemInfo)
+ continue
+
+ if len(itemInfo) == 3:
+ itemID, itemCnt, isAuctionItem = itemInfo
+ else:
+ continue
+
+ addItemDict = {}
+ addItemDict['ItemID'] = itemID
+ addItemDict['Count'] = itemCnt
+ addItemDict['IsAuctionItem'] = isAuctionItem
+ addItemDictList.append(addItemDict)
+
+ 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, "%s<$_$>%s<$_$>%s" % (sender, title, content),
+ gold, goldPaper, silver, detail, serverID)
+ return
+
## 添加全服补偿
# @param addItemDictList, LimitTime, mailInfo, PlayerJob, Text
# @return None
@@ -378,38 +696,33 @@
# 检查邮件是否已达到保存上限,如超过则先删除旧邮件
# @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)
#先取得要删除的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:
+ for i in xrange(delCount):
+ curIpyPersonalData = GameWorld.GetCompensationMgr().PersonalCompensationAt(PlayerID, i)
+ delGUIDs.append(curIpyPersonalData.GUID)
+
+ for guid in delGUIDs:
ClearPersonalCompensation(PlayerID, guid)
- #GameWorld.DebugLog("PyAddPersonalCompensation DeletePersonalCompensation GUID = %s"%guid)
+ 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,存值时需要处理下
GameWorld.GetCompensationMgr().AddPersonalCompensation(GUID, PlayerID, CreateTime,
- LimitTime, Text, sourceType, gold, goldPaper, silver)
+ LimitTime, Text, mailType, gold, goldPaper, silver)
return
@@ -417,9 +730,11 @@
## 添加个人补偿
# @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))
@@ -433,8 +748,7 @@
#批量添加玩家个人补偿领取表
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:
@@ -454,7 +768,7 @@
#添加流向
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
@@ -538,6 +852,7 @@
# 提取接收邮件下发
def NotifyPlayerCompensation(curPlayer):
+ RequestToGetCrossMail(curPlayer)
notifyList = SeekPlayerCompensation(curPlayer)
SyncQueryCompensationResult(curPlayer, notifyList)
return
@@ -615,6 +930,11 @@
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:
SetPrizeState(curPlayerID, curRequire.GUID, Enable_State, readState)
@@ -680,7 +1000,6 @@
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)
@@ -690,7 +1009,7 @@
# return
#===========================================================================
#发送到MapServer给予奖励
- SendGMRequestCompensationResult(routeIndex, mapID, curPlayer, GUID, compensationType, Text, gold, goldPaper, silver)
+ SendGMRequestCompensationResult(routeIndex, mapID, curPlayer, GUID, compensationType, curEntireRequire)
GameWorld.DebugLog("Compensation### OnMGRequestCompensation out")
##请求领取物品
@@ -766,17 +1085,24 @@
##发送封包 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):
@@ -857,11 +1183,49 @@
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):
+ #tempKey = mailText[mailText.index(tempSign) + len(tempSign):mailText.index(tempSignEnd)]
+ #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)
+ return
+
## 清理超时补偿, 个人邮件在超过上限后才会自动删除
# @param None
# @return None
def ClearUpTimeOutCompensation():
+ ClearUpPersonalCompensation()
ClearUpEntireCompensation()
return
@@ -917,6 +1281,11 @@
#在个人补偿中
curPersonalCompensation = GameWorld.GetCompensationMgr().FindPersonalCompensation(curPlayerID, GUID)
if curPersonalCompensation.PlayerID == curPlayerID:
+ if not CheckCanDelCompensation(curPersonalCompensation, GUID):
+ #有附件不可删除
+ NotifyCompensationResult(curPlayer, GUID, 0)
+ return
+
ClearPersonalCompensation(curPlayerID, GUID)
NotifyCompensationResult(curPlayer, GUID, 1)
#GameWorld.DebugLog("个人补偿中OnDelCompensation:%s"%GUID)
@@ -932,12 +1301,28 @@
#全服邮件
curEntireRequire = GameWorld.GetCompensationMgr().FindEntireCompensation(GUID)
if curEntireRequire.GUID == GUID:
+ if not CheckCanDelCompensation(curEntireRequire, GUID):
+ #有附件不可删除
+ NotifyCompensationResult(curPlayer, GUID, 0)
+ return
+
SetPrizeState(curPlayerID, GUID, Disable_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):
+ 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):
--
Gitblit v1.8.0