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 | 248 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 241 insertions(+), 7 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py
index 876684c..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
@@ -86,10 +300,10 @@
# @param addItemList [(itemID, itemCnt, 是否拍品), {或物品信息字典}, ...]
# @return GUID
def SendPersonalItemMailEx(title, content, getDays, playerIDList, addItemList, gold = 0, goldPaper = 0, silver = 0,
- detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
+ 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, detail, moneySource)
+ return SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail)
def SendPersonalItemMailBatch(batchMailInfoList):
## 批量发送邮件
@@ -123,14 +337,14 @@
return
def SendMailByKey(mailTypeKey, playerIDList, addItemList, paramList=[], gold=0, goldPaper=0, silver=0,
- detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
+ 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, 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, moneySource)
+ return SendPersonalItemMailEx(title, content, 30, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail)
def CrossServerMsg_SendMail(msgData):
## 收到跨服服务器同步的发送邮件
@@ -147,7 +361,7 @@
# @return GUID
# @remarks addItemList支持append字典
def SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold = 0, goldPaper = 0, silver = 0,
- detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
+ detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
if not playerIDList:
return ""
@@ -181,11 +395,13 @@
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, detail, moneySource)
+ gold, goldPaper, silver, detail, moneySource, crossMail)
return GUID
## 发送纯文字个人补偿
@@ -514,8 +730,11 @@
## 添加个人补偿
# @param addItemDict, PlayerIDList, LimitTime, Text
# @return None
-def AddPersonalItem(GUID, addItemDictList, PlayerIDList, LimitTime, Text, gold = 0, goldPaper = 0, silver = 0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
+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))
@@ -633,6 +852,7 @@
# 提取接收邮件下发
def NotifyPlayerCompensation(curPlayer):
+ RequestToGetCrossMail(curPlayer)
notifyList = SeekPlayerCompensation(curPlayer)
SyncQueryCompensationResult(curPlayer, notifyList)
return
@@ -969,11 +1189,25 @@
# @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:
--
Gitblit v1.8.0