From d196d101b54ca95a1343399841d6b4e1117143b7 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 04 六月 2025 14:53:08 +0800
Subject: [PATCH] 16 卡牌服务端(GMT命令个人邮件、全服邮件相关;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationQuery.py         |   84 +++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddPersonalCompensation.py   |   80 +++++---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationQueryPersonal.py |   93 ++++++++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DataRecordPack.py                                                      |   10 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddEntireCompensation.py     |   54 ++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/ProjSpecialProcess.py                     |   88 +++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py                                              |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMail.py                                                   |   28 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBMail.py                                                |   19 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationMgr.py           |   49 +++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Mail.py                                                    |    6 
 11 files changed, 450 insertions(+), 63 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py
index 582d745..fee72a3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py
@@ -302,6 +302,8 @@
         self.__memberList.append(member)
         return member
     
+    def GetMemberIDList(self): return self.__memberDict.keys()
+    
     def AddMember(self, playerID):
         member = None
         if playerID in self.__memberDict:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBMail.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBMail.py
index 561d085..f86f89c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBMail.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBMail.py
@@ -254,13 +254,32 @@
             itemObj = MailItem()
         return itemObj
     
+    def GetMailItemList(self, guid):
+        if guid not in self.__mailItemDict:
+            return []
+        itemList = []
+        for mailItem in self.__mailItemDict[guid]:
+            itemID = mailItem.GetItemID()
+            itemCount = mailItem.GetCount()
+            isBind = mailItem.GetIsBind()
+            userData = mailItem.GetUserData()
+            itemInfo = [itemID, itemCount, isBind]
+            if userData:
+                itemInfo.append(userData)
+            itemList.append(itemInfo)
+        return itemList
+    
     def AddServerMail(self, guid, title, text, itemList, limitDays=7, mailType=0):
         '''添加个人邮件
         @param guid: 指定的邮件guid,为空时自动生成新guid
         @param itemList: 元素支持字典{k:v, ...} 或列表 [itemID, itemCount, 可选是否拍品, 物品UserData]
         '''
+        mailObj = None
         if not guid:
             guid = GameWorld.GetGUID()
+        if guid in self.__serverMailDict:
+            # 已经存在的guid不允许重复插入全服邮件,防止多领取,后台发送全服邮件时如果重复推送到某个服务器就可能存在重复情况
+            return mailObj
         dbData = DBStruct.tagDBMailServer()
         dbData.GUID = guid
         dbData.Type = mailType
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DataRecordPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DataRecordPack.py
index 014408a..f9cc3d6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DataRecordPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DataRecordPack.py
@@ -1493,8 +1493,16 @@
     SendEventPack("MailDel", dataDict)
     return 
 
+def DR_ServerMail(GUID, eventName, addDict={}):
+    ## 全服邮件流向
+    dataDict = {'GUID':GUID, "eventName":eventName}
+    dataDict.update(addDict)
+    SendEventPack("MailServerMail", dataDict)
+    return
+
 def DR_CreateRole(playerData):
     dataDict = {'PlayerID':playerData.PlayerID, 'AccID':playerData.AccID, 'PlayerName':playerData.PlayerName, "Job":playerData.Job}
     #发送封包
     SendEventPack("CreateRole", dataDict)
-    return
\ No newline at end of file
+    return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Mail.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Mail.py
index 78412de..eb1d801 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Mail.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Mail.py
@@ -122,15 +122,13 @@
         DataRecordPack.DR_MailDel(playerID, guid, "GMDel")
         notifyGUIDState[guid] = ShareDefine.MailState_Del
     GameWorld.DebugAnswer(curPlayer, "删除个人邮件:%s" % len(guidList))
+    PlayerMail.Sync_PlayerMailState(curPlayer, notifyGUIDState)
     
     guidList = mailMgr.GetServerMailGuids()
     for guid in guidList:
-        playerStateDict = mailMgr.DelServerMail(guid)
-        if playerID in playerStateDict and playerStateDict[playerID] < ShareDefine.MailState_Del:
-            notifyGUIDState[guid] = ShareDefine.MailState_Del
+        PlayerMail.DelServerMail(guid, "GMDel")
     if len(guidList):
         GameWorld.DebugAnswer(curPlayer, "删除全服邮件:%s" % len(guidList))
-    PlayerMail.Sync_PlayerMailState(curPlayer, notifyGUIDState)
     return
 
 def PrintPlayerMail(curPlayer):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMail.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMail.py
index c6118c8..184f1f3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMail.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMail.py
@@ -56,13 +56,15 @@
             #GameWorld.DebugLog("全服邮件未超时,不删除! %s,createTime=%s,limitTime=%s" % (guid, mailObj.GetCreateTime(), GameWorld.ChangeTimeNumToStr(limitTime)))
             continue
         
-        DelServerMail(guid)
+        DelServerMail(guid, "Timeout")
         
     return
 
-def DelServerMail(guid):
+def DelServerMail(guid, delEvent=""):
+    GameWorld.Log("删除全服邮件: %s" % (guid))
     mailMgr = DBDataMgr.GetMailMgr()
     playerStateDict = mailMgr.DelServerMail(guid)
+    DataRecordPack.DR_ServerMail(guid, "Delete" + delEvent)
     if not playerStateDict:
         return
     playerMgr = GameWorld.GetPlayerManager()
@@ -175,15 +177,23 @@
     @param limitLV: 限制可领的最低等级
     @param limitLVType: 等级达到后是否可领,默认不可
     @param checkState: 是否需要审核,默认不需要
+    @return: None - 发送失败; mailObj - 成功发送的邮件实例
     '''
     mailMgr = DBDataMgr.GetMailMgr()
     mailObj = mailMgr.AddServerMail(guid, title, text, itemList, limitDays, mailType)
+    if not mailObj:
+        return mailObj
+    GUID = mailObj.GetGUID()
     mailObj.SetLimitLV(limitLV)
     mailObj.SetLimitLVType(limitLVType)
     mailObj.SetCheckState(checkState)
+    eventName = "Add" if not checkState else "AddToCheck"
+    addDict = {"LimitDays":limitDays, "LimitLV":limitLV, "LimitLVType":limitLVType, "CheckState":checkState, 
+               "title":title, "Text":text, "ItemList":itemList}
+    DataRecordPack.DR_ServerMail(GUID, eventName, addDict)
     if not checkState:
         Sync_ServerMail(mailObj.GetGUID())
-    return
+    return mailObj
 
 def CheckServerMailResult(guid, isOK):
     ## 审核全服邮件结果
@@ -193,8 +203,12 @@
     if not mailObj:
         return
     if not isOK:
+        # 审核不通过的直接删除
+        DelServerMail(guid, "GMDel")
         return
+    GameWorld.Log("全服邮件审核通过: %s" % guid)
     mailObj.SetCheckState(0) # 设置为0,不需要审核了,即通过
+    DataRecordPack.DR_ServerMail(guid, "CheckOK")
     Sync_ServerMail(guid)
     return
 
@@ -325,11 +339,12 @@
     Sync_PlayerMailState(curPlayer, notifyGUIDState)
     return
 
-def doMailDel(curPlayer, guid, isGM=False):
+def doMailDel(curPlayer, guid, isGM=False, playerID=0):
     ## 执行邮件删除
     # @param isGM: 是否GM删除,无视物品是否已领取,强制删除
     
-    playerID = curPlayer.GetPlayerID()
+    if curPlayer:
+        playerID = curPlayer.GetPlayerID()
     mailMgr = DBDataMgr.GetMailMgr()
     
     # 批量处理,仅针对个人邮件
@@ -357,7 +372,8 @@
             DataRecordPack.DR_MailDel(playerID, guid, "GMDel")
         # 这里玩家主动删除的可不记录流向,因为未读未领取不允许主动删除,已领取的已有领取记录,所以可不记录
         
-    Sync_PlayerMailState(curPlayer, notifyGUIDState)
+    if curPlayer:
+        Sync_PlayerMailState(curPlayer, notifyGUIDState)
     return
 
 def Sync_ServerMail(guid):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddEntireCompensation.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddEntireCompensation.py
new file mode 100644
index 0000000..7db024e
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddEntireCompensation.py
@@ -0,0 +1,54 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package PyMongoDB.GMToolLogicProcess.Commands.GMT_AddEntireCompensation
+#
+# @todo:GM工具命令 - 添加全服邮件
+# @author hxp
+# @date 2025-06-04
+# @version 1.0
+#
+# 详细描述: GM工具命令 - 添加全服邮件
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-06-04 15:00"""
+#-------------------------------------------------------------------------------
+
+import PlayerMail
+import DataRecordPack
+import GMT_AddPersonalCompensation
+import GMCommon
+
+## 执行逻辑
+#  @param curPlayer 当前玩家
+#  @param gmCmdDict: 命令字典
+#  @return None
+#  @remarks 函数详细说明.
+def OnExec(gmCmdDict):
+    
+    LimitDays = int(gmCmdDict.get('LimitDays', '7'))
+    MailType = int(gmCmdDict.get('MailType', '0'))
+    Title = gmCmdDict.get('Title', '')
+    Text = gmCmdDict.get('Text', '')
+    GUID = gmCmdDict.get('GUID', '') # GM工具需要对全服邮件进行多服批量管理,所以这里GUID暂由GM工具决定
+    
+    if GUID.startswith("{") and GUID.endswith("}"):
+        GUID = GUID[1:-1]
+    if not GUID:
+        return GMCommon.Def_ParamErr
+    
+    limitLV = min(99999, int(gmCmdDict.get('PlayerLV', '0'))) # 支持的最大等级
+    limitLVType = int(gmCmdDict.get('LimitLVType', '0')) # 原先未达到邮件领取等级的玩家之后升级上来是否可领取邮件, 默认0-不可,1-可以
+    checkState = int(gmCmdDict.get('CheckState', '0')) # 邮件审核状态,为兼容老邮件,默认0-已审核,1-未审核
+    itemList = GMT_AddPersonalCompensation.GetGMTMailItemList(gmCmdDict)
+    
+    mailObj = PlayerMail.SendSeverMail(GUID, Title, Text, itemList, LimitDays, MailType, limitLV, limitLVType, checkState)
+    if not mailObj:
+        return GMCommon.Def_ParamErr, "GUID is exist."
+    
+    # 流向
+    GMT_Name = gmCmdDict.get(GMCommon.Def_GMKey_Type, '')
+    DataRecordPack.DR_ToolGMOperate(0, '', '', GMT_Name, str(gmCmdDict))
+    return GMCommon.Def_Success, {"GUID":GUID}
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddPersonalCompensation.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddPersonalCompensation.py
index af490fd..70d7893 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddPersonalCompensation.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddPersonalCompensation.py
@@ -2,45 +2,69 @@
 # -*- coding: GBK -*-
 #-------------------------------------------------------------------------------
 #
-#-------------------------------------------------------------------------------
+##@package PyMongoDB.GMToolLogicProcess.Commands.GMT_AddPersonalCompensation
 #
-##@package PyMongoDataServer.GMToolLogicProcess.Commands.GMT_AddPersonalCompensation
-#
-# @todo:个人补偿 - 新
+# @todo:GM工具命令 - 添加个人邮件
 # @author hxp
-# @date 2014-09-23
+# @date 2025-06-04
 # @version 1.0
 #
-# 详细描述: 个人补偿 - 新
+# 详细描述: GM工具命令 - 添加个人邮件
 #
-#---------------------------------------------------------------------
-"""Version = 2014-09-23 12:00"""
+#-------------------------------------------------------------------------------
+#"""Version = 2025-06-04 15:00"""
+#-------------------------------------------------------------------------------
 
+import GameWorld
 import GMCommon
-#---------------------------------------------------------------------
-#全局变量
-
-#---------------------------------------------------------------------
-
+import DataRecordPack
+import PlayerMail
 
 ## 收到gm命令执行
 # @param gmCmdDict:gm命令字典
 # @return None 
 def OnExec(gmCmdDict):
-    playerList = gmCmdDict.get("playerList", "")  #玩家列表
+    from GMToolLogicProcess import  ProjSpecialProcess
+    ret = ProjSpecialProcess.GMCmdPlayerListValidationID(gmCmdDict)
+    Result = ret[0]
+    if Result != GMCommon.Def_Success:
+        return Result, ret[1]
+    playerIDList = ret[1]
     
-    if playerList == "":
-        return GMCommon.Def_ParamErr, "Please enter search player info!"               
+    LimitDays = int(gmCmdDict.get('LimitDays', '7'))
+    MailType = int(gmCmdDict.get('MailType', '0'))
+    Title = gmCmdDict.get('Title', '')
+    Text = gmCmdDict.get('Text', '')
+    itemList = GetGMTMailItemList(gmCmdDict)
+    
+    for playerID in playerIDList:
+        PlayerMail.SendMail(playerID, Title, Text, itemList, LimitDays, MailType)
+        
+    # 流向
+    GMT_Name = gmCmdDict.get(GMCommon.Def_GMKey_Type, '')
+    DataRecordPack.DR_ToolGMOperate(0, '', '', GMT_Name, str(gmCmdDict))
+    return GMCommon.Def_Success
 
-    # 回复gm参数错误
-    return GMCommon.Def_DoQueryUserDB, ''
-
-## 查询userdb返回
-# @param userdb:userdb
-# @param data:传入的信息
-# @param gmCmdDict:gm命令字典
-# @return None 
-def UserDBResponse(userdb, data, gmCmdDict):
-    return GMCommon.Def_SendToGameServer, ''
-
-
+def GetGMTMailItemList(gmCmdDict):
+    
+    #工具发过来的物品下标依据 'index,index,...'  不一定是从0开始并按顺序连续 =_=#
+    intemIndexStrList = []
+    itemNums = gmCmdDict.get('itemNums', '')
+    if itemNums.strip() != '':
+        intemIndexStrList = itemNums.split(',')
+    #添加物品
+    itemList = []
+    for itemIndexStr in intemIndexStrList:
+        itemID = GameWorld.ToIntDef(gmCmdDict.get('ItemID%s' % itemIndexStr, '0'))
+        if not itemID:
+            continue
+        itemCount = GameWorld.ToIntDef(gmCmdDict.get('ItemCnt%s' % itemIndexStr, '0'))
+        if not itemCount:
+            continue
+        isBind = GameWorld.ToIntDef(gmCmdDict.get('IsBind%s' % itemIndexStr, '0'))
+        
+        #添加到物品信息列表
+        itemList.append([itemID, itemCount, isBind])
+        
+    GameWorld.DebugLog("GetGMTMailItemList %s" % itemList)
+    return itemList
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationMgr.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationMgr.py
new file mode 100644
index 0000000..de90509
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationMgr.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package PyMongoDB.GMToolLogicProcess.Commands.GMT_CompensationMgr
+#
+# @todo:GM工具命令 - 全服邮件管理
+# @author hxp
+# @date 2025-06-04
+# @version 1.0
+#
+# 详细描述: GM工具命令 - 全服邮件管理
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-06-04 15:00"""
+#-------------------------------------------------------------------------------
+
+import GMCommon
+import GameWorld
+import DataRecordPack
+import PlayerMail
+
+## 执行逻辑
+#  @param curPlayer 当前玩家
+#  @param gmCmdDict: 命令字典
+#  @return None
+#  @remarks 函数详细说明.
+def OnExec(gmCmdDict):
+    
+    GUIDInfo = gmCmdDict.get('GUIDInfo', '')
+    operation = GameWorld.ToIntDef(gmCmdDict.get('operation', 0)) # 1-通过;2-删除
+    if not GUIDInfo:
+        return GMCommon.Def_ParamErr
+    operGUIDList = GUIDInfo.split(",")
+    if not operGUIDList:
+        return GMCommon.Def_ParamErr
+    
+    if operation not in [1, 2]:
+        return GMCommon.Def_ParamErr
+    
+    isOK = (operation == 1)
+    for GUID in operGUIDList:
+        PlayerMail.CheckServerMailResult(GUID, isOK)
+        
+    #流向
+    GMT_Name = gmCmdDict.get(GMCommon.Def_GMKey_Type, '') 
+    DataRecordPack.DR_ToolGMOperate(0, '', '', GMT_Name, str(gmCmdDict))
+    return GMCommon.Def_Success
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationQuery.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationQuery.py
new file mode 100644
index 0000000..5b75d84
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationQuery.py
@@ -0,0 +1,84 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package PyMongoDB.GMToolLogicProcess.Commands.GMT_CompensationQuery
+#
+# @todo:GM工具命令 - 全服邮件查询
+# @author hxp
+# @date 2025-06-04
+# @version 1.0
+#
+# 详细描述: GM工具命令 - 全服邮件查询
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-06-04 15:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import DBDataMgr
+import GMCommon
+
+## 执行逻辑
+#  @param curPlayer 当前玩家
+#  @param gmCmdDict: 命令字典
+#  @return None
+#  @remarks 函数详细说明.
+def OnExec(gmCmdDict):
+    
+    fromDate = gmCmdDict.get('FromDate', '')
+    toDate = gmCmdDict.get('ToDate', '')
+    guid = gmCmdDict.get('GUID', '')
+    searchTitle = gmCmdDict.get('SearchTitle', '')
+    searchContent = gmCmdDict.get('SearchContent', '')
+    searchState = GameWorld.ToIntDef(gmCmdDict.get('SearchState')) # 0-全部;1-通过;2-未审
+    if searchState == 1:
+        searchState = 0
+    elif searchState == 2:
+        searchState = 1
+    else:
+        searchState = None
+    maxCount = GameWorld.ToIntDef(gmCmdDict.get('MaxCount', ''), 5)
+    maxCount = min(50, maxCount)
+    
+    mailMgr = DBDataMgr.GetMailMgr()
+    queryRetList = []
+    if guid:
+        mailObj = mailMgr.GetServerMail(guid)
+        queryRetList.append(__getServerMailInfo(mailObj, mailMgr.GetMailItemList(guid)))
+    else:
+        if fromDate:
+            fromDate = "%s 00:00:00" % fromDate
+        if toDate:
+            toDate = "%s 23:59:59" % toDate
+            
+        for guid in mailMgr.GetServerMailGuids():
+            mailObj = mailMgr.GetServerMail(guid)
+            if fromDate and mailObj.GetCreateTime() < fromDate:
+                continue
+            
+            if toDate and mailObj.GetCreateTime() > toDate:
+                continue
+            
+            if searchTitle and searchTitle not in mailObj.GetTitle():
+                continue
+            
+            if searchContent and searchContent not in mailObj.GetText():
+                continue
+            
+            if searchState != None and searchState != mailObj.GetCheckState():
+                continue
+            
+            queryRetList.append(__getServerMailInfo(mailObj, mailMgr.GetMailItemList(guid)))
+            if len(queryRetList) >= maxCount:
+                break
+            
+        queryRetList.sort(key=lambda m:(m["CreateTime"]), reverse=True)
+        
+    return GMCommon.Def_Success, queryRetList
+
+def __getServerMailInfo(mailObj, itemList):
+    return {"GUID":mailObj.GetGUID(), "CheckState":mailObj.GetCheckState(), "LimitLVType":mailObj.GetLimitLVType(), 
+            "LimitLV":mailObj.GetLimitLV(), "MailType":mailObj.GetType(), "Title":mailObj.GetTitle(), "Content":mailObj.GetText(),
+            "CreateTime":mailObj.GetCreateTime(), "LimitDays":mailObj.GetLimitDays(), "ItemList":itemList}
+    
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationQueryPersonal.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationQueryPersonal.py
index 0fb9a73..3bee2aa 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationQueryPersonal.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CompensationQueryPersonal.py
@@ -2,39 +2,90 @@
 # -*- coding: GBK -*-
 #-------------------------------------------------------------------------------
 #
-##@package PyMongoDataServer.GMToolLogicProcess.Commands.GMT_CompensationQueryPersonal
+##@package PyMongoDB.GMToolLogicProcess.Commands.GMT_CompensationQueryPersonal
 #
-# @todo:个人补偿查询管理
+# @todo:GM工具命令 - 个人邮件查询管理
 # @author hxp
-# @date 2020-12-21
+# @date 2025-06-04
 # @version 1.0
 #
-# 详细描述: 个人补偿查询管理
+# 详细描述: GM工具命令 - 个人邮件查询管理
 #
 #-------------------------------------------------------------------------------
-#"""Version = 2020-12-21 19:00"""
+#"""Version = 2025-06-04 15:00"""
 #-------------------------------------------------------------------------------
 
 import GMCommon
+import GameWorld
+import DataRecordPack
+import PlayerMail
+import DBDataMgr
 
 ## 收到gm命令执行
 # @param gmCmdDict:gm命令字典
 # @return None 
 def OnExec(gmCmdDict):
-    playerList = gmCmdDict.get("playerList", "")  #玩家列表
     
-    if playerList == "":
-        return GMCommon.Def_ParamErr, "Please enter search player info!"               
-
-    # 回复gm参数错误
-    return GMCommon.Def_DoQueryUserDB, ''
-
-## 查询userdb返回
-# @param userdb:userdb
-# @param data:传入的信息
-# @param gmCmdDict:gm命令字典
-# @return None 
-def UserDBResponse(userdb, data, gmCmdDict):
-    return GMCommon.Def_SendToGameServer, ''
-
-
+    errorMsg = ""
+    from GMToolLogicProcess import  ProjSpecialProcess
+    Result, playerID = ProjSpecialProcess.GMCmdPlayerValidationID(gmCmdDict)
+    if Result != GMCommon.Def_Success:
+        return Result, errorMsg
+    
+    Result = GMCommon.Def_Unknow
+    
+    opType = gmCmdDict.get('opType', 'query')
+    
+    # 暂仅做删除及查询
+    if opType == "del":
+        GUIDInfo = gmCmdDict.get('GUIDInfo', '')
+        if not GUIDInfo:
+            return GMCommon.Def_ParamErr
+        
+        delGUIDList = GUIDInfo.split(",")
+        if not delGUIDList:
+            return GMCommon.Def_ParamErr
+        
+        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+        for delGUID in delGUIDList:
+            PlayerMail.doMailDel(curPlayer, delGUID, True, playerID)
+            
+    else:
+        pass
+    
+    mailList = __queryMailInfoList(playerID)
+    
+    #流向
+    if opType == "del":
+        GMT_Name = gmCmdDict.get(GMCommon.Def_GMKey_Type, '') 
+        DataRecordPack.DR_ToolGMOperate(0, '', '', GMT_Name, str(gmCmdDict))
+    return GMCommon.Def_Success, {"mailList":mailList}
+    
+def __queryMailInfoList(playerID):
+    '''个人补偿邮件查询
+    '''
+    
+    mailList = []
+    mailMgr = DBDataMgr.GetMailMgr()
+    guids = mailMgr.GetPersonalMailGuids(playerID)
+    for guid in guids:
+        mailObj = mailMgr.GetPersonalMail(playerID, guid)
+        if not mailObj:
+            continue
+        title = mailObj.GetTitle()
+        content = mailObj.GetText()
+        mailType = mailObj.GetType()
+        createTime = mailObj.GetCreateTime()
+        limitDays = mailObj.GetLimitDays()
+        mailState = mailObj.GetMailState()
+        
+        if "<T>" in title:
+            title = title[3:-4]
+            
+        itemList = mailMgr.GetMailItemList(guid)
+        infoDict = {"GUID":guid, "Title":title, "Content":content, "State":mailState, "MailType":mailType,
+                    "CreateTime":createTime, "LimitDays":limitDays, "ItemList":itemList}
+        mailList.append(infoDict)
+        
+    mailList.sort(key=lambda m:(m["CreateTime"]), reverse=True)
+    return mailList
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/ProjSpecialProcess.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/ProjSpecialProcess.py
index aebce44..066fc38 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/ProjSpecialProcess.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/ProjSpecialProcess.py
@@ -44,6 +44,7 @@
 import PlayerOfflineSupport
 import PyGameData
 import GameWorld
+import DBDataMgr
       
 ################################################################## 
                 ####### python逻辑入口 ####### 
@@ -155,6 +156,82 @@
 
 ################################################################## 
 
+def GMCmdPlayerListValidationID(gmCmdDict):
+    '''后台GM工具玩家列表命令通用验证
+    @param gmCmdDict: 命令参数字典
+    @return: GMCommon.Def_xxx, idList or errorInfo
+                                非 Def_Success 的错误类型        -    代表错误,可直接返回给后台
+            Def_Success, playerIDList    -  待处理的玩家ID列表
+    '''
+    playerList = gmCmdDict.get("playerList", '')
+    playerList = playerList.split(",")
+    if not playerList:
+        return GMCommon.Def_ParamErr, ""
+    
+    playerIDList = []
+    queryType = gmCmdDict.get(GMCommon.Def_GMKey_QueryType, '')    
+    if queryType in [GMCommon.Def_GMKey_PlayerName, GMCommon.Def_GMKey_PlayerAccID]:
+        for playerFind in playerList:
+            if queryType == GMCommon.Def_GMKey_PlayerName:
+                rec = PyGameData.g_usrCtrlDB.findDBPlayerByName(playerFind)
+            elif queryType == GMCommon.Def_GMKey_PlayerAccID:
+                rec = PyGameData.g_usrCtrlDB.findDBPlayerByAccID(playerFind)
+            else:
+                continue
+            
+            if not rec:
+                # db找不到就是不存在该玩家
+                return GMCommon.Def_NoTag, "%s can not found!" % str(playerFind)
+            
+            playerID = rec.get(u'PlayerID', 0)
+            playerIDList.append(playerID)
+            
+    elif queryType == GMCommon.Def_GMKey_FamilyID:
+        # 根据家族ID的直接返回
+        familyMgr = DBDataMgr.GetFamilyMgr()
+        for familyID in eval(playerList):
+            familyID = GameWorld.ToIntDef(familyID)
+            family = familyMgr.FindFamily(familyID)
+            if not family:
+                GameWorld.DebugLog("    not family %s" % familyID)
+                continue
+            memberIDList = family.GetMemberIDList()
+            playerIDList += memberIDList
+            
+    if not playerIDList:
+        return GMCommon.Def_ParamErr, ""
+    
+    return GMCommon.Def_Success, playerIDList
+
+def GMCmdPlayerValidationID(gmCmdDict):
+    '''后台GM工具玩家命令通用验证
+    @param gmCmdDict: 命令参数字典
+    @return: GMCommon.Def_xxx, playerID
+                                非 Def_Success 的错误类型        -    代表错误,可直接返回给后台
+            Def_Success, playerID    -    本服玩家ID
+    '''
+    
+    queryType = gmCmdDict.get(GMCommon.Def_GMKey_QueryType, '')
+    playerFind = gmCmdDict.get(GMCommon.Def_GMKey_PlayerFind, '')
+    
+    if len(playerFind) <= 0:
+        return GMCommon.Def_ParamErr, None
+    
+    # 玩家姓名
+    if queryType == GMCommon.Def_GMKey_PlayerName:
+        rec = PyGameData.g_usrCtrlDB.findDBPlayerByName(playerFind)
+    elif queryType == GMCommon.Def_GMKey_PlayerAccID:
+        rec = PyGameData.g_usrCtrlDB.findDBPlayerByAccID(playerFind)
+    else:
+        return GMCommon.Def_ParamErr, None
+    
+    if not rec:
+        # db找不到就是不存在该玩家
+        return GMCommon.Def_NoTag, None
+    
+    playerID = rec.get(u'PlayerID', 0)
+    return GMCommon.Def_Success, playerID
+
 def GMCmdPlayerValidation(gmCmdDict, offlineSupport=True):
     '''后台GM工具玩家命令通用验证
     @param gmCmdDict: 命令参数字典
@@ -239,11 +316,16 @@
     def GMToolCommand(self):
         callFunc = GetExecFunc(Commands, "%s.%s"%(self.funcName, "OnExec"))
         
-        execType = GMCommon.Def_SendToGameServer
+        execType = GMCommon.Def_Unknow
         execInfo = ''
         if callFunc != None:
-            execType, execInfo = callFunc(self.gmCmdDict)
-        
+            ret = callFunc(self.gmCmdDict)
+            if isinstance(ret, int):
+                execType = ret
+            elif isinstance(ret, tuple):
+                execType = ret[0]
+                execInfo = ret[1]
+                
         GetGMOrderMgr().PopCmd(self.orderId)
         GMCommandResult(self.orderId, self.funcName, execType, execInfo)
         

--
Gitblit v1.8.0