10192 【越南】【主干】【港台】【砍树】上线增加膜拜主动推送(增加膜拜功能,目前支持跨服排位赛名次及服务器冠名膜拜;增加GameServer玩家记录表;玩家缓存增加记录佩戴称号ID)
20个文件已修改
4个文件已添加
1792 ■■■■■ 已修改文件
PySysDB/PySysDBG.h 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/PyNetPack.ini 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_Worship.py 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorship.py 521 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GiveAward.py 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBG.h
@@ -1276,6 +1276,17 @@
    BYTE        AssistAwardCount;    // 协助奖励每日次数
};
//膜拜表
struct tagWorship
{
    BYTE        _WorshipType;    //膜拜类型
    DWORD        _WorshipValue;    //膜拜值
    BYTE        WorshipDays;    //膜拜天数
    BYTE        MoneyType;    //膜拜货币类型
    list        MoneyRange;    //货币值范围
};
//缥缈仙域表
struct tagFairyDomain
ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
@@ -541,6 +541,17 @@
PacketSubCMD_1=0x07
PacketCallFunc_1=OnVoiceChat
[GameWorship]
ScriptName = GameWorldLogic\GameWorship.py
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 1
PacketCMD_1=0xB0
PacketSubCMD_1=0x20
PacketCallFunc_1=OnWorship
[GameWorldMineArea]
ScriptName = GameWorldLogic\GameWorldMineArea.py
Writer = hxp
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -2382,6 +2382,66 @@
#------------------------------------------------------
# B0 20 请求膜拜玩家 #tagCGWorship
class  tagCGWorship(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("PlayerID", c_int),    # 目标玩家ID
                  ("WorshipType", c_ubyte),    # 膜拜类型
                  ("WorshipValue", c_int),    # 膜拜类型对应的功能值,如名次或其他,由具体膜拜类型定义对应值含义
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB0
        self.SubCmd = 0x20
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xB0
        self.SubCmd = 0x20
        self.PlayerID = 0
        self.WorshipType = 0
        self.WorshipValue = 0
        return
    def GetLength(self):
        return sizeof(tagCGWorship)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B0 20 请求膜拜玩家 //tagCGWorship:
                                Cmd:%s,
                                SubCmd:%s,
                                PlayerID:%d,
                                WorshipType:%d,
                                WorshipValue:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.PlayerID,
                                self.WorshipType,
                                self.WorshipValue
                                )
        return DumpString
m_NAtagCGWorship=tagCGWorship()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGWorship.Cmd,m_NAtagCGWorship.SubCmd))] = m_NAtagCGWorship
#------------------------------------------------------
# B3 19 提升魅力等级 #tagCGCharmLVUp
class  tagCGCharmLVUp(Structure):
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -8515,6 +8515,213 @@
#------------------------------------------------------
# B0 20 膜拜信息列表 #tagGCWorshipInfoList
class  tagGCWorshipInfo(Structure):
    PlayerID = 0    #(DWORD PlayerID)// 目标玩家ID
    WorshipType = 0    #(BYTE WorshipType)// 膜拜类型
    WorshipValue = 0    #(DWORD WorshipValue)// 膜拜类型对应的功能值,如名次或其他,由具体膜拜类型定义对应值含义
    InfoLen = 0    #(WORD InfoLen)
    PlayerInfo = ""    #(String PlayerInfo)// 玩家信息{k:v, ...}
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.WorshipType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.WorshipValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.InfoLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.PlayerInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.InfoLen)
        return _pos
    def Clear(self):
        self.PlayerID = 0
        self.WorshipType = 0
        self.WorshipValue = 0
        self.InfoLen = 0
        self.PlayerInfo = ""
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 1
        length += 4
        length += 2
        length += len(self.PlayerInfo)
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteBYTE(data, self.WorshipType)
        data = CommFunc.WriteDWORD(data, self.WorshipValue)
        data = CommFunc.WriteWORD(data, self.InfoLen)
        data = CommFunc.WriteString(data, self.InfoLen, self.PlayerInfo)
        return data
    def OutputString(self):
        DumpString = '''
                                PlayerID:%d,
                                WorshipType:%d,
                                WorshipValue:%d,
                                InfoLen:%d,
                                PlayerInfo:%s
                                '''\
                                %(
                                self.PlayerID,
                                self.WorshipType,
                                self.WorshipValue,
                                self.InfoLen,
                                self.PlayerInfo
                                )
        return DumpString
class  tagGCWorshipInfoList(Structure):
    Head = tagHead()
    WorshipCount = 0    #(BYTE WorshipCount)
    WorshipInfoList = list()    #(vector<tagGCWorshipInfo> WorshipInfoList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB0
        self.Head.SubCmd = 0x20
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.WorshipCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.WorshipCount):
            temWorshipInfoList = tagGCWorshipInfo()
            _pos = temWorshipInfoList.ReadData(_lpData, _pos)
            self.WorshipInfoList.append(temWorshipInfoList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB0
        self.Head.SubCmd = 0x20
        self.WorshipCount = 0
        self.WorshipInfoList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        for i in range(self.WorshipCount):
            length += self.WorshipInfoList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.WorshipCount)
        for i in range(self.WorshipCount):
            data = CommFunc.WriteString(data, self.WorshipInfoList[i].GetLength(), self.WorshipInfoList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                WorshipCount:%d,
                                WorshipInfoList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.WorshipCount,
                                "..."
                                )
        return DumpString
m_NAtagGCWorshipInfoList=tagGCWorshipInfoList()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCWorshipInfoList.Head.Cmd,m_NAtagGCWorshipInfoList.Head.SubCmd))] = m_NAtagGCWorshipInfoList
#------------------------------------------------------
# B0 21 膜拜结果 #tagGCWorshipResult
class  tagGCWorshipResult(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("PlayerID", c_int),    # 目标玩家ID
                  ("WorshipType", c_ubyte),    # 膜拜类型
                  ("WorshipValue", c_int),    # 膜拜类型对应的功能值,如名次或其他,由具体膜拜类型定义对应值含义
                  ("Result", c_ubyte),    # 膜拜结果:0-成功;1-不存在该膜拜类型;2-不存在该目标膜拜;3-不能膜拜该目标;
                  ("MoneyType", c_ubyte),    # 货币类型
                  ("MoneyValue", c_int),    # 货币奖励
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB0
        self.SubCmd = 0x21
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xB0
        self.SubCmd = 0x21
        self.PlayerID = 0
        self.WorshipType = 0
        self.WorshipValue = 0
        self.Result = 0
        self.MoneyType = 0
        self.MoneyValue = 0
        return
    def GetLength(self):
        return sizeof(tagGCWorshipResult)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B0 21 膜拜结果 //tagGCWorshipResult:
                                Cmd:%s,
                                SubCmd:%s,
                                PlayerID:%d,
                                WorshipType:%d,
                                WorshipValue:%d,
                                Result:%d,
                                MoneyType:%d,
                                MoneyValue:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.PlayerID,
                                self.WorshipType,
                                self.WorshipValue,
                                self.Result,
                                self.MoneyType,
                                self.MoneyValue
                                )
        return DumpString
m_NAtagGCWorshipResult=tagGCWorshipResult()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCWorshipResult.Cmd,m_NAtagGCWorshipResult.SubCmd))] = m_NAtagGCWorshipResult
#------------------------------------------------------
#B3 03 询问是否允许添加好友#tagGCFriendAskIfJoin
class  tagGCFriendAskIfJoin(Structure):
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/GMT_Worship.py
New file
@@ -0,0 +1,130 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.GMT_Worship
#
# @todo:后台管理膜拜
# @author hxp
# @date 2024-07-02
# @version 1.0
#
# 详细描述: 后台管理膜拜
#
#-------------------------------------------------------------------------------
#"""Version = 2024-07-02 16:30"""
#-------------------------------------------------------------------------------
import GMCommon
import ChConfig
import GameWorship
import PyDataManager
import PlayerViewCache
import IpyGameDataPY
import ShareDefine
import GameWorld
## 执行逻辑
#  @param curPlayer 当前玩家
#  @param gmCmdDict: 命令字典
#  @return None
#  @remarks 函数详细说明.
def OnExec(orderId, gmCmdDict):
    GameWorld.Log("GMT_Worship %s" % gmCmdDict)
    queryType = gmCmdDict.get(GMCommon.Def_GMKey_QueryType, '')
    playerFind = gmCmdDict.get(GMCommon.Def_GMKey_PlayerFind, '')
    worshipType = GameWorld.ToIntDef(gmCmdDict.get('worshipType', ''), 0)
    worshipValue = GameWorld.ToIntDef(gmCmdDict.get('worshipValue', ''), 0)
    zoneID = GameWorld.ToIntDef(gmCmdDict.get('zoneID', ''), 0)
    days = GameWorld.ToIntDef(gmCmdDict.get('days', ''), 0)
    opType = gmCmdDict.get('opType', '')
    if not opType or not worshipType:
        GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_ParamErr)
        return
    if opType == "view":
        worshipList = __GetServerWorshipList()
        GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_Success, {"WorshipList":worshipList})
        return
    if worshipType in ShareDefine.Def_WorshipTypeCross:
        if not GameWorld.IsCrossServer():
            GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_ParamErr, "player run in cross server.")
            return
    else:
        if GameWorld.IsCrossServer():
            GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_ParamErr, "do not run in cross server.")
            return
    ipyData = IpyGameDataPY.GetIpyGameData("Worship", worshipType, worshipValue)
    if not ipyData:
        GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_ParamErr, "worshipType value ipyData is not exist.")
        return
    playerManager = GameWorld.GetPlayerManager()
    if queryType == "playerID":
        tagPlayerID = GameWorld.ToIntDef(playerFind, 0)
    else:
        if queryType == GMCommon.Def_GMKey_PlayerAccID:
            queryType = ChConfig.queryType_sqtPlayerByAccID
            tagPlayer = playerManager.FindPlayerByAccID(str(playerFind))
        elif queryType == GMCommon.Def_GMKey_PlayerName:
            queryType = ChConfig.queryType_sqtPlayerByName
            tagPlayer = playerManager.FindPlayerByName(str(playerFind))
        else:
            GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_ParamErr)
            return
        if not tagPlayer:
            GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_PlayerOfLine)
            return
        tagPlayerID = tagPlayer.GetPlayerID()
    cacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(tagPlayerID))
    if not cacheDict:
        GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_NoTag, "can not found player view cache")
        return {}
    Name = cacheDict.get("Name", "")
    AccID = cacheDict.get("AccID", "")
    if opType == "add":
        if not GameWorship.AddWorshipPlayer(tagPlayerID, worshipType, worshipValue, days, zoneID):
            GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_Unknow, "add error.")
            return
    elif opType == "del":
        GameWorship.DelWorshipPlayer(worshipType, worshipValue, tagPlayerID)
    else:
        GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_ParamErr)
        return
    worshipList = __GetServerWorshipList()
    GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_Success, {"AccID":AccID, "Name":Name, "PlayerID":tagPlayerID, "WorshipList":worshipList})
    return
def __GetServerWorshipList():
    worshipList = []
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    recDict = playerRecMgr.GetPlayerRecDataDict(ShareDefine.Def_PlayerRecType_WorshipPlayer)
    for recDataList in recDict.values():
        for recData in recDataList:
            playerInfo = GameWorship.GetModelShowInfo(recData)
            worshipList.append({"PlayerID":recData.GetPlayerID(),
                                "AddTime":GameWorld.ChangeTimeNumToStr(recData.GetTime()),
                                "WorshipType":GameWorship.GetWorshipType(recData),
                                "WorshipValue":GameWorship.GetWorshipValue(recData),
                                "Days":GameWorship.GetWorshipDays(recData),
                                "ZoneID":GameWorship.GetWorshipZoneID(recData),
                                "AccID":playerInfo.get("AccID", ""),
                                "Name":playerInfo.get("Name", ""),
                                })
    return worshipList
ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
@@ -700,6 +700,15 @@
    return pastTimeDelta.days * 24 * 60 * 60 + pastTimeDelta.seconds
#---------------------------------------------------------------------
def GetDiff_Day(timeA , timeB):
    ## 获取 timeA - timeB 相差的日期天数
    dateTimeA = ChangeTimeNumToDatetime(timeA)
    dateTimeA = datetime.datetime(dateTimeA.year, dateTimeA.month, dateTimeA.day, 0, 0, 0)
    dateTimeB = ChangeTimeNumToDatetime(timeB)
    dateTimeB = datetime.datetime(dateTimeB.year, dateTimeB.month, dateTimeB.day, 0, 0, 0)
    return (dateTimeA - dateTimeB).days
##设置世界服务器字典
# @param key 字典值
# @param tick 时间戳
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
@@ -29,6 +29,7 @@
import PlayerControl
import PyDataManager
import NetPackCommon
import GameWorship
import PyGameData
import ChConfig
import PlayerFB
@@ -1945,9 +1946,14 @@
    champMgr = GetChampionshipMgr()
    champMgr.ClearOfficialZone() # 最终结算重置仙官信息,替换最新仙官
    
    # 膜拜重置
    worshipType = ShareDefine.Def_WorshipType_CrossChampionship
    GameWorship.DelWorshipPlayer(worshipType)
    pkZoneIDList = champMgr.GetChampPKZoneIDList()
    GameWorld.Log("pkZoneIDList=%s" % pkZoneIDList)
    
    worshipList = []
    for zoneID in pkZoneIDList:
        GameWorld.Log("=== 结算排位分区: zoneID=%s ===" % zoneID, zoneID)
        finalPlayerIDList = []
@@ -1991,6 +1997,11 @@
                
                offZoneMgr.officialInfo[officialID] = offObj
                
                worshipValue = rank
                if GameWorship.GetWorshipIpyData(worshipType, worshipValue):
                    worshipData = GameWorship.AddWorshipPlayer(playerID, worshipType, worshipValue, zoneID=zoneID, isNotify=False)
                    worshipList.append(worshipData)
            # 名次奖励
            paramList = [rank]
            PlayerCompensation.SendMailByKey("CrossChampionshipPKRank", [playerID], rankAwardItemList, paramList, crossMail=True)
@@ -2033,6 +2044,9 @@
    
    serverGroupIDList = [] # 全服统一逻辑
    PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "ChampionshipOver")
    # 通知新添加的膜拜
    GameWorship.SyncAddCrossWorship(worshipList)
    GameWorld.Log("===================================================================")
    return
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
@@ -33,6 +33,7 @@
import CrossYaomoBoss
import GameWorldBoss
import CrossRealmPK
import GameWorship
import PlayerQuery
import PlayerTalk
import PyGameData
@@ -209,6 +210,7 @@
    CrossActAllRecharge.Sync_AllRechargeDataToClientServer(serverGroupID)
    CrossYaomoBoss.Sync_CrossYaomoBossDataToClientServer(serverGroupID)
    PlayerCompensation.Sync_CrossMailPlayerIDToClientServer(serverGroupID)
    GameWorship.Sync_CrossWorshipToClientServer(serverGroupID)
    return
def MapServer_CrossServerReceiveMsg(msgType, msgData, serverGroupID):
@@ -362,6 +364,9 @@
        elif msgType == ShareDefine.CrossServerMsg_CrossBossTrialFamilyAward:
            PlayerActBossTrial.CrossServerMsg_CrossBossTrialFamilyAward(msgData)
            
        elif msgType == ShareDefine.CrossServerMsg_Worship:
            GameWorship.CrossServerMsg_Worship(msgData)
        elif msgType == ShareDefine.CrossServerMsg_ChampionshipState:
            CrossChampionship.CrossServerMsg_ChampionshipState(msgData)
            
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
@@ -113,6 +113,7 @@
import CrossBillboard
import CrossChampionship
import GameWorldMineArea
import GameWorship
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -186,6 +187,8 @@
    PlayerLove.DoOnDay()
    # 云购
    CrossLuckyCloudBuy.DoOnDay()
    # 膜拜
    GameWorship.DoOnDay()
    return
def OnDayEx(tick):
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorship.py
New file
@@ -0,0 +1,521 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GameWorship
#
# @todo:膜拜
# @author hxp
# @date 2024-07-02
# @version 1.0
#
# 详细描述: 膜拜
#
#-------------------------------------------------------------------------------
#"""Version = 2024-7-02 16:30"""
#-------------------------------------------------------------------------------
import ShareDefine
import PyDataManager
import NetPackCommon
import PlayerControl
import ChPyNetSendPack
import CrossChampionship
import PlayerViewCache
import PlayerRecData
import CrossRealmMsg
import IpyGameDataPY
import GameWorld
import random
import time
# 被膜拜玩家  RecType = ShareDefine.Def_PlayerRecType_WorshipPlayer
def GetWorshipType(recData): return recData.GetValue1() # 膜拜类型
def SetWorshipType(recData, worshipType): recData.SetValue1(worshipType)
def GetWorshipValue(recData): return recData.GetValue2() # 膜拜类型下的功能值,即膜拜什么,功能自定义,如排名或其他,可选
def SetWorshipValue(recData, worshipValue): recData.SetValue2(worshipValue)
def GetWorshipDays(recData): return recData.GetValue3() # 持续天数: 0永久,>0-天数
def SetWorshipDays(recData, days): recData.SetValue3(days)
def GetWorshipZoneID(recData): return recData.GetValue4() # 膜拜分区,跨服膜拜类型有用
def SetWorshipZoneID(recData, zoneID): recData.SetValue4(zoneID)
def GetModelShowInfo(recData): return recData.GetEvalUserData({}) # 模型外观显示信息,备用,缓存没有时取这里
def SetModelShowInfo(recData, modelShow): return recData.SetEvalUserData(modelShow)
def GetPlayerModelShow(playerID):
    ## 获取膜拜对象的外观显示信息 - 本服跨服通用
    cacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(playerID))
    if not cacheDict:
        return {}
    modelShow = {
                 "Name":cacheDict.get("Name", ""),
                 "AccID":cacheDict.get("AccID", ""),
                 "LV":cacheDict.get("LV", 0),
                 "RealmLV":cacheDict.get("RealmLV", 0),
                 "Job":cacheDict.get("Job", 0),
                 "VIPLV":cacheDict.get("VIPLV", 0),
                 "TitleID":cacheDict.get("TitleID", 0),
                 "FightPower":cacheDict.get("FightPower", 0),
                 "EquipShowID":cacheDict.get("EquipShowID", []),
                 }
    return modelShow
# 玩家每日膜拜记录  RecType = ShareDefine.Def_PlayerRecType_WorshipDaily
def GetTodayWorshipRecord(recData): return recData.GetEvalUserData({}) # 今日已膜拜记录 {tagPlayerID:[[膜拜类型, 膜拜值], ...], ...}
##--------------------------------------------------------------------------------------------------
def OnPlayerLogin(curPlayer):
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    unWorshipList = [] # 未膜拜列表
    recDict = playerRecMgr.GetPlayerRecDataDict(ShareDefine.Def_PlayerRecType_WorshipPlayer)
    for recDataList in recDict.values():
        for recData in recDataList:
            if not __CheckPlayerCanWorship(curPlayer, recData):
                continue
            unWorshipList.append(recData)
    Sync_UnWorshipInfo(curPlayer, unWorshipList)
    return
def DoOnDay():
    '''
        本服先过天
                已过期的跨服膜拜也会被先删除,相当于提交删除过期的跨服膜拜
                未过期的跨服膜拜当跨服服务器过天时同样也是未过期,故也可正常膜拜,每天的膜拜记录是存在本服玩家,相当于提前膜拜
        跨服先过天
                已过期的跨服膜拜会被删除,然后同步给子服先同步删除掉即可
                未过期的跨服膜拜不处理即可
        所以,过天时,本服及跨服各自处理各自的逻辑即可
    '''
    isCrossServer = GameWorld.IsCrossServer()
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    worshipList = []
    curTime = int(time.time())
    recDict = playerRecMgr.GetPlayerRecDataDict(ShareDefine.Def_PlayerRecType_WorshipPlayer)
    for recDataList in recDict.values():
        for recData in recDataList[::-1]: # 倒序处理删除到期的膜拜对象
            recTime = recData.GetTime()
            tagPlayerID = recData.GetPlayerID()
            worshipType = GetWorshipType(recData)
            worshipValue = GetWorshipValue(recData)
            worshipDays = GetWorshipDays(recData)
            if not worshipDays: # 永久膜拜不处理,直到被替换
                GameWorld.DebugLog("永久膜拜不处理: worshipType=%s,worshipValue=%s,tagPlayerID=%s" % (worshipType, worshipValue, tagPlayerID))
                __UpdWorshipByDay(isCrossServer, worshipList, recData)
                continue
            diffDays = GameWorld.GetDiff_Day(curTime, recTime)
            if diffDays < worshipDays:
                GameWorld.DebugLog("膜拜未到期: worshipType=%s,worshipValue=%s,tagPlayerID=%s,diffDays=%s < %s"
                                   % (worshipType, worshipValue, tagPlayerID, diffDays, worshipDays))
                __UpdWorshipByDay(isCrossServer, worshipList, recData)
                continue
            GameWorld.DebugLog("删除膜拜: worshipType=%s,worshipValue=%s,tagPlayerID=%s" % (worshipType, worshipValue, tagPlayerID))
            playerRecMgr.DelRecData(recData)
    if isCrossServer:
        # 同步给子服
        dataMsg = {"msgType":"AllCrossWorship", "worshipDataList":worshipList}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Worship, dataMsg)
        return
    # 本服处理
    playerRecMgr.DelRecDataByType(ShareDefine.Def_PlayerRecType_WorshipDaily) # 删除本服所有玩家的每日膜拜记录
    Sync_UnWorshipInfo(None, worshipList)
    return
def __UpdWorshipByDay(isCrossServer, worshipList, recData):
    ## 过天更新未过期膜拜信息
    playerID = recData.GetPlayerID()
    modelShow = GetPlayerModelShow(playerID)
    if modelShow:
        SetModelShowInfo(recData, modelShow)
    if isCrossServer:
        worshipList.append(recData.GetString())
    else:
        worshipList.append(recData)
    return
def IsWorshipPlayer(playerID):
    ## 是否膜拜玩家
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    if playerRecMgr.GetPlayerRecDataList(ShareDefine.Def_PlayerRecType_WorshipPlayer, playerID):
        return True
    return False
def GetWorshipIpyData(worshipType, worshipValue):
    ## 获取膜拜配置数据
    ipyData = IpyGameDataPY.GetIpyGameDataNotLog("Worship", worshipType, worshipValue)
    return ipyData
def AddWorshipPlayer(playerID, worshipType, worshipValue, days=None, zoneID=0, isNotify=True):
    ## 添加膜拜玩家,本服跨服通用
    # @param isNotify: 本服-是否通知玩家;跨服-是否通知子服
    if worshipType in ShareDefine.Def_WorshipTypeCross:
        if not GameWorld.IsCrossServer():
            GameWorld.ErrLog("非跨服服务器不允许添加跨服膜拜! worshipType=%s" % (worshipType))
            return
    else:
        if GameWorld.IsCrossServer():
            GameWorld.ErrLog("跨服服务器不允许添加非跨服膜拜! worshipType=%s" % (worshipType))
            return
    ipyData = IpyGameDataPY.GetIpyGameData("Worship", worshipType, worshipValue)
    if not ipyData:
        return
    if days == None:
        days = ipyData.GetWorshipDays() # 没有指定天数的话取配表
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    recData = playerRecMgr.GetPlayerRecData(ShareDefine.Def_PlayerRecType_WorshipPlayer, playerID, [worshipType, worshipValue])
    if not recData:
        GameWorld.Log("添加膜拜数据: playerID=%s,worshipType=%s,worshipValue=%s,days=%s,zoneID=%s" % (playerID, worshipType, worshipValue, days, zoneID))
        recData = playerRecMgr.AddPlayerRecData(ShareDefine.Def_PlayerRecType_WorshipPlayer, playerID)
    else:
        GameWorld.Log("更新膜拜数据: playerID=%s,worshipType=%s,worshipValue=%s,days=%s,zoneID=%s" % (playerID, worshipType, worshipValue, days, zoneID))
    SetWorshipType(recData, worshipType)
    SetWorshipValue(recData, worshipValue)
    SetWorshipDays(recData, days)
    SetModelShowInfo(recData, GetPlayerModelShow(playerID))
    SetWorshipZoneID(recData, zoneID)
    if isNotify:
        if GameWorld.IsCrossServer():
            SyncAddCrossWorship([recData])
        else:
            Sync_UnWorshipInfo(None, [recData])
    return recData
def DelWorshipPlayer(worshipType, worshipValue=None, delPlayerID=None):
    ## 删除膜拜玩家,本服跨服通用
    valueList = [worshipType]
    if worshipValue != None:
        valueList.append(worshipValue)
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    playerRecMgr.DelRecDataByTypeValue(ShareDefine.Def_PlayerRecType_WorshipPlayer, valueList, delPlayerID)
    if GameWorld.IsCrossServer():
        dataMsg = {"msgType":"DelCrossWorship", "worshipType":worshipType, "worshipValue":worshipValue, "delPlayerID":delPlayerID}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Worship, dataMsg)
    return
#// B0 20 请求膜拜玩家 #tagCGWorship
#
#struct    tagCGWorship
#{
#    tagHead        Head;
#    DWORD        PlayerID;        // 目标玩家ID
#    BYTE        WorshipType;    // 膜拜类型
#    DWORD        WorshipValue;    // 膜拜类型对应的功能值,如名次或其他,由具体膜拜类型定义对应值含义
#};
def OnWorship(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    tagPlayerID = clientData.PlayerID
    worshipType = clientData.WorshipType
    worshipValue = clientData.WorshipValue
    ipyData = IpyGameDataPY.GetIpyGameData("Worship", worshipType, worshipValue)
    if not ipyData:
        __SyncWorshipResult(curPlayer, tagPlayerID, worshipType, worshipValue, 1)
        return
    findWorshipData = None
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    recDataList = playerRecMgr.GetPlayerRecDataList(ShareDefine.Def_PlayerRecType_WorshipPlayer, tagPlayerID)
    for recData in recDataList:
        if worshipType == GetWorshipType(recData) and worshipValue == GetWorshipValue(recData):
            findWorshipData = recData
            break
    if not findWorshipData:
        __SyncWorshipResult(curPlayer, tagPlayerID, worshipType, worshipValue, 2)
        GameWorld.DebugLog("不存在该目标玩家的膜拜! tagPlayerID=%s,worshipType=%s,worshipValue=%s"
                           % (tagPlayerID, worshipType, worshipValue), playerID)
        return
    if not __CheckPlayerCanWorship(curPlayer, recData):
        __SyncWorshipResult(curPlayer, tagPlayerID, worshipType, worshipValue, 3)
        return
    moneyType = ipyData.GetMoneyType()
    moneyRange = ipyData.GetMoneyRange()
    if len(moneyRange) != 2:
        return
    moneyValue = random.randint(moneyRange[0], moneyRange[1])
    GameWorld.DebugLog("膜拜: tagPlayerID=%s,worshipType=%s,worshipValue=%s,moneyType=%s,moneyValue=%s"
                       % (tagPlayerID, worshipType, worshipValue, moneyType, moneyValue), playerID)
    __AddWorshipRecord(playerID, recData)
    __SyncWorshipResult(curPlayer, tagPlayerID, worshipType, worshipValue, 0, moneyType, moneyValue)
    # 同步地图发放货币
    PlayerControl.MapServerGiveAward(curPlayer, "Worship", {moneyType:moneyValue})
    return
def __CheckPlayerCanWorship(curPlayer, recData):
    ## 检查玩家是否可膜拜该对象
    playerID = curPlayer.GetPlayerID()
    recPlayerID = recData.GetPlayerID()
    if playerID == recPlayerID:
        GameWorld.DebugLog("不能膜拜自己!", playerID)
        return
    modelShow = GetModelShowInfo(recData)
    if not modelShow:
        GameWorld.DebugLog("没有外观展示的不同步! recPlayerID=%s" % recPlayerID, playerID)
        return
    accID = modelShow.get("AccID", "")
    if not accID:
        return
    worshipType = GetWorshipType(recData)
    worshipValue = GetWorshipValue(recData)
    zoneID = GetWorshipZoneID(recData)
    if worshipType == ShareDefine.Def_WorshipType_ServerNaming:
        #只同步给同ServerID的
        serverID = GameWorld.GetAccIDServerID(accID)
        playerServerID = GameWorld.GetPlayerServerID(curPlayer)
        if serverID != playerServerID:
            GameWorld.DebugLog("只同步给同ServerID的! recPlayerID=%s,accID=%s,serverID=%s != playerServerID=%s"
                               % (recPlayerID, accID, serverID, playerServerID), playerID)
            return
    elif worshipType == ShareDefine.Def_WorshipType_CrossChampionship:
        #只同步给同分区的
        playerZoneID = CrossChampionship.GetChampionshipMgr().GetPlayerOfficialZoneID(playerID)
        if playerZoneID != zoneID:
            GameWorld.DebugLog("只同步给同分区的! recPlayerID=%s,zoneID=%s != playerZoneID=%s" % (recPlayerID, zoneID, playerZoneID), playerID)
            return
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    worshipRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_WorshipDaily, playerID)
    worshipRecordDict = GetTodayWorshipRecord(worshipRecData)
    if recPlayerID in worshipRecordDict and [worshipType, worshipValue] in worshipRecordDict[recPlayerID]:
        GameWorld.DebugLog("已膜拜过! recPlayerID=%s,worshipType=%s, worshipValue=%s,worshipRecordDict=%s"
                           % (recPlayerID, worshipType, worshipValue, worshipRecordDict), playerID)
        return
    return True
def __AddWorshipRecord(playerID, recData):
    ## 添加玩家膜拜目标记录
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    worshipRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_WorshipDaily, playerID)
    worshipRecordDict = GetTodayWorshipRecord(worshipRecData)
    tagPlayerID = recData.GetPlayerID()
    worshipType = GetWorshipType(recData)
    worshipValue = GetWorshipValue(recData)
    recordInfo = [worshipType, worshipValue]
    if tagPlayerID not in worshipRecordDict:
        worshipRecordDict[tagPlayerID] = []
    worshipRecordList = worshipRecordDict[tagPlayerID]
    if recordInfo not in worshipRecordList:
        worshipRecordList.append(recordInfo)
    #GameWorld.DebugLog("更新今日膜拜记录: %s" % GetTodayWorshipRecord(worshipRecData), playerID)
    return
def __SyncWorshipResult(curPlayer, tagPlayerID, worshipType, worshipValue, result, moneyType=0, moneyValue=0):
    ## 同步膜拜结果
    # @param result: 膜拜结果:0-成功;1-不存在该膜拜;2-不能膜拜目标
    clientPack = ChPyNetSendPack.tagGCWorshipResult()
    clientPack.PlayerID = tagPlayerID
    clientPack.WorshipType = worshipType
    clientPack.WorshipValue = worshipValue
    clientPack.Result = result
    clientPack.MoneyType = moneyType
    clientPack.MoneyValue = moneyValue
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def CrossServerMsg_Worship(msgData):
    ## 子服收到跨服信息
    msgType = msgData["msgType"]
    if msgType == "AddCrossWorship":
        __Client_AddCrossWorship(msgData)
    elif msgType == "AllCrossWorship":
        __Client_AllCrossWorship(msgData)
    elif msgType == "DelCrossWorship":
        __Client_DelCrossWorship(msgData)
    return
def __Client_AllCrossWorship(msgData):
    ## 子服更新所有跨服膜拜
    worshipDataList = msgData["worshipDataList"]
    GameWorld.Log("子服更新所有跨服膜拜: count=%s" % len(worshipDataList))
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    for crossWorshipType in ShareDefine.Def_WorshipTypeCross:
        playerRecMgr.DelRecDataByTypeValue(ShareDefine.Def_PlayerRecType_WorshipPlayer, [crossWorshipType])
    sysnList = []
    for attrDict in worshipDataList:
        recData = playerRecMgr.AddPlayerRecDataByDict(attrDict)
        playerID = recData.GetPlayerID()
        # 如果存在本服的最新外观数据则已本服的为准
        modelShow = GetPlayerModelShow(playerID)
        if modelShow:
            SetModelShowInfo(recData, modelShow)
        sysnList.append(recData)
        GameWorld.Log("    更新跨服膜拜: worshipType=%s,zoneID=%s,playerID=%s,worshipValue=%s,days=%s"
                      % (GetWorshipType(recData), GetWorshipZoneID(recData), playerID, GetWorshipValue(recData), GetWorshipDays(recData)))
    #更新数据的可不同步,每个人的膜拜记录都不一样,由登录触发及添加新膜拜触发即可
    #Sync_UnWorshipInfo(None, sysnList)
    return
def __Client_AddCrossWorship(msgData):
    ## 子服添加跨服膜拜
    worshipDataList = msgData["worshipDataList"]
    GameWorld.Log("子服添加跨服膜拜: addCount=%s" % len(worshipDataList))
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    tempData = PlayerRecData.PlayerRecDataTemp
    sysnList = []
    for attrDict in worshipDataList:
        tempData.SetAttr(attrDict, True)
        playerID = tempData.GetPlayerID()
        worshipType = GetWorshipType(tempData)
        worshipValue = GetWorshipValue(tempData)
        if not playerID or not worshipType:
            continue
        # 如果已经存在该膜拜则直接更新数据,否则添加新数据
        recData = playerRecMgr.GetPlayerRecData(ShareDefine.Def_PlayerRecType_WorshipPlayer, playerID, [worshipType, worshipValue])
        if recData:
            recData.SetAttr(attrDict, True)
        else:
            recData = playerRecMgr.AddPlayerRecDataByDict(attrDict)
        sysnList.append(recData)
        GameWorld.Log("    添加跨服膜拜: worshipType=%s,zoneID=%s,playerID=%s,worshipValue=%s,days=%s"
                      % (GetWorshipType(recData), GetWorshipZoneID(recData), playerID, GetWorshipValue(recData), GetWorshipDays(recData)))
    Sync_UnWorshipInfo(None, sysnList)
    return
def __Client_DelCrossWorship(msgData):
    ## 子服删除跨服膜拜
    worshipType = msgData["worshipType"]
    worshipValue = msgData["worshipValue"]
    delPlayerID = msgData["delPlayerID"]
    GameWorld.Log("子服删除跨服膜拜: worshipType=%s,worshipValue=%s,delPlayerID=%s" % (worshipType, worshipValue, delPlayerID))
    DelWorshipPlayer(worshipType, worshipValue, delPlayerID)
    return
def Sync_UnWorshipInfo(curPlayer, unWorshipList):
    ## curPlayer 可能为None
    if not unWorshipList:
        return
    infoList = []
    for recData in unWorshipList:
        recPlayerID = recData.GetPlayerID()
        modelShow = GetPlayerModelShow(recPlayerID)
        if modelShow:
            # 更新本服最新的外观显示,跨服玩家由跨服每日同步更新 __UpdWorshipByDay
            SetModelShowInfo(recData, modelShow)
        else:
            modelShow = GetModelShowInfo(recData)
        if not modelShow:
            # 没有外观展示的不同步
            continue
        if curPlayer:
            if not __CheckPlayerCanWorship(curPlayer, recData):
                continue
        infoPack = ChPyNetSendPack.tagGCWorshipInfo()
        infoPack.PlayerID = recPlayerID
        infoPack.WorshipType = GetWorshipType(recData)
        infoPack.WorshipValue = GetWorshipValue(recData)
        infoPack.PlayerInfo = str(modelShow).replace(" ", "")
        infoPack.InfoLen = len(infoPack.PlayerInfo)
        if curPlayer:
            infoList.append(infoPack)
        else:
            infoList.append([recData, infoPack])
    if not infoList:
        return
    clientPack = ChPyNetSendPack.tagGCWorshipInfoList()
    if not curPlayer:
        # 全服广播在线玩家,每个人同步的可能不一样
        playerManager = GameWorld.GetPlayerManager()
        for i in range(0, playerManager.GetPlayerCount()):
            curPlayer = playerManager.GetPlayerByIndex(i)
            if curPlayer == None or not curPlayer.GetInitOK():
                continue
            clientPack.WorshipInfoList = []
            for info in infoList:
                recData, infoPack = info
                if not __CheckPlayerCanWorship(curPlayer, recData):
                    continue
                clientPack.WorshipInfoList.append(infoPack)
            if not clientPack.WorshipInfoList:
                continue
            clientPack.WorshipCount = len(clientPack.WorshipInfoList)
            NetPackCommon.SendFakePack(curPlayer, clientPack)
    else:
        clientPack.WorshipInfoList = infoList
        clientPack.WorshipCount = len(clientPack.WorshipInfoList)
        NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
##--------------------------------------------------------------------------------------------------
def Sync_CrossWorshipToClientServer(serverGroupID=0):
    ''' 同步跨服膜拜数据到子服务器
    @param serverGroupID: 为0时同步所有子服
    '''
    GameWorld.Log("同步给子服膜拜数据: syncServerGroupID=%s" % (serverGroupID))
    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
    recDataDict = playerRecMgr.GetPlayerRecDataDict(ShareDefine.Def_PlayerRecType_WorshipPlayer)
    worshipDataList = []
    for recDataList in recDataDict.values():
        for recData in recDataList:
            if not recData:
                continue
            if GetWorshipType(recData) not in ShareDefine.Def_WorshipTypeCross:
                continue
            worshipDataList.append(recData.GetString())
    dataMsg = {"msgType":"AllCrossWorship", "worshipDataList":worshipDataList}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Worship, dataMsg)
    return
def SyncAddCrossWorship(addRecDataList):
    # 同步子服
    worshipDataList = []
    for recData in addRecDataList:
        if not recData:
            continue
        worshipDataList.append(recData.GetString())
    if not worshipDataList:
        return
    dataMsg = {"msgType":"AddCrossWorship", "worshipDataList":worshipDataList}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Worship, dataMsg)
    return
ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
@@ -1030,6 +1030,14 @@
                        ("BYTE", "AssistAwardCount", 0),
                        ),
                "Worship":(
                        ("BYTE", "WorshipType", 1),
                        ("DWORD", "WorshipValue", 1),
                        ("BYTE", "WorshipDays", 0),
                        ("BYTE", "MoneyType", 0),
                        ("list", "MoneyRange", 0),
                        ),
                "FairyDomain":(
                        ("WORD", "ID", 1),
                        ("DWORD", "HourCntPubLimit", 0),
@@ -2500,6 +2508,19 @@
    def GetGiftID(self): return self.attrTuple[0] # 礼盒物品ID DWORD
    def GetAssistAwardCount(self): return self.attrTuple[1] #  协助奖励每日次数 BYTE
# 膜拜表
class IPY_Worship():
    def __init__(self):
        self.attrTuple = None
        return
    def GetWorshipType(self): return self.attrTuple[0] # 膜拜类型 BYTE
    def GetWorshipValue(self): return self.attrTuple[1] # 膜拜值 DWORD
    def GetWorshipDays(self): return self.attrTuple[2] # 膜拜天数 BYTE
    def GetMoneyType(self): return self.attrTuple[3] # 膜拜货币类型 BYTE
    def GetMoneyRange(self): return self.attrTuple[4] # 货币值范围 list
# 缥缈仙域表
class IPY_FairyDomain():
    
@@ -2659,6 +2680,7 @@
        self.__LoadFileData("MineAreaItem", onlyCheck)
        self.__LoadFileData("FamilyWarRankAward", onlyCheck)
        self.__LoadFileData("AssistThanksGift", onlyCheck)
        self.__LoadFileData("Worship", onlyCheck)
        self.__LoadFileData("FairyDomain", onlyCheck)
        Log("IPY_DataMgr ReloadOK! onlyCheck=%s" % onlyCheck)
        return
@@ -3516,6 +3538,13 @@
        self.CheckLoadData("AssistThanksGift")
        return self.ipyAssistThanksGiftCache[index]
    def GetWorshipCount(self):
        self.CheckLoadData("Worship")
        return self.ipyWorshipLen
    def GetWorshipByIndex(self, index):
        self.CheckLoadData("Worship")
        return self.ipyWorshipCache[index]
    def GetFairyDomainCount(self):
        self.CheckLoadData("FairyDomain")
        return self.ipyFairyDomainLen
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -75,6 +75,7 @@
import CrossActAllRecharge
import CrossYaomoBoss
import GameWorldMineArea
import GameWorship
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -235,6 +236,8 @@
        PlayerCharm.OnPlayerLogin(curPlayer)
        #情缘
        PlayerLove.OnPlayerLogin(curPlayer)
        #膜拜
        GameWorship.OnPlayerLogin(curPlayer)
        #跨服战场
        CrossBattlefield.OnPlayerLogin(curPlayer)
        #跨服排位
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
@@ -376,6 +376,12 @@
    curPlayer.MapServer_QueryPlayerResult(0, 0, "DelItem", result, len(result))
    return
def MapServerGiveAward(curPlayer, eventName, moneyInfo={}, itemList=[], drDict={}):
    ## 地图给奖励
    result = str([eventName, moneyInfo, itemList, drDict])
    curPlayer.MapServer_QueryPlayerResult(0, 0, "GiveAward", result, len(result))
    return
## 增加仙盟活跃
#  @param curPlayer
#  @param successType: 成就类型
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerRecData.py
New file
@@ -0,0 +1,271 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package PlayerRecData
#
# @todo:玩家记录
# @author hxp
# @date 2024-07-02
# @version 1.0
#
# 详细描述: 玩家记录,区别与通用记录,通用记录字符长度记录有限,且针对玩家的记录查找每次需要遍历,效率不高
#
#-------------------------------------------------------------------------------
#"""Version = 2024-07-02 16:30"""
#-------------------------------------------------------------------------------
import CommFunc
import PyGameDataStruct
import GameWorld
import time
class PlayerRecData():
    def __init__(self, dbRecData=None):
        if not dbRecData:
            dbRecData = PyGameDataStruct.tagDBPlayerRecData()
        self.dbRecData = dbRecData
        self.evalUserData = None
        return
    def clear(self):
        self.dbRecData.clear()
        self.evalUserData = None
        return
    def GetPlayerID(self): return self.dbRecData.PlayerID
    def SetPlayerID(self, playerID): self.dbRecData.PlayerID = playerID
    def GetRecType(self): return self.dbRecData.RecType
    def SetRecType(self, recType): self.dbRecData.RecType = recType
    def GetTime(self): return self.dbRecData.Time
    def SetTime(self, sTime): self.dbRecData.Time = sTime
    def GetValue1(self): return self.dbRecData.Value1
    def SetValue1(self, value1): self.dbRecData.Value1 = value1
    def GetValue2(self): return self.dbRecData.Value2
    def SetValue2(self, value2): self.dbRecData.Value2 = value2
    def GetValue3(self): return self.dbRecData.Value3
    def SetValue3(self, value3): self.dbRecData.Value3 = value3
    def GetValue4(self): return self.dbRecData.Value4
    def SetValue4(self, value4): self.dbRecData.Value4 = value4
    def GetValue5(self): return self.dbRecData.Value5
    def SetValue5(self, value5): self.dbRecData.Value5 = value5
    def GetValue6(self): return self.dbRecData.Value6
    def SetValue6(self, value6): self.dbRecData.Value6 = value6
    def GetValue7(self): return self.dbRecData.Value7
    def SetValue7(self, value7): self.dbRecData.Value7 = value7
    def GetValue8(self): return self.dbRecData.Value8
    def SetValue8(self, value8): self.dbRecData.Value8 = value8
    def GetUserData(self): return self.dbRecData.UserData
    def SetUserData(self, userData):
        if type(userData) != str:
            userData = str(userData).replace(" ", "")
        self.dbRecData.UserData = userData
        self.dbRecData.UserDataLen = len(self.dbRecData.UserData)
        if self.evalUserData != None:
            self.evalUserData = None
        return
    def GetEvalUserData(self, defValue={}):
        if self.evalUserData == None:
            try:
                self.evalUserData = eval(self.dbRecData.UserData)
            except:
                self.evalUserData = defValue
        return self.evalUserData
    def SetEvalUserData(self, eValue):
        self.evalUserData = eValue
        return
    def IsMatchValue(self, valueList):
        # 检查记录值列表是否配置该记录
        # @param valueList: [value1, value2, ...] value为None时不判断该值
        if not valueList:
            return False
        for i, value in enumerate(valueList, 1):
            if value == None:
                continue
            if not hasattr(self, "GetValue%s" % i):
                continue
            curValue = getattr(self, "GetValue%s" % i)()
            if curValue != value:
                return False
        return True
    def GetString(self):
        return {"PlayerID":self.GetPlayerID(), "RecType":self.GetRecType(), "Time":self.GetTime(),
                "Value1":self.GetValue1(), "Value2":self.GetValue2(), "Value3":self.GetValue3(), "Value4":self.GetValue4(),
                "Value5":self.GetValue5(), "Value6":self.GetValue6(), "Value7":self.GetValue7(), "Value8":self.GetValue8(),
                "UserData":self.GetUserData()
                }
    def SetAttr(self, attrDict, isClear=False):
        if isClear:
            self.clear()
        for k, v in attrDict.items():
            if hasattr(self, "Set%s" % k):
                getattr(self, "Set%s" % k, v)(v)
        return
class DBPlayerRecDataManager():
    ## 玩家记录管理
    def __init__(self):
        self.Clear()
        return
    def Clear(self):
        self.recTypeDict = {} # {recType:{playerID:[PlayerRecData, ...], ...}}
        return
    def DelRecDataByType(self, recType):
        ## 删除某个记录类型所有玩家记录
        GameWorld.DebugLog("删除所有玩家指定记录类型: recType=%s" % recType)
        self.recTypeDict.pop(recType, None)
        return
    def DelRecDataByTypePlayer(self, recType, delPlayerID):
        ## 删除玩家某个类型记录
        if recType not in self.recTypeDict:
            return 0
        playerRecDataDict = self.recTypeDict[recType]
        recDataList = playerRecDataDict.pop(delPlayerID, None)
        delCount = len(recDataList) if recDataList else 0
        GameWorld.DebugLog("删除某个玩家指定记录类型: recType=%s,delPlayerID=%s,delCount=%s" % (recType, delPlayerID, delCount))
        return delCount
    def DelRecDataByTypeValue(self, recType, valueList, delPlayerID=None):
        ## 删除某个记录类型匹配Value值列表的记录
        # @param valueList: [value1, value2, ...] value为None时不判断该值
        # @param delPlayerID: 可指定只删除某个玩家的记录
        if not valueList:
            return 0
        if recType not in self.recTypeDict:
            return 0
        delCountTotal = 0
        recDict = self.recTypeDict[recType]
        for playerID, recDataList in recDict.items():
            if delPlayerID and playerID != delPlayerID:
                continue
            delCount = 0
            for recData in recDataList[::-1]: # 倒序处理删除
                if recData.IsMatchValue(valueList):
                    recDataList.remove(recData)
                    delCount += 1
            if delCount:
                delCountTotal += delCount
                GameWorld.DebugLog("删除某个记录类型所有Value1匹配值的记录: recType=%s,valueList=%s,delPlayerID=%s,delCount=%s"
                                   % (recType, valueList, playerID, delCount))
        return delCountTotal
    def DelRecData(self, recData):
        ## 删除指定记录
        playerID = recData.GetPlayerID()
        recType = recData.GetRecType()
        if recType not in self.recTypeDict:
            return 0
        playerRecDataDict = self.recTypeDict[recType]
        if playerID not in playerRecDataDict:
            return 0
        playerRecDataList = playerRecDataDict[playerID]
        if recData in playerRecDataList:
            playerRecDataList.remove(recData)
        return 1
    def AddPlayerRecData(self, recType, playerID):
        ## 添加玩家记录
        recData = PlayerRecData()
        recData.clear()
        recData.SetPlayerID(playerID)
        recData.SetRecType(recType)
        recData.SetTime(int(time.time()))
        self.__AddRecData(recData)
        return recData
    def AddPlayerRecDataByDict(self, attrDict):
        ## 一般是跨服同步过来数据添加用
        recData = PlayerRecData()
        recData.SetAttr(attrDict, True)
        self.__AddRecData(recData)
        return recData
    def __AddRecData(self, recData):
        playerID = recData.GetPlayerID()
        recType = recData.GetRecType()
        if recType not in self.recTypeDict:
            self.recTypeDict[recType] = {}
        playerRecDataDict = self.recTypeDict[recType]
        if playerID not in playerRecDataDict:
            playerRecDataDict[playerID] = []
        playerRecDataList = playerRecDataDict[playerID]
        playerRecDataList.append(recData)
        return
    def GetPlayerRecDataFirst(self, recType, playerID):
        ## 获取玩家记录类型对应的第一条记录,适用于仅需一条的记录类型
        recDataList = self.GetPlayerRecDataList(recType, playerID)
        if recDataList:
            recData = recDataList[0]
        else:
            recData = self.AddPlayerRecData(recType, playerID)
        return recData
    def GetPlayerRecData(self, recType, playerID, valueList):
        ## 获取玩家记录类型对应的某条记录
        # @param valueList: [value1, value2, ...] value为None时不判断该值
        recDataList = self.GetPlayerRecDataList(recType, playerID)
        if not recDataList:
            return
        for recData in recDataList:
            if recData.IsMatchValue(valueList):
                return recData
        return
    def GetPlayerRecDataList(self, recType, playerID):
        ## 获取玩家记录类型对应记录列表 [recData, ...]
        if recType not in self.recTypeDict:
            return []
        playerRecDataDict = self.recTypeDict[recType]
        if playerID not in playerRecDataDict:
            return []
        return playerRecDataDict[playerID]
    def GetPlayerRecDataDict(self, recType):
        ## 获取记录类型对应所有玩家的记录字典 {playerID:[recData, ...], ...}
        if recType not in self.recTypeDict:
            return {}
        return self.recTypeDict[recType]
    # 保存数据 存数据库和realtimebackup
    def GetSaveData(self):
        savaData = ""
        cntData = ""
        cnt = 0
        for playerRecDataDict in self.recTypeDict.values():
            for recDataList in playerRecDataDict.values():
                for recData in recDataList:
                    cnt += 1
                    if recData.evalUserData != None:
                        recData.SetUserData(recData.evalUserData)
                    savaData += recData.dbRecData.getBuffer()
        GameWorld.Log("Save DBPlayerRecData 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 DBPlayerRecData count :%s" % cnt)
        self.Clear()
        for _ in xrange(cnt):
            recData = PyGameDataStruct.tagDBPlayerRecData()
            recData.clear()
            pos += recData.readData(datas, pos, dataslen)
            self.__AddRecData(PlayerRecData(recData))
        return pos
PlayerRecDataTemp = PlayerRecData()
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
@@ -19,6 +19,7 @@
#---------------------------------------------------------------------
import GameWorld
import GameWorship
import PlayerControl
import NetPackCommon
import GameWorldArena
@@ -54,6 +55,9 @@
    if CrossChampionship.IsChampionshipPlayer(playerID):
        return True
    
    if GameWorship.IsWorshipPlayer(playerID):
        return True
    if GameWorldSkyTower.IsSkyTowerPassPlayer(playerID):
        return True
    
ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
@@ -26,6 +26,7 @@
import CrossRealmPK
import AuctionHouse
import PlayerAssist
import PlayerRecData
import GameWorldMineArea
import PyGameDataStruct
import IpyGameDataPY
@@ -310,6 +311,7 @@
class PyGameDataManager(object):
    def __init__(self):
        self.DBPlayerRecDataManager = PlayerRecData.DBPlayerRecDataManager()
        self.DBPyMineAreaAwardManager = GameWorldMineArea.DBPyMineAreaAwardManager()
        self.DBPyMineAreaRecordManager = GameWorldMineArea.DBPyMineAreaRecordManager()
        self.DBPyMineAreaItemManager = GameWorldMineArea.DBPyMineAreaItemManager()
@@ -342,6 +344,7 @@
    def GetSaveData(self):
        buff = ""
        buff += self.DBPlayerRecDataManager.GetSaveData()
        buff += self.DBPyMineAreaAwardManager.GetSaveData()
        buff += self.DBPyMineAreaRecordManager.GetSaveData()
        buff += self.DBPyMineAreaItemManager.GetSaveData()
@@ -373,6 +376,7 @@
        return buff
    
    def LoadGameData(self, gameBuffer, pos):
        pos = self.DBPlayerRecDataManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
        pos = self.DBPyMineAreaAwardManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
        pos = self.DBPyMineAreaRecordManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
        pos = self.DBPyMineAreaItemManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
@@ -491,6 +495,11 @@
    pyGameDataMgr = GetPyGameDataManager()
    return pyGameDataMgr.familyStoreItemManager
def GetDBPlayerRecDataManager():
    # 玩家记录管理
    pyGameDataMgr = GetPyGameDataManager()
    return pyGameDataMgr.DBPlayerRecDataManager
def GetDBPyMineAreaAwardManager():
    # 福地奖励结算管理
    pyGameDataMgr = GetPyGameDataManager()
ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
@@ -3014,3 +3014,133 @@
            )
        return output
# 玩家记录表 #tagDBPlayerRecData
class tagDBPlayerRecData(Structure):
    _pack_ = 1
    _fields_ = [
        ('PlayerID', ctypes.c_ulong),
        ('RecType', ctypes.c_ushort),
        ('Time', ctypes.c_double),
        ('Value1', ctypes.c_ulong),
        ('Value2', ctypes.c_ulong),
        ('Value3', ctypes.c_ulong),
        ('Value4', ctypes.c_ulong),
        ('Value5', ctypes.c_ulong),
        ('Value6', ctypes.c_ulong),
        ('Value7', ctypes.c_ulong),
        ('Value8', ctypes.c_ulong),
        ('UserDataLen', ctypes.c_ushort),
        ('UserData', ctypes.c_char_p),
        ('ADOResult', ctypes.c_ulong),
    ]
    def __init__(self):
        Structure.__init__(self)
        self.clear()
    def clear(self):
        self.PlayerID = 0
        self.RecType = 0
        self.Time = 0.0
        self.Value1 = 0
        self.Value2 = 0
        self.Value3 = 0
        self.Value4 = 0
        self.Value5 = 0
        self.Value6 = 0
        self.Value7 = 0
        self.Value8 = 0
        self.UserDataLen = 0
        self.UserData = ''
    def readData(self, buf, pos = 0, length = 0):
        if not pos <= length:
            return -1
        if len(buf) < pos + self.getLength():
            return -1
        self.clear()
        self.PlayerID, pos = CommFunc.ReadDWORD(buf, pos)
        self.RecType, pos = CommFunc.ReadWORD(buf, pos)
        self.Time, pos = CommFunc.ReadDouble(buf, pos)
        self.Value1, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value2, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value3, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value4, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value5, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value6, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value7, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value8, pos = CommFunc.ReadDWORD(buf, pos)
        self.UserDataLen, pos = CommFunc.ReadWORD(buf, pos)
        tmp, pos = CommFunc.ReadString(buf, pos, self.UserDataLen)
        self.UserData = ctypes.c_char_p(tmp)
        return self.getLength()
    def getBuffer(self):
        buf = ''
        buf = CommFunc.WriteDWORD(buf, self.PlayerID)
        buf = CommFunc.WriteWORD(buf, self.RecType)
        buf = CommFunc.WriteDouble(buf, self.Time)
        buf = CommFunc.WriteDWORD(buf, self.Value1)
        buf = CommFunc.WriteDWORD(buf, self.Value2)
        buf = CommFunc.WriteDWORD(buf, self.Value3)
        buf = CommFunc.WriteDWORD(buf, self.Value4)
        buf = CommFunc.WriteDWORD(buf, self.Value5)
        buf = CommFunc.WriteDWORD(buf, self.Value6)
        buf = CommFunc.WriteDWORD(buf, self.Value7)
        buf = CommFunc.WriteDWORD(buf, self.Value8)
        buf = CommFunc.WriteWORD(buf, self.UserDataLen)
        buf = CommFunc.WriteString(buf, self.UserDataLen, self.UserData)
        return buf
    def getLength(self):
        length = 0
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ushort)
        length += sizeof(ctypes.c_double)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ushort)
        length += self.UserDataLen
        return length
    def outputString(self):
        output = '''// 玩家记录表 #tagDBPlayerRecData:
            PlayerID = %s,
            RecType = %s,
            Time = %s,
            Value1 = %s,
            Value2 = %s,
            Value3 = %s,
            Value4 = %s,
            Value5 = %s,
            Value6 = %s,
            Value7 = %s,
            Value8 = %s,
            UserDataLen = %s,
            UserData = %s,
            ADOResult = %s,
            '''%(
                self.PlayerID,
                self.RecType,
                self.Time,
                self.Value1,
                self.Value2,
                self.Value3,
                self.Value4,
                self.Value5,
                self.Value6,
                self.Value7,
                self.Value8,
                self.UserDataLen,
                self.UserData,
                self.ADOResult,
            )
        return output
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1297,7 +1297,26 @@
Def_Weapon_Dual_Hands,  # 双持(左右手可互换)
) = range(3)
#玩家通用信息记录类型
#膜拜类型
Def_WorshipTypeList = (
                       Def_WorshipType_ServerNaming, # 服务器冠名 1
                       Def_WorshipType_CrossChampionship, # 跨服排位冠军 2
                       ) = range(1, 1 + 2)
#跨服膜拜类型
Def_WorshipTypeCross = [Def_WorshipType_CrossChampionship]
#玩家记录类型
Def_PlayerRecTypeList = (
                         Def_PlayerRecType_WorshipPlayer, # 被膜拜的玩家 1
                         Def_PlayerRecType_WorshipDaily, # 玩家每日膜拜记录 2
                         ) = range(1, 1 + 2)
#玩家记录类型每人限制条数,没有配置的类型不限制,由功能自行控制
Def_PlayerRecCountDict = {
                          }
#通用信息记录类型
Def_UniversalGameRecTypeList = (
                                Def_UniversalGameRecType_XMZZPKInfoRecord, # 仙魔之争信息记录0
                                Def_UniversalGameRecType_HijackTruck,   # 劫镖1
@@ -1541,6 +1560,7 @@
CrossServerMsg_CrossYaomoBossHurtInfo = "CrossYaomoBossHurtInfo" # 跨服妖魔boss玩家伤害信息
CrossServerMsg_FamilyFlagwarOver = "FamilyFlagwarOver"  # 逐鹿万界结算信息
CrossServerMsg_CrossBossTrialFamilyAward = "CrossBossTrialFamilyAward"  # 跨服boss历练仙盟奖励结算
CrossServerMsg_Worship = "Worship"  # 膜拜信息
# 子服发送跨服信息定义
ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -2382,6 +2382,66 @@
#------------------------------------------------------
# B0 20 请求膜拜玩家 #tagCGWorship
class  tagCGWorship(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("PlayerID", c_int),    # 目标玩家ID
                  ("WorshipType", c_ubyte),    # 膜拜类型
                  ("WorshipValue", c_int),    # 膜拜类型对应的功能值,如名次或其他,由具体膜拜类型定义对应值含义
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB0
        self.SubCmd = 0x20
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xB0
        self.SubCmd = 0x20
        self.PlayerID = 0
        self.WorshipType = 0
        self.WorshipValue = 0
        return
    def GetLength(self):
        return sizeof(tagCGWorship)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B0 20 请求膜拜玩家 //tagCGWorship:
                                Cmd:%s,
                                SubCmd:%s,
                                PlayerID:%d,
                                WorshipType:%d,
                                WorshipValue:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.PlayerID,
                                self.WorshipType,
                                self.WorshipValue
                                )
        return DumpString
m_NAtagCGWorship=tagCGWorship()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGWorship.Cmd,m_NAtagCGWorship.SubCmd))] = m_NAtagCGWorship
#------------------------------------------------------
# B3 19 提升魅力等级 #tagCGCharmLVUp
class  tagCGCharmLVUp(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -8515,6 +8515,213 @@
#------------------------------------------------------
# B0 20 膜拜信息列表 #tagGCWorshipInfoList
class  tagGCWorshipInfo(Structure):
    PlayerID = 0    #(DWORD PlayerID)// 目标玩家ID
    WorshipType = 0    #(BYTE WorshipType)// 膜拜类型
    WorshipValue = 0    #(DWORD WorshipValue)// 膜拜类型对应的功能值,如名次或其他,由具体膜拜类型定义对应值含义
    InfoLen = 0    #(WORD InfoLen)
    PlayerInfo = ""    #(String PlayerInfo)// 玩家信息{k:v, ...}
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.WorshipType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.WorshipValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.InfoLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.PlayerInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.InfoLen)
        return _pos
    def Clear(self):
        self.PlayerID = 0
        self.WorshipType = 0
        self.WorshipValue = 0
        self.InfoLen = 0
        self.PlayerInfo = ""
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 1
        length += 4
        length += 2
        length += len(self.PlayerInfo)
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteBYTE(data, self.WorshipType)
        data = CommFunc.WriteDWORD(data, self.WorshipValue)
        data = CommFunc.WriteWORD(data, self.InfoLen)
        data = CommFunc.WriteString(data, self.InfoLen, self.PlayerInfo)
        return data
    def OutputString(self):
        DumpString = '''
                                PlayerID:%d,
                                WorshipType:%d,
                                WorshipValue:%d,
                                InfoLen:%d,
                                PlayerInfo:%s
                                '''\
                                %(
                                self.PlayerID,
                                self.WorshipType,
                                self.WorshipValue,
                                self.InfoLen,
                                self.PlayerInfo
                                )
        return DumpString
class  tagGCWorshipInfoList(Structure):
    Head = tagHead()
    WorshipCount = 0    #(BYTE WorshipCount)
    WorshipInfoList = list()    #(vector<tagGCWorshipInfo> WorshipInfoList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB0
        self.Head.SubCmd = 0x20
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.WorshipCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.WorshipCount):
            temWorshipInfoList = tagGCWorshipInfo()
            _pos = temWorshipInfoList.ReadData(_lpData, _pos)
            self.WorshipInfoList.append(temWorshipInfoList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB0
        self.Head.SubCmd = 0x20
        self.WorshipCount = 0
        self.WorshipInfoList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        for i in range(self.WorshipCount):
            length += self.WorshipInfoList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.WorshipCount)
        for i in range(self.WorshipCount):
            data = CommFunc.WriteString(data, self.WorshipInfoList[i].GetLength(), self.WorshipInfoList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                WorshipCount:%d,
                                WorshipInfoList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.WorshipCount,
                                "..."
                                )
        return DumpString
m_NAtagGCWorshipInfoList=tagGCWorshipInfoList()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCWorshipInfoList.Head.Cmd,m_NAtagGCWorshipInfoList.Head.SubCmd))] = m_NAtagGCWorshipInfoList
#------------------------------------------------------
# B0 21 膜拜结果 #tagGCWorshipResult
class  tagGCWorshipResult(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("PlayerID", c_int),    # 目标玩家ID
                  ("WorshipType", c_ubyte),    # 膜拜类型
                  ("WorshipValue", c_int),    # 膜拜类型对应的功能值,如名次或其他,由具体膜拜类型定义对应值含义
                  ("Result", c_ubyte),    # 膜拜结果:0-成功;1-不存在该膜拜类型;2-不存在该目标膜拜;3-不能膜拜该目标;
                  ("MoneyType", c_ubyte),    # 货币类型
                  ("MoneyValue", c_int),    # 货币奖励
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB0
        self.SubCmd = 0x21
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xB0
        self.SubCmd = 0x21
        self.PlayerID = 0
        self.WorshipType = 0
        self.WorshipValue = 0
        self.Result = 0
        self.MoneyType = 0
        self.MoneyValue = 0
        return
    def GetLength(self):
        return sizeof(tagGCWorshipResult)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B0 21 膜拜结果 //tagGCWorshipResult:
                                Cmd:%s,
                                SubCmd:%s,
                                PlayerID:%d,
                                WorshipType:%d,
                                WorshipValue:%d,
                                Result:%d,
                                MoneyType:%d,
                                MoneyValue:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.PlayerID,
                                self.WorshipType,
                                self.WorshipValue,
                                self.Result,
                                self.MoneyType,
                                self.MoneyValue
                                )
        return DumpString
m_NAtagGCWorshipResult=tagGCWorshipResult()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCWorshipResult.Cmd,m_NAtagGCWorshipResult.SubCmd))] = m_NAtagGCWorshipResult
#------------------------------------------------------
#B3 03 询问是否允许添加好友#tagGCFriendAskIfJoin
class  tagGCFriendAskIfJoin(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -6310,6 +6310,11 @@
def GetPayCoin(curPlayer): return curPlayer.GetExAttr11()
def SetPayCoin(curPlayer, value): return curPlayer.SetExAttr11(min(value, ChConfig.Def_UpperLimit_DWord), False, False)
## 获取佩戴的称号ID
def GetTitleID(curPlayer):
    curDienstgradMgr = curPlayer.GetDienstgradManager()
    return curDienstgradMgr.GetCurGradID()
##伴侣
def GetCoupleID(curPlayer):
    coupleInfo = GetCoupleInfo(curPlayer.GetPlayerID())
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
@@ -171,6 +171,7 @@
    curPlayerPropDict["Name"] = curPlayer.GetPlayerName()
    curPlayerPropDict["FamilyID"] = curPlayer.GetFamilyID()
    curPlayerPropDict["FamilyName"] = curPlayer.GetFamilyName()
    curPlayerPropDict["TitleID"] = PlayerControl.GetTitleID(curPlayer)
    curPlayerPropDict["CoupleName"] = PlayerControl.GetCoupleName(curPlayer)
    curPlayerPropDict["FightPower"] = PlayerControl.GetFightPower(curPlayer)
    curPlayerPropDict["AppID"] = GameWorld.GetPlayerPlatform(curPlayer)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GiveAward.py
New file
@@ -0,0 +1,52 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.RemoteQuery.GY_Query_GiveAward
#
# @todo:给奖励
# @author hxp
# @date 2024-07-02
# @version 1.0
#
# 详细描述: 给奖励
#
#-------------------------------------------------------------------------------
#"""Version = 2024-07-02 16:30"""
#-------------------------------------------------------------------------------
import PlayerControl
import ItemControler
import GameWorld
#逻辑实现
## 玩家请求领取奖励
#  @param query_Type 请求类型
#  @param query_ID 请求的玩家ID
#  @param packCMDList 发包命令
#  @param tick 当前时间
#  @return "True" or "False" or ""
#  @remarks 函数详细说明.
def DoLogic(query_Type, query_ID, packCMDList, tick):
    return ''
#---------------------------------------------------------------------
## 执行结果
#  @param curPlayer 发出请求的玩家
#  @param callFunName 功能名称
#  @param funResult 查询的结果
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def DoResult(curPlayer, callFunName, funResult, tick):
    GameWorld.Log("GY_Query_GiveAward funResult=%s" % str(funResult), curPlayer.GetPlayerID())
    if funResult == "":
        return
    eventName, moneyInfo, itemList, drDict = eval(funResult)
    if moneyInfo:
        for moneyType, moneyValue in moneyInfo.items():
            PlayerControl.GiveMoney(curPlayer, moneyType, moneyValue, eventName, drDict)
    ItemControler.GivePlayerItemOrMail(curPlayer, itemList, event=[eventName, False, drDict])
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1297,7 +1297,26 @@
Def_Weapon_Dual_Hands,  # 双持(左右手可互换)
) = range(3)
#玩家通用信息记录类型
#膜拜类型
Def_WorshipTypeList = (
                       Def_WorshipType_ServerNaming, # 服务器冠名 1
                       Def_WorshipType_CrossChampionship, # 跨服排位冠军 2
                       ) = range(1, 1 + 2)
#跨服膜拜类型
Def_WorshipTypeCross = [Def_WorshipType_CrossChampionship]
#玩家记录类型
Def_PlayerRecTypeList = (
                         Def_PlayerRecType_WorshipPlayer, # 被膜拜的玩家 1
                         Def_PlayerRecType_WorshipDaily, # 玩家每日膜拜记录 2
                         ) = range(1, 1 + 2)
#玩家记录类型每人限制条数,没有配置的类型不限制,由功能自行控制
Def_PlayerRecCountDict = {
                          }
#通用信息记录类型
Def_UniversalGameRecTypeList = (
                                Def_UniversalGameRecType_XMZZPKInfoRecord, # 仙魔之争信息记录0
                                Def_UniversalGameRecType_HijackTruck,   # 劫镖1
@@ -1541,6 +1560,7 @@
CrossServerMsg_CrossYaomoBossHurtInfo = "CrossYaomoBossHurtInfo" # 跨服妖魔boss玩家伤害信息
CrossServerMsg_FamilyFlagwarOver = "FamilyFlagwarOver"  # 逐鹿万界结算信息
CrossServerMsg_CrossBossTrialFamilyAward = "CrossBossTrialFamilyAward"  # 跨服boss历练仙盟奖励结算
CrossServerMsg_Worship = "Worship"  # 膜拜信息
# 子服发送跨服信息定义
ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功