10249 【越南】【砍树】仙宫(新增仙宫系统;跨服boss历练、跨服仙匣秘境、跨服骑宠养成;跨服古宝养成、跨服排位赛个人排行榜结算支持晋升仙宫;)
30个文件已修改
7个文件已添加
2991 ■■■■■ 已修改文件
PySysDB/PySysDBG.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/PyNetPack.ini 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py 539 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/Championship.py 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/Xiangong.py 117 ●●●●● 补丁 | 查看 | 原始文档 | 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 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameRecData.py 377 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameXiangong.py 366 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActBossTrial.py 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActGubao.py 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActHorsePetTrain.py 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActXianXiaMJ.py 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFuncTeam.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 539 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Xiangong.py 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_TiandaoQiyun.py 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerXiangong.py 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_Xiangong.py 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBG.h
@@ -600,6 +600,7 @@
    list        MemAwardItemList;    //仙盟榜成员奖励物品信息列表[[物品ID,个数,是否拍品], ...]
    DWORD        NeedScore;    //上榜所需积分
    dict        ScoreAwardEx;    //达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...}
    WORD        XiangongID;    //晋升仙宫ID
};
//Boss历练跨服活动表
@@ -662,6 +663,7 @@
    list        AwardItemList;    //奖励物品列表[[物品ID,个数,是否拍品], ...]
    DWORD        NeedScore;    //上榜所需积分
    dict        ScoreAwardEx;    //达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...}
    WORD        XiangongID;    //晋升仙宫ID
};
//古宝养成活动时间表
@@ -703,6 +705,7 @@
    list        AwardItemList;    //奖励物品列表[[物品ID,个数,是否拍品], ...]
    DWORD        NeedScore;    //上榜所需积分
    dict        ScoreAwardEx;    //达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...}
    WORD        XiangongID;    //晋升仙宫ID
};
//仙匣秘境活动时间表
@@ -746,6 +749,7 @@
    list        AwardItemList;    //奖励物品列表[[物品ID,个数,是否拍品], ...]
    DWORD        NeedScore;    //上榜所需积分
    dict        ScoreAwardEx;    //达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...}
    WORD        XiangongID;    //晋升仙宫ID
};
//天帝礼包活动时间表
@@ -1046,6 +1050,7 @@
    BYTE        _Rank;    // 名次
    list        RankAwardItemList;    //名次奖励物品列表
    WORD        MainOfficialID;    //主官职ID
    WORD        XiangongID;    //晋升仙宫ID
};
//跨服排位官职表
@@ -1420,6 +1425,19 @@
    list        MoneyRange;    //货币值范围
};
//仙宫表
struct tagXiangong
{
    WORD        _XiangongID;    //仙宫ID
    BYTE        ShowDays;    //展示天数
    BYTE        MoneyType;    //点赞货币类型
    DWORD        MoneyValue;    //货币值
    DWORD        TitleID;    //称号ID
    list        AwardItemList;    //晋级仙宫奖励物品列表
    char        MailKey;    //仙官通知邮件
};
//缥缈仙域表
struct tagFairyDomain
PySysDB/PySysDBPY.h
@@ -3158,3 +3158,19 @@
    list        ZLRewardItemList;    //战令奖励物品列表 [[物品ID,个数,是否拍品],...]
    list        ZLRewardItemListH;    //高级战令奖励物品列表 [[物品ID,个数,是否拍品],...]
};
//仙宫表
struct tagXiangong
{
    WORD        _XiangongID;    //仙宫ID
};
//仙宫天道树
struct tagTiandaoTree
{
    WORD        _AwardIndex;    //奖励索引
    DWORD        NeedQiyun;    //所需气运值
    list        AwardItemList;    //奖励物品列表
};
ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
@@ -580,6 +580,21 @@
PacketSubCMD_1=0x20
PacketCallFunc_1=OnWorship
[GameXiangong]
ScriptName = GameWorldLogic\GameXiangong.py
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 2
PacketCMD_1=0xA9
PacketSubCMD_1=0x06
PacketCallFunc_1=OnQueryXiangongRecPlayers
PacketCMD_2=0xA9
PacketSubCMD_2=0x07
PacketCallFunc_2=OnLikeXiangong
[GameWorldMineArea]
ScriptName = GameWorldLogic\GameWorldMineArea.py
Writer = hxp
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -1252,6 +1252,58 @@
#------------------------------------------------------
# A9 07 点赞仙宫 #tagCGLikeXiangong
class  tagCGLikeXiangong(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("XiangongID", c_ushort),    # 仙宫ID,为0时代表每日的仙宫点赞
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA9
        self.SubCmd = 0x07
        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 = 0xA9
        self.SubCmd = 0x07
        self.XiangongID = 0
        return
    def GetLength(self):
        return sizeof(tagCGLikeXiangong)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A9 07 点赞仙宫 //tagCGLikeXiangong:
                                Cmd:%s,
                                SubCmd:%s,
                                XiangongID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.XiangongID
                                )
        return DumpString
m_NAtagCGLikeXiangong=tagCGLikeXiangong()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGLikeXiangong.Cmd,m_NAtagCGLikeXiangong.SubCmd))] = m_NAtagCGLikeXiangong
#------------------------------------------------------
# A9 A5 查看竞技场对战玩家最新信息 #tagCGQueryArenaBattlePlayer
class  tagCGQueryArenaBattlePlayer(Structure):
@@ -1572,6 +1624,58 @@
#------------------------------------------------------
# A9 06 查看仙宫仙名录 #tagCGQueryXiangongRecPlayers
class  tagCGQueryXiangongRecPlayers(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("XiangongID", c_ushort),    # 仙宫ID
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA9
        self.SubCmd = 0x06
        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 = 0xA9
        self.SubCmd = 0x06
        self.XiangongID = 0
        return
    def GetLength(self):
        return sizeof(tagCGQueryXiangongRecPlayers)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A9 06 查看仙宫仙名录 //tagCGQueryXiangongRecPlayers:
                                Cmd:%s,
                                SubCmd:%s,
                                XiangongID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.XiangongID
                                )
        return DumpString
m_NAtagCGQueryXiangongRecPlayers=tagCGQueryXiangongRecPlayers()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryXiangongRecPlayers.Cmd,m_NAtagCGQueryXiangongRecPlayers.SubCmd))] = m_NAtagCGQueryXiangongRecPlayers
#------------------------------------------------------
#A9 A6 设置邮件(补偿)已读状态 #tagCGReadCompensation
class  tagCGReadCompensation(Structure):
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -5736,6 +5736,356 @@
#------------------------------------------------------
# A9 27 仙宫新晋玩家信息 #tagGCXiangongNewPlayerInfo
class  tagGCXiangongNewPlayer(Structure):
    AddTime = 0    #(DWORD AddTime)// 新晋时间戳
    ServerID = 0    #(DWORD ServerID)
    PlayerID = 0    #(DWORD PlayerID)
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)// 玩家名,size = NameLen
    LV = 0    #(WORD LV)// 玩家等级
    Job = 0    #(BYTE Job)// 玩家职业
    RealmLV = 0    #(WORD RealmLV)// 玩家境界
    EquipShowSwitch = 0    #(DWORD EquipShowSwitch)
    EquipShowIDCount = 0    #(BYTE EquipShowIDCount)
    EquipShowID = list()    #(vector<DWORD> EquipShowID)
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.AddTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.EquipShowSwitch,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.EquipShowIDCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.EquipShowIDCount):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.EquipShowID.append(value)
        return _pos
    def Clear(self):
        self.AddTime = 0
        self.ServerID = 0
        self.PlayerID = 0
        self.NameLen = 0
        self.Name = ""
        self.LV = 0
        self.Job = 0
        self.RealmLV = 0
        self.EquipShowSwitch = 0
        self.EquipShowIDCount = 0
        self.EquipShowID = list()
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 4
        length += 4
        length += 1
        length += len(self.Name)
        length += 2
        length += 1
        length += 2
        length += 4
        length += 1
        length += 4 * self.EquipShowIDCount
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.AddTime)
        data = CommFunc.WriteDWORD(data, self.ServerID)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteBYTE(data, self.Job)
        data = CommFunc.WriteWORD(data, self.RealmLV)
        data = CommFunc.WriteDWORD(data, self.EquipShowSwitch)
        data = CommFunc.WriteBYTE(data, self.EquipShowIDCount)
        for i in range(self.EquipShowIDCount):
            data = CommFunc.WriteDWORD(data, self.EquipShowID[i])
        return data
    def OutputString(self):
        DumpString = '''
                                AddTime:%d,
                                ServerID:%d,
                                PlayerID:%d,
                                NameLen:%d,
                                Name:%s,
                                LV:%d,
                                Job:%d,
                                RealmLV:%d,
                                EquipShowSwitch:%d,
                                EquipShowIDCount:%d,
                                EquipShowID:%s
                                '''\
                                %(
                                self.AddTime,
                                self.ServerID,
                                self.PlayerID,
                                self.NameLen,
                                self.Name,
                                self.LV,
                                self.Job,
                                self.RealmLV,
                                self.EquipShowSwitch,
                                self.EquipShowIDCount,
                                "..."
                                )
        return DumpString
class  tagGCXiangongNewPlayerInfo(Structure):
    Head = tagHead()
    XiangongID = 0    #(WORD XiangongID)// 仙宫ID
    NewPlayerCount = 0    #(BYTE NewPlayerCount)
    NewPlayerList = list()    #(vector<tagGCXiangongNewPlayer> NewPlayerList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x27
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.XiangongID,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.NewPlayerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.NewPlayerCount):
            temNewPlayerList = tagGCXiangongNewPlayer()
            _pos = temNewPlayerList.ReadData(_lpData, _pos)
            self.NewPlayerList.append(temNewPlayerList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x27
        self.XiangongID = 0
        self.NewPlayerCount = 0
        self.NewPlayerList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 2
        length += 1
        for i in range(self.NewPlayerCount):
            length += self.NewPlayerList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteWORD(data, self.XiangongID)
        data = CommFunc.WriteBYTE(data, self.NewPlayerCount)
        for i in range(self.NewPlayerCount):
            data = CommFunc.WriteString(data, self.NewPlayerList[i].GetLength(), self.NewPlayerList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                XiangongID:%d,
                                NewPlayerCount:%d,
                                NewPlayerList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.XiangongID,
                                self.NewPlayerCount,
                                "..."
                                )
        return DumpString
m_NAtagGCXiangongNewPlayerInfo=tagGCXiangongNewPlayerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCXiangongNewPlayerInfo.Head.Cmd,m_NAtagGCXiangongNewPlayerInfo.Head.SubCmd))] = m_NAtagGCXiangongNewPlayerInfo
#------------------------------------------------------
# A9 28 仙宫仙名录玩家信息 #tagGCXiangongRecPlayerInfo
class  tagGCXiangongRecPlayer(Structure):
    AddTime = 0    #(DWORD AddTime)// 新晋时间戳
    ServerID = 0    #(DWORD ServerID)
    PlayerID = 0    #(DWORD PlayerID)
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)// 玩家名,size = NameLen
    LV = 0    #(WORD LV)// 玩家等级
    Job = 0    #(BYTE Job)// 玩家职业
    RealmLV = 0    #(WORD RealmLV)// 玩家境界
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.AddTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.AddTime = 0
        self.ServerID = 0
        self.PlayerID = 0
        self.NameLen = 0
        self.Name = ""
        self.LV = 0
        self.Job = 0
        self.RealmLV = 0
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 4
        length += 4
        length += 1
        length += len(self.Name)
        length += 2
        length += 1
        length += 2
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.AddTime)
        data = CommFunc.WriteDWORD(data, self.ServerID)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteBYTE(data, self.Job)
        data = CommFunc.WriteWORD(data, self.RealmLV)
        return data
    def OutputString(self):
        DumpString = '''
                                AddTime:%d,
                                ServerID:%d,
                                PlayerID:%d,
                                NameLen:%d,
                                Name:%s,
                                LV:%d,
                                Job:%d,
                                RealmLV:%d
                                '''\
                                %(
                                self.AddTime,
                                self.ServerID,
                                self.PlayerID,
                                self.NameLen,
                                self.Name,
                                self.LV,
                                self.Job,
                                self.RealmLV
                                )
        return DumpString
class  tagGCXiangongRecPlayerInfo(Structure):
    Head = tagHead()
    XiangongID = 0    #(WORD XiangongID)// 仙宫ID
    RecPlayerCount = 0    #(BYTE RecPlayerCount)
    RecPlayerList = list()    #(vector<tagGCXiangongRecPlayer> RecPlayerList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x28
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.XiangongID,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.RecPlayerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.RecPlayerCount):
            temRecPlayerList = tagGCXiangongRecPlayer()
            _pos = temRecPlayerList.ReadData(_lpData, _pos)
            self.RecPlayerList.append(temRecPlayerList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x28
        self.XiangongID = 0
        self.RecPlayerCount = 0
        self.RecPlayerList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 2
        length += 1
        for i in range(self.RecPlayerCount):
            length += self.RecPlayerList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteWORD(data, self.XiangongID)
        data = CommFunc.WriteBYTE(data, self.RecPlayerCount)
        for i in range(self.RecPlayerCount):
            data = CommFunc.WriteString(data, self.RecPlayerList[i].GetLength(), self.RecPlayerList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                XiangongID:%d,
                                RecPlayerCount:%d,
                                RecPlayerList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.XiangongID,
                                self.RecPlayerCount,
                                "..."
                                )
        return DumpString
m_NAtagGCXiangongRecPlayerInfo=tagGCXiangongRecPlayerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCXiangongRecPlayerInfo.Head.Cmd,m_NAtagGCXiangongRecPlayerInfo.Head.SubCmd))] = m_NAtagGCXiangongRecPlayerInfo
#------------------------------------------------------
# AC 10 仙盟抢Boss所有Boss伤血进度信息 #tagGCAllFamilyBossHurtInfoList
class  tagGCFamilyBossHurtInfo(Structure):
@@ -50177,6 +50527,80 @@
#------------------------------------------------------
# B1 15 天道树信息 #tagMCTiandaoTreeInfo
class  tagMCTiandaoTreeInfo(Structure):
    Head = tagHead()
    Qiyun = 0    #(DWORD Qiyun)// 当前气运值
    AwardCount = 0    #(BYTE AwardCount)// 天道果领取记录值个数
    AwardStateList = list()    #(vector<DWORD> AwardStateList)// 天道果领取记录值列表,按奖励索引位二进制记录是否已领取,一个值可存31位,如值1存0~30,值2存31~61,...
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x15
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Qiyun,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.AwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.AwardCount):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.AwardStateList.append(value)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x15
        self.Qiyun = 0
        self.AwardCount = 0
        self.AwardStateList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 4
        length += 1
        length += 4 * self.AwardCount
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteDWORD(data, self.Qiyun)
        data = CommFunc.WriteBYTE(data, self.AwardCount)
        for i in range(self.AwardCount):
            data = CommFunc.WriteDWORD(data, self.AwardStateList[i])
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Qiyun:%d,
                                AwardCount:%d,
                                AwardStateList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Qiyun,
                                self.AwardCount,
                                "..."
                                )
        return DumpString
m_NAtagMCTiandaoTreeInfo=tagMCTiandaoTreeInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTiandaoTreeInfo.Head.Cmd,m_NAtagMCTiandaoTreeInfo.Head.SubCmd))] = m_NAtagMCTiandaoTreeInfo
#------------------------------------------------------
# B1 12 培养功能境界信息 #tagMCTrainRealmLVInfo
class  tagMCTrainRealmLV(Structure):
@@ -50285,6 +50709,121 @@
#------------------------------------------------------
# B1 14 仙宫信息 #tagMCXiangongInfo
class  tagMCXiangong(Structure):
    _pack_ = 1
    _fields_ = [
                  ("XiangongID", c_ushort),    # 仙宫ID
                  ("LikeStateToday", c_ubyte),    # 今日是否已点赞
                  ]
    def __init__(self):
        self.Clear()
        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.XiangongID = 0
        self.LikeStateToday = 0
        return
    def GetLength(self):
        return sizeof(tagMCXiangong)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B1 14 仙宫信息 //tagMCXiangongInfo:
                                XiangongID:%d,
                                LikeStateToday:%d
                                '''\
                                %(
                                self.XiangongID,
                                self.LikeStateToday
                                )
        return DumpString
class  tagMCXiangongInfo(Structure):
    Head = tagHead()
    LikeStateToday = 0    #(BYTE LikeStateToday)// 今日是否已点赞,指仙宫的外层点赞,非某个指定仙宫
    XiangongCount = 0    #(BYTE XiangongCount)
    XiangongList = list()    #(vector<tagMCXiangong> XiangongList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x14
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.LikeStateToday,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.XiangongCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.XiangongCount):
            temXiangongList = tagMCXiangong()
            _pos = temXiangongList.ReadData(_lpData, _pos)
            self.XiangongList.append(temXiangongList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x14
        self.LikeStateToday = 0
        self.XiangongCount = 0
        self.XiangongList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        for i in range(self.XiangongCount):
            length += self.XiangongList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.LikeStateToday)
        data = CommFunc.WriteBYTE(data, self.XiangongCount)
        for i in range(self.XiangongCount):
            data = CommFunc.WriteString(data, self.XiangongList[i].GetLength(), self.XiangongList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                LikeStateToday:%d,
                                XiangongCount:%d,
                                XiangongList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.LikeStateToday,
                                self.XiangongCount,
                                "..."
                                )
        return DumpString
m_NAtagMCXiangongInfo=tagMCXiangongInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCXiangongInfo.Head.Cmd,m_NAtagMCXiangongInfo.Head.SubCmd))] = m_NAtagMCXiangongInfo
#------------------------------------------------------
# B1 20 战令信息 #tagMCZhanlingInfo
class  tagMCZhanling(Structure):
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/Championship.py
@@ -19,6 +19,7 @@
import CrossChampionship
import PlayerDBGSEvent
import ShareDefine
import time
#逻辑实现
@@ -44,6 +45,9 @@
        GameWorld.DebugAnswer(curPlayer, "如果没有指定ID则该组重新随机匹配")
        GameWorld.DebugAnswer(curPlayer, "命令需在对应的阶段设置才有效;")
        GameWorld.DebugAnswer(curPlayer, "重置活动数据需在非活动时间重置,不然可能导致活动状态异常")
        GameWorld.DebugAnswer(curPlayer, "虚拟结算排名: Championship 8 分区 第1名ID ...")
        GameWorld.DebugAnswer(curPlayer, "虚拟结算执行: Championship over")
        GameWorld.DebugAnswer(curPlayer, "注:虚拟结算的命令主要用于快速测试结算用,玩家ID不足则假人代替")
        
    else:
        value1 = gmList[0]
@@ -207,9 +211,59 @@
        CrossChampionship.Send_CrossServerMsg_ChampionshipGroup(groupMark)
        return
    
    if value1 == 8:
        __FackOverData(playerID, serverGroupID, gmList)
        return
    if value1 == "over":
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "虚拟结算执行")
        CrossChampionship.DoCrossChampionshipFinalOver()
        return
    GameWorld.DebugAnswerCross(playerID, serverGroupID, "命令参数错误,详见命令说明")
    return
def __FackOverData(playerID, serverGroupID, gmList):
    ## 虚拟结算数据
    zoneID = gmList[1] if len(gmList) > 1 else 0
    rankPlayerIDList = gmList[2:]
    batPlayerCount = CrossChampionship.Def_CrossChampionshipPlayerWFCount
    # 先设置参赛玩家
    champMgr = CrossChampionship.GetChampionshipMgr()
    pkZoneMgr = champMgr.GetChampPKZoneMgr(zoneID, True)
    if len(rankPlayerIDList) < batPlayerCount:
        # 不足的机器人补足
        zonePlayerIDStar = zoneID * 100 + 1 # 确保每个分区的假人不重复
        rankPlayerIDList += range(zonePlayerIDStar, zonePlayerIDStar + (batPlayerCount - len(rankPlayerIDList)))
    pkZoneMgr.playerDict = {} # 清空玩家,重新设置
    CrossChampionship.Send_CrossServerMsg_ChampionshipPlayer(isSync=True, clearPlayer=True)
    for pID in rankPlayerIDList:
        batPlayer = CrossChampionship.ChampionshipBatPlayer()
        batPlayer.zoneID = zoneID
        batPlayer.playerID = pID
        pkZoneMgr.playerDict[pID] = batPlayer
    CrossChampionship.Send_CrossServerMsg_ChampionshipPlayer(isSync=True)
    # 虚拟战斗场次
    overTime = int(time.time())
    pkZoneMgr.battleInfo = {} # 清空对战记录
    battleIndexDict = {8:[[1, 5], [3, 7], [2, 6], [4, 8]], 4:[[1, 3], [5, 7], [2, 4], [6, 8]], 2:[[1, 2], [3, 4], [5, 6], [7, 8]]}
    for groupMark in [8, 4, 2]:
        battleList = battleIndexDict[groupMark]
        for battleNum in range(1, 1 + len(battleList)):
            battleRankInfo = battleList[battleNum - 1]
            battle = CrossChampionship.ChampionshipBattle()
            battle.overTime = overTime
            battle.zoneID = zoneID
            battle.groupMark = groupMark
            battle.battleNum = battleNum
            battle.playerIDA = rankPlayerIDList[battleRankInfo[0] - 1]
            battle.playerIDB = rankPlayerIDList[battleRankInfo[1] - 1]
            battle.winPlayerID = battle.playerIDA
            pkZoneMgr.AddBattle(groupMark, battleNum, battle)
        CrossChampionship.Send_CrossServerMsg_ChampionshipGroup(groupMark)
    GameWorld.DebugAnswerCross(playerID, serverGroupID, "虚拟结算排名:分区%s,%s" % (zoneID, rankPlayerIDList))
    return
def __PrintChampionshipInfo():
    GameWorld.Log("================ 跨服排位当前信息 ==================")
    ID = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_CrossChampionshipID)
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/Xiangong.py
New file
@@ -0,0 +1,117 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.Xiangong
#
# @todo:仙宫
# @author hxp
# @date 2024-09-04
# @version 1.0
#
# 详细描述: 仙宫
#
#-------------------------------------------------------------------------------
#"""Version = 2024-09-04 16:30"""
#-------------------------------------------------------------------------------
import GameWorld
import ShareDefine
import IpyGameDataPY
import PyDataManager
import GameXiangong
import random
import time
#逻辑实现
## 执行逻辑
#  @param curPlayer 当前玩家
#  @param gmList [cmdIndex gmAccID msg]
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, gmList):
    ## 本服处理
    if not gmList:
        GameWorld.DebugAnswer(curPlayer, "插入新晋仙官: Xiangong a 仙宫ID 个数 [可视区服IDA 至区服IDB 名次 可指定ID ...]")
        GameWorld.DebugAnswer(curPlayer, "清除仙宫仙官: Xiangong d 仙宫ID")
        GameWorld.DebugAnswer(curPlayer, "输出仙宫仙官: Xiangong p 仙宫ID")
        GameWorld.DebugAnswer(curPlayer, "注:插入指定仙官ID前提得该玩家在跨服有缓存")
        return
    return
def OnGetMergeParam(curPlayer):
    playerID = curPlayer.GetPlayerID()
    serverGroupID = GameWorld.GetServerGroupID()
    return [serverGroupID, playerID]
def OnMergeServerExec(gmList, tick):
    ## 跨服处理
    serverGroupID = gmList[-2]
    playerID = gmList[-1]
    gmList = gmList[:-2]
    if not gmList:
        return
    value1 = gmList[0]
    if value1 == "a":
        xiangongID = gmList[1] if len(gmList) > 1 else 0
        addCount = gmList[2] if len(gmList) > 2 else 1
        serverIDA = gmList[3] if len(gmList) > 3 else 1
        serverIDB = gmList[4] if len(gmList) > 4 else 9999
        order = gmList[5] if len(gmList) > 5 else None
        playerIDList = gmList[6:] if len(gmList) > 6 else []
        serverIDList = [[serverIDA, serverIDB]]
        ipyData = IpyGameDataPY.GetIpyGameData("Xiangong", xiangongID)
        if not ipyData:
            GameWorld.DebugAnswerCross(playerID, serverGroupID, "仙宫ID不存在:%s" % (xiangongID))
            return
        syncDict = {}
        for _ in xrange(addCount):
            if playerIDList:
                addPlayerID = playerIDList.pop(0)
            else:
                addPlayerID = random.randint(1000, 2000)
            GameXiangong.AddXiangongPlayer(xiangongID, addPlayerID, serverIDList, order, syncDict)
        GameXiangong.SendNewXiangongPlayerToClientServer(syncDict)
        gameRecMgr = PyDataManager.GetDBGameRecDataManager()
        recDataList = gameRecMgr.GetGameRecDataList(ShareDefine.Def_GameRecType_Xiangong, xiangongID)
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "插入新晋仙官:%s, 仙官ID:%s, 仙官总数:%s" % (addCount, xiangongID, len(recDataList)))
        return
    if value1 == "d":
        xiangongID = gmList[1] if len(gmList) > 1 else 0
        ipyData = IpyGameDataPY.GetIpyGameData("Xiangong", xiangongID)
        if not ipyData:
            GameWorld.DebugAnswerCross(playerID, serverGroupID, "仙宫ID不存在:%s" % (xiangongID))
            return
        gameRecMgr = PyDataManager.GetDBGameRecDataManager()
        delCount = gameRecMgr.DelGameRecDataByTypeID(ShareDefine.Def_GameRecType_Xiangong, xiangongID)
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "清除仙宫仙官:%s, 仙官ID:%s" % (delCount, xiangongID))
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "如果要获得正确的展示仙官请重登")
        return
    if value1 == "p":
        xiangongID = gmList[1] if len(gmList) > 1 else 0
        startIndex = gmList[2] if len(gmList) > 2 else 0
        gameRecMgr = PyDataManager.GetDBGameRecDataManager()
        recDataList = gameRecMgr.GetGameRecDataList(ShareDefine.Def_GameRecType_Xiangong, xiangongID)
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "仙宫ID:%s, 仙官总数:%s" % (xiangongID, len(recDataList)))
        curTime = int(time.time())
        for i, recData in enumerate(recDataList[startIndex:startIndex + 20], startIndex):
            xgPlayerID = GameXiangong.GetXGPlayerID(recData)
            serverIDList = recData.GetUserDataByKey(GameXiangong.Def_UserDataKey_ServerIDList)
            addTime = recData.GetTime()
            passDays = GameWorld.GetDiff_Day(curTime, addTime) + 1
            GameWorld.DebugAnswerCross(playerID, serverGroupID, " %s,ID:%s,天数:%s,区服:%s" % (i, xgPlayerID, passDays, serverIDList))
        return
    return
ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
@@ -476,6 +476,15 @@
        return mainServerID
    return 0
def CheckServerIDInList(serverID, serverIDList):
    if not serverIDList:
        return True
    for serverIDInfo in serverIDList:
        if (isinstance(serverIDInfo, tuple) and serverIDInfo[0] <= serverID <= serverIDInfo[1]) \
            or (isinstance(serverIDInfo, list) and serverIDInfo[0] <= serverID <= serverIDInfo[1]) \
            or (isinstance(serverIDInfo, int) and serverIDInfo == serverID):
            return True
    return False
#===============================================================================
# ƽ̨ID = appid
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossChampionship.py
@@ -29,6 +29,7 @@
import PlayerControl
import PyDataManager
import NetPackCommon
import GameXiangong
import GameWorship
import PyGameData
import ChConfig
@@ -1955,6 +1956,7 @@
    GameWorld.Log("pkZoneIDList=%s" % pkZoneIDList)
    
    worshipList = []
    syncNewXiangongDict = {}
    for zoneID in pkZoneIDList:
        GameWorld.Log("=== 结算排位分区: zoneID=%s ===" % zoneID, zoneID)
        finalPlayerIDList = []
@@ -1986,8 +1988,9 @@
            rankIpyData = IpyGameDataPY.GetIpyGameData("ChampionshipRank", rank)
            officialID = rankIpyData.GetMainOfficialID() if rankIpyData else 0
            rankAwardItemList = rankIpyData.GetRankAwardItemList() if rankIpyData else []
            GameWorld.Log("    最终排名: zoneID=%s,rank=%s,playerID=%s,officialID=%s,rankAwardItemList=%s,accID=%s,fightPower=%s"
                          % (zoneID, rank, playerID, officialID, rankAwardItemList, accID, fightPower), zoneID)
            xiangongID = rankIpyData.GetXiangongID() if rankIpyData else 0
            GameWorld.Log("    最终排名: zoneID=%s,rank=%s,playerID=%s,officialID=%s,xiangongID=%s,rankAwardItemList=%s,accID=%s,fightPower=%s"
                          % (zoneID, rank, playerID, officialID, xiangongID, rankAwardItemList, accID, fightPower), zoneID)
            
            if officialID:
                offObj = ChampionshipOfficial()
@@ -2007,6 +2010,12 @@
            paramList = [rank]
            PlayerCompensation.SendMailByKey("CrossChampionshipPKRank", [playerID], rankAwardItemList, paramList, crossMail=True)
            
            if xiangongID:
                crossZoneName = GameWorld.GetCrossZoneName()
                zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, zoneID)
                serverIDRangeList = zoneIpyData.GetServerGroupIDList() if zoneIpyData else []
                GameXiangong.AddXiangongPlayer(xiangongID, playerID, serverIDRangeList, rank, syncNewXiangongDict)
        # 处理4强竞猜发奖励
        guessType = 4
        moneyType = ShareDefine.TYPE_Price_GongdePoint
@@ -2048,6 +2057,7 @@
    
    # 通知新添加的膜拜
    GameWorship.SyncAddCrossWorship(worshipList)
    GameXiangong.SendNewXiangongPlayerToClientServer(syncNewXiangongDict)
    GameWorld.Log("===================================================================")
    return
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
@@ -37,6 +37,7 @@
import CrossYaomoBoss
import GameWorldBoss
import CrossRealmPK
import GameXiangong
import GameWorship
import PlayerQuery
import PlayerTalk
@@ -201,6 +202,9 @@
            
        elif msgType == ShareDefine.ClientServerMsg_QueryFuncTeam:
            PlayerFuncTeam.ClientServerMsg_QueryFuncTeam(serverGroupID, msgData)
        elif msgType == ShareDefine.ClientServerMsg_QueryXiangong:
            GameXiangong.ClientServerMsg_QueryXiangong(serverGroupID, msgData)
            
        # 需要发送到地图服务器处理的
        elif msgType in [ShareDefine.ClientServerMsg_Reborn, ShareDefine.ClientServerMsg_CollectNPC]:
@@ -408,6 +412,9 @@
        elif msgType == ShareDefine.CrossServerMsg_Worship:
            GameWorship.CrossServerMsg_Worship(msgData)
            
        elif msgType == ShareDefine.CrossServerMsg_Xiangong:
            GameXiangong.CrossServerMsg_Xiangong(msgData)
        elif msgType == ShareDefine.CrossServerMsg_ChampionshipState:
            CrossChampionship.CrossServerMsg_ChampionshipState(msgData)
            
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameRecData.py
New file
@@ -0,0 +1,377 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GameRecData
#
# @todo:通用记录表新
# @author hxp
# @date 2024-09-04
# @version 1.0
#
# 详细描述: 通用记录表新,原通用记录字符长度记录有限,且针对某个记录类型下的子类型查找每次需要遍历,效率不高
#
#-------------------------------------------------------------------------------
#"""Version = 2024-09-04 16:30"""
#-------------------------------------------------------------------------------
import GameWorld
import PyGameDataStruct
import ShareDefine
import CommFunc
import time
import json
class GameRecData():
    def __init__(self, dbRecData=None):
        if not dbRecData:
            dbRecData = PyGameDataStruct.tagDBGameRec()
        self.dbRecData = dbRecData
        self.__userDataDict = None
        self.__userDataChange = False
        return
    def clear(self):
        self.dbRecData.clear()
        self.__userDataDict = None
        self.__userDataChange = False
        return
    def GetRecType(self): return self.dbRecData.RecType
    def SetRecType(self, recType): self.dbRecData.RecType = recType
    def GetRecID(self): return self.dbRecData.RecID
    def SetRecID(self, recID): self.dbRecData.RecID = recID
    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 __GetUserDataDict(self):
        if self.__userDataDict == None:
            try:
                self.__userDataDict = eval(self.dbRecData.UserData)
            except:
                self.__userDataDict = {}
        return self.__userDataDict
    def GetUserDataByKey(self, key, defaultValue=None):
        userDataDict = self.__GetUserDataDict()
        return userDataDict.get(str(key), defaultValue)
    def SetUserDataByKey(self, key, value):
        userDataDict = self.__GetUserDataDict()
        userDataDict[str(key)] = value
        self.__userDataChange = True
        return
    def GetUserData(self):
        if self.__userDataChange:
            self.SaveUserData()
        return self.dbRecData.UserData
    def SaveUserData(self):
        userDataDict = self.__GetUserDataDict()
        self.dbRecData.UserData = json.dumps(userDataDict, ensure_ascii=False).replace(" ", "")
        self.dbRecData.UserDataLen = len(self.dbRecData.UserData)
        self.__userDataChange = False
        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 {"RecID":self.GetRecID(), "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(),
                "UserDataDict":self.__GetUserDataDict()
                }
    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)
            elif k == "UserDataDict":
                self.__userDataDict = v
        return
class DBGameRecDataManager():
    ## 通用记录管理
    def __init__(self):
        self.Clear()
        return
    def Clear(self):
        self.recTypeDict = {} # {recType:{recID:[GameRecData, ...], ...}}
        self.recValueIndexDict = {} # {recType:{recID:{indexKey:[GameRecData, ...], ...}, ...}, ...}
        return
    def DelGameRecDataByType(self, recType):
        ## 删除某个记录类型所有记录
        recDict = self.recTypeDict.pop(recType, {})
        delCount = 0
        for recList in recDict.values():
            delCount += len(recList)
        GameWorld.DebugLog("删除指定新通用记录类型所有记录: recType=%s,delCount=%s" % (recType, delCount))
        self.recValueIndexDict.pop(recType, {})
        return delCount
    def DelGameRecDataByTypeID(self, recType, delRecID):
        ## 删除某个类型对应的ID记录
        if recType not in self.recTypeDict:
            return 0
        recDataDict = self.recTypeDict[recType]
        recDataList = recDataDict.pop(delRecID, None)
        delCount = len(recDataList) if recDataList else 0
        GameWorld.DebugLog("删除指定新通用记录类型某个记录ID所有记录: recType=%s,delRecID=%s,delCount=%s" % (recType, delRecID, delCount))
        if recType in self.recValueIndexDict:
            recIndexDataDict = self.recValueIndexDict[recType]
            recIndexDataDict.pop(delRecID, None)
        return delCount
    def DelGameRecDataByTypeValue(self, recType, valueList, delRecID=None):
        ## 删除某个记录类型匹配Value值列表的记录
        # @param valueList: [value1, value2, ...] value为None时不判断该值
        # @param delRecID: 可指定只删除记录ID的记录
        if not valueList:
            return 0
        if recType not in self.recTypeDict:
            return 0
        delCountTotal = 0
        recDict = self.recTypeDict[recType]
        for recID, recDataList in recDict.items():
            if delRecID and recID != delRecID:
                continue
            delCount = 0
            for recData in recDataList[::-1]: # 倒序处理删除
                if recData.IsMatchValue(valueList):
                    delCount += self.DelGameRecData(recData)
            if delCount:
                delCountTotal += delCount
                GameWorld.DebugLog("删除某个新通用记录类型所有Value1匹配值的记录: recType=%s,valueList=%s,delRecID=%s,delCount=%s"
                                   % (recType, valueList, recID, delCount))
        return delCountTotal
    def DelGameRecData(self, recData):
        ## 删除指定记录
        recID = recData.GetRecID()
        recType = recData.GetRecType()
        if recType not in self.recTypeDict:
            return 0
        recDataDict = self.recTypeDict[recType]
        if recID not in recDataDict:
            return 0
        recDataList = recDataDict[recID]
        if recData in recDataList:
            recDataList.remove(recData)
        keyStr = self.__GetValueIndexKey(recData)
        if keyStr:
            recIndexDataDict = self.recValueIndexDict.get(recType, {})
            valueIndexDict = recIndexDataDict.get(recID, {})
            recIndexDataList = valueIndexDict.get(keyStr, [])
            if recData in recIndexDataList:
                recIndexDataList.remove(recData)
        return 1
    def AddGameRecData(self, recType, recID, valueSetList=None, maxCount=0):
        '''添加记录
        @param recType: 记录类型
        @param recID: 记录类型对应的子ID,比如可以是玩家ID或者其他自定的ID,该ID在同个记录类型中唯一,不同记录类型可重复
        @param valueList: [value1, value2, ...] 设置的Value值列表
        @param maxCount: 每种记录ID最大可保存记录条数,默认0不限制
        '''
        recData = GameRecData()
        recData.clear()
        recData.SetRecType(recType)
        recData.SetRecID(recID)
        recData.SetTime(int(time.time()))
        if valueSetList:
            for num, v in enumerate(valueSetList, 1):
                if not hasattr(recData, "SetValue%s" % num):
                    continue
                getattr(recData, "SetValue%s" % num)(v)
        recDataList = self.__AddGameRecData(recData)
        doCount = len(recDataList)
        while maxCount and len(recDataList) > maxCount and doCount > 0:
            GameWorld.DebugLog("超过记录上限删除记录: recType=%s,recID=%s,recCount=%s,maxCount=%s" % (recType, recID, len(recDataList), maxCount))
            doCount -= 1
            self.DelGameRecData(recDataList[0]) # 超过最大上限,删除第一个
        return recData
    def AddGameRecDataByDict(self, attrDict):
        ## 一般是跨服同步过来数据添加用
        recData = GameRecData()
        recData.SetAttr(attrDict, True)
        self.__AddGameRecData(recData)
        return recData
    def __AddGameRecData(self, recData):
        recID = recData.GetRecID()
        recType = recData.GetRecType()
        if recType not in self.recTypeDict:
            self.recTypeDict[recType] = {}
        recDataDict = self.recTypeDict[recType]
        if recID not in recDataDict:
            recDataDict[recID] = []
        recDataList = recDataDict[recID]
        recDataList.append(recData)
        keyStr = self.__GetValueIndexKey(recData)
        if keyStr:
            if recType not in self.recValueIndexDict:
                self.recValueIndexDict[recType] = {}
            recIndexDataDict = self.recValueIndexDict[recType]
            if recID not in recIndexDataDict:
                recIndexDataDict[recID] = {}
            valueIndexDict = recIndexDataDict[recID]
            if keyStr not in valueIndexDict:
                valueIndexDict[keyStr] = []
            recIndexDataList = valueIndexDict[keyStr]
            recIndexDataList.append(recData)
        return recDataList
    def __GetValueIndexKey(self, recData):
        ## 获取记录对象对应字典key值,默认使用value1
        recType = recData.GetRecType()
        if recType not in ShareDefine.Def_GameRecValueKeyDict:
            return
        valueNumList = ShareDefine.Def_GameRecValueKeyDict[recType]
        if not valueNumList:
            valueNumList = [1]
        keyStr = ""
        for num in valueNumList:
            if not hasattr(recData, "GetValue%s" % num):
                return
            if keyStr:
                keyStr += "_"
            keyStr += str(getattr(recData, "GetValue%s" % num)())
        return keyStr
    def GetGameRecDataMatch(self, recType, recID, valueList, findone=False):
        '''获取记录类型对应的匹配value值记录
        @param recType: 记录类型
        @param recID: 记录类型对应的子ID
        @param valueList: [value1, value2, ...] value为None时不判断该值
        @param findone: 是否只匹配一条满足的记录
        @return: recData or [recData, ...] or None
        '''
        # 有配置value索引key的,直接快速获取
        if recType in ShareDefine.Def_GameRecValueKeyDict:
            if recType not in self.recValueIndexDict:
                return
            recIndexDataDict = self.recValueIndexDict[recType]
            if recID not in recIndexDataDict:
                return
            valueIndexDict = recIndexDataDict[recID]
            keyStr = ""
            for v in valueList:
                if keyStr:
                    keyStr += "_"
                keyStr += str(v)
            if keyStr not in valueIndexDict:
                return
            recIndexDataList = valueIndexDict[keyStr]
            if not recIndexDataList:
                return
            return recIndexDataList[0] if findone else recIndexDataList
        # 没有的则遍历匹配
        recDataList = self.GetGameRecDataList(recType, recID)
        if not recDataList:
            return
        matchRecDataList = []
        for recData in recDataList:
            if not recData.IsMatchValue(valueList):
                continue
            if findone:
                return recData
            matchRecDataList.append(recData)
        return matchRecDataList
    def GetGameRecDataList(self, recType, recID):
        ## 获取记录类型对应记录列表 [recData, ...]
        if recType not in self.recTypeDict:
            self.recTypeDict[recType] = {}
        recDataDict = self.recTypeDict[recType]
        if recID not in recDataDict:
            recDataDict[recID] = []
        recDataList = recDataDict[recID]
        return recDataList
    def GetGameRecDataDict(self, recType):
        ## 获取记录类型对应所有记录字典 {recID:[recData, ...], ...}
        if recType not in self.recTypeDict:
            return {}
        return self.recTypeDict[recType]
    def SortGameRecDataList(self, recDataList):
        recDataList.sort(key=lambda r: (r.GetTime()), reverse=False)
        return
    # 保存数据 存数据库和realtimebackup
    def GetSaveData(self):
        savaData = ""
        cntData = ""
        cnt = 0
        for recDataDict in self.recTypeDict.values():
            for recDataList in recDataDict.values():
                for recData in recDataList:
                    cnt += 1
                    recData.SaveUserData()
                    savaData += recData.dbRecData.getBuffer()
        GameWorld.Log("Save DBGameRec 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 DBGameRec count :%s" % cnt)
        self.Clear()
        for _ in xrange(cnt):
            recData = PyGameDataStruct.tagDBGameRec()
            recData.clear()
            pos += recData.readData(datas, pos, dataslen)
            self.__AddGameRecData(GameRecData(recData))
        # 按时间升序排序下
        for recDataDict in self.recTypeDict.values():
            for recDataList in recDataDict.values():
                recDataList.sort(key=lambda d: (d.GetTime()))
        return pos
GameRecDataTemp = GameRecData()
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameXiangong.py
New file
@@ -0,0 +1,366 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GameXiangong
#
# @todo:仙宫
# @author hxp
# @date 2024-09-04
# @version 1.0
#
# 详细描述: 仙宫
#
#-------------------------------------------------------------------------------
#"""Version = 2024-09-04 16:30"""
#-------------------------------------------------------------------------------
import ShareDefine
import PyDataManager
import NetPackCommon
import ChPyNetSendPack
import PlayerCompensation
import PlayerViewCache
import CrossRealmMsg
import IpyGameDataPY
import PyGameData
import GameWorld
import time
Def_UserDataKey_ServerIDList = "ServerIDList"
Def_UserDataKey_PlayerInfo = "PlayerInfo"
# 仙宫玩家记录
def GetXGPlayerID(recData): return recData.GetValue1() # 仙宫玩家ID
##--------------------------------------------------------------------------------------------------
def OnPlayerLogin_CrossLogic(serverGroupID, serverID, playerID):
    ## 玩家登录 - 跨服处理逻辑
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetXiangongCount()):
        ipyData = ipyDataMgr.GetXiangongByIndex(index)
        if not ipyData:
            continue
        SendShowXiangongPlayerToClientServer(ipyData, serverGroupID, serverID, playerID)
    return
def IsXiangongPlayer(playerID):
    ## 是否仙宫玩家
    gameRecMgr = PyDataManager.GetDBGameRecDataManager()
    recDataDict = gameRecMgr.GetGameRecDataDict(ShareDefine.Def_GameRecType_Xiangong)
    for xiangongID in recDataDict.keys():
        if gameRecMgr.GetGameRecDataMatch(ShareDefine.Def_GameRecType_Xiangong, xiangongID, [playerID], findone=True):
            return True
    return False
def AddXiangongPlayer(xiangongID, playerID, serverIDList, rank=None, syncDict=None):
    ## 添加新晋仙官玩家
    if not xiangongID:
        return
    ipyData = IpyGameDataPY.GetIpyGameData("Xiangong", xiangongID)
    if not ipyData:
        return
    gameRecMgr = PyDataManager.GetDBGameRecDataManager()
    recData = gameRecMgr.AddGameRecData(ShareDefine.Def_GameRecType_Xiangong, xiangongID, [playerID])
    playerInfo = PlayerViewCache.GetShotCacheDict(playerID, "ServerID")
    serverID = playerInfo.get("ServerID", 0)
    saveServerIDList = [] + serverIDList # 重新创建一份存储,不改变传入值
    # 确保玩家自身一定能看到自己,跨服排位赛历史分区问题
    if saveServerIDList and serverID and not GameWorld.CheckServerIDInList(serverID, saveServerIDList):
        saveServerIDList.append(serverID)
    recData.SetUserDataByKey(Def_UserDataKey_ServerIDList, saveServerIDList) # 保存当下的区服ID范围
    recData.SetUserDataByKey(Def_UserDataKey_PlayerInfo, playerInfo) # 保存当下的玩家基本信息
    GameWorld.Log("新晋仙官玩家: xiangongID=%s,playerID=%s,rank=%s,serverID=%s,saveServerIDList=%s,%s"
                  % (xiangongID, playerID, rank, serverID, saveServerIDList, playerInfo))
    # 晋升邮件通知
    if playerID > 10000 and rank:
        titleID = ipyData.GetTitleID()
        addItemList = ipyData.GetAwardItemList()
        addQiyun = 0 if not addItemList else addItemList[0][1]
        paramList = [rank, titleID, addQiyun]
        PlayerCompensation.SendMailByKey(ipyData.GetMailKey(), [playerID], addItemList, paramList, crossMail=True)
    if isinstance(syncDict, dict):
        if xiangongID not in syncDict:
            syncDict[xiangongID] = []
        newRecDataList = syncDict[xiangongID]
        newRecDataList.append(recData)
    return
def SendNewXiangongPlayerToClientServer(syncDict):
    ## 同步新晋仙宫玩家到子服
    if not syncDict or not isinstance(syncDict, dict):
        return
    for xiangongID, newRecDataList in syncDict.items():
        ipyData = IpyGameDataPY.GetIpyGameData("Xiangong", xiangongID)
        if not ipyData:
            continue
        SendShowXiangongPlayerToClientServer(ipyData, syncRecDataList=newRecDataList)
    return
def SendShowXiangongPlayerToClientServer(ipyData, serverGroupID=0, playerServerID=0, queryPlayerID=0, syncRecDataList=None):
    ## 发送需要展示的新晋仙宫玩家到子服
    if not ipyData:
        return
    xiangongID = ipyData.GetXiangongID()
    showDays = ipyData.GetShowDays()
    curTime = int(time.time())
    if syncRecDataList:
        recDataList = syncRecDataList
    else:
        gameRecMgr = PyDataManager.GetDBGameRecDataManager()
        recDataList = gameRecMgr.GetGameRecDataList(ShareDefine.Def_GameRecType_Xiangong, xiangongID)
    if not recDataList:
        return
    GameWorld.DebugLog("发送需要展示的新晋仙宫玩家到子服: xiangongID=%s,recDataLen=%s" % (xiangongID, len(recDataList)))
    GameWorld.DebugLog("serverGroupID=%s,playerServerID=%s,queryPlayerID=%s" % (serverGroupID, playerServerID, queryPlayerID))
    playerInfoList = []
    for recData in recDataList[::-1]:
        xgPlayerID = GetXGPlayerID(recData)
        addTime = recData.GetTime()
        passDays = GameWorld.GetDiff_Day(curTime, addTime) + 1
        if passDays > showDays:
            GameWorld.DebugLog("    xgPlayerID=%s,addTime=%s,passDays=%s > %s" % (xgPlayerID, addTime, passDays, showDays))
            break
        serverIDList = recData.GetUserDataByKey(Def_UserDataKey_ServerIDList)
        if playerServerID:
            if serverIDList == None:
                GameWorld.DebugLog("    xgPlayerID=%s,serverIDList is None" % (xgPlayerID))
                continue
            if not GameWorld.CheckServerIDInList(playerServerID, serverIDList):
                GameWorld.DebugLog("    xgPlayerID=%s,playerServerID=%s not in %s" % (xgPlayerID, playerServerID, serverIDList))
                continue
        playerInfo = PlayerViewCache.GetShotCacheDict(xgPlayerID, "PlayerID", "ServerID", "Model")
        if not playerInfo:
            GameWorld.Log("找不到玩家缓存的暂不同步仙宫新晋仙官! xgPlayerID=%s" % xgPlayerID)
            continue
        playerInfo["AddTime"] = addTime
        playerInfo["ServerIDList"] = serverIDList
        playerInfoList.insert(0, playerInfo)
    GameWorld.DebugLog("playerInfoListLen=%s" % (len(playerInfoList)))
    if not playerInfoList:
        return
    serverGroupIDList = [serverGroupID] if serverGroupID else []
    dataMsg = {"msgType":"ShowXiangongPlayer", "xiangongID":xiangongID, "playerInfoList":playerInfoList, "queryPlayerID":queryPlayerID}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Xiangong, dataMsg, serverGroupIDList)
    return
def ClientServerMsg_QueryXiangong(serverGroupID, msgData):
    ## 收到子服 - 查看仙名录
    serverID = msgData["serverID"]
    queryPlayerID = msgData["queryPlayerID"]
    xiangongID = msgData["xiangongID"]
    playerInfoList = []
    maxSyncCount = min(IpyGameDataPY.GetFuncCfg("XiangongSet", 2), 200)
    gameRecMgr = PyDataManager.GetDBGameRecDataManager()
    recDataList = gameRecMgr.GetGameRecDataList(ShareDefine.Def_GameRecType_Xiangong, xiangongID)
    for recData in recDataList[::-1]:
        serverIDList = recData.GetUserDataByKey(Def_UserDataKey_ServerIDList)
        playerInfo = recData.GetUserDataByKey(Def_UserDataKey_PlayerInfo)
        if not playerInfo or not GameWorld.CheckServerIDInList(serverID, serverIDList):
            continue
        playerInfo["AddTime"] = recData.GetTime()
        playerInfo["PlayerID"] = GetXGPlayerID(recData)
        playerInfoList.insert(0, playerInfo)
        if len(playerInfoList) >= maxSyncCount:
            break
    # 没有记录也要回包
    serverGroupList = [serverGroupID] # 仅通知查询服即可
    sendMsg = {"msgType":"QueryXiangongPlayer", "xiangongID":xiangongID, "playerInfoList":playerInfoList, "queryPlayerID":queryPlayerID}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Xiangong, sendMsg, serverGroupList)
    return
##--------------------------------------------------------------------------------------------------
#// A9 06 查看仙宫仙名录 #tagCGQueryXiangongRecPlayers
#
#struct    tagCGQueryXiangongRecPlayers
#{
#    tagHead        Head;
#    WORD        XiangongID;    // 仙宫ID
#};
def OnQueryXiangongRecPlayers(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    xiangongID = clientData.XiangongID
    serverID = GameWorld.GetPlayerServerID(curPlayer)
    dataMsg = {"serverID":serverID, "queryPlayerID":playerID, "xiangongID":xiangongID}
    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_QueryXiangong, dataMsg)
    return
#// A9 07 点赞仙宫 #tagCGLikeXiangong
#
#struct    tagCGLikeXiangong
#{
#    tagHead        Head;
#    WORD        XiangongID;    // 仙宫ID,为0时代表每日的仙宫点赞
#};
def OnLikeXiangong(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    xiangongID = clientData.XiangongID
    if xiangongID:
        ipyData = IpyGameDataPY.GetIpyGameData("Xiangong", xiangongID)
        if not ipyData:
            return
        showDays = ipyData.GetShowDays()
        timeDict = PyGameData.g_xiangongCanLikeTimeDict.get(playerID, {})
        if xiangongID not in timeDict:
            GameWorld.DebugLog("该仙宫没有需要展示的新晋玩家记录! xiangongID=%s" % xiangongID, playerID)
            return
        addTime = timeDict[xiangongID]
        passDays = GameWorld.GetDiff_Day(int(time.time()), addTime) + 1
        if passDays > showDays:
            GameWorld.DebugLog("该仙宫新晋展示时间超过最大展示天数,无法点赞! xiangongID=%s,addTime=%s,passDays=%s > %s"
                               % (xiangongID, addTime, passDays, showDays), playerID)
            return
        moneyType, moneyValue = ipyData.GetMoneyType(), ipyData.GetMoneyValue()
    else:
        moneyType, moneyValue = IpyGameDataPY.GetFuncEvalCfg("XiangongSet", 1)
    msgInfo = str(["LikeXiangong", [xiangongID, moneyType, moneyValue]])
    curPlayer.MapServer_QueryPlayerResult(0, 0, "Xiangong", msgInfo, len(msgInfo))
    return
def CrossServerMsg_Xiangong(msgData):
    ## 子服收到跨服信息
    msgType = msgData["msgType"]
    if msgType == "ShowXiangongPlayer":
        __Client_ShowXiangongPlayer(msgData)
    elif msgType == "QueryXiangongPlayer":
        __Client_QueryXiangongPlayer(msgData)
    return
def __Client_ShowXiangongPlayer(msgData):
    ## 子服收到 - 跨服同步展示的新晋仙宫玩家
    xiangongID = msgData["xiangongID"]
    playerInfoList = msgData["playerInfoList"]
    queryPlayerID = msgData.get("queryPlayerID", 0)
    if not playerInfoList:
        return
    newPlayerList = []
    for playerInfo in playerInfoList:
        newP = ChPyNetSendPack.tagGCXiangongNewPlayer()
        newP.AddTime = playerInfo["AddTime"]
        newP.ServerID = playerInfo["ServerID"]
        newP.PlayerID = playerInfo["PlayerID"]
        newP.Name = playerInfo["Name"]
        newP.NameLen = len(newP.Name)
        newP.LV = playerInfo["LV"]
        newP.Job = playerInfo["Job"]
        newP.RealmLV = playerInfo["RealmLV"]
        newP.EquipShowSwitch = playerInfo["EquipShowSwitch"]
        newP.EquipShowID = playerInfo["EquipShowID"]
        newP.EquipShowIDCount = len(newP.EquipShowID)
        newPlayerList.append(newP)
    if not newPlayerList:
        return
    if queryPlayerID:
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(queryPlayerID)
        if not curPlayer:
            return
        __updXiangongCanLikeTime(queryPlayerID, xiangongID, playerInfoList[-1]["AddTime"])
        clientPack = ChPyNetSendPack.tagGCXiangongNewPlayerInfo()
        clientPack.XiangongID = xiangongID
        clientPack.NewPlayerList = newPlayerList[-255:]
        clientPack.NewPlayerCount = len(clientPack.NewPlayerList)
        NetPackCommon.SendFakePack(curPlayer, clientPack)
        return
    ## 全服同步
    clientPack = ChPyNetSendPack.tagGCXiangongNewPlayerInfo()
    clientPack.XiangongID = xiangongID
    playerManager = GameWorld.GetPlayerManager()
    for i in range(0, playerManager.GetPlayerCount()):
        curPlayer = playerManager.GetPlayerByIndex(i)
        if curPlayer == None or not curPlayer.GetInitOK():
            continue
        syncNewPlayerList = []
        for nIndex, newP in enumerate(newPlayerList):
            playerInfo = playerInfoList[nIndex]
            serverIDList = playerInfo["ServerIDList"]
            if not GameWorld.CheckServerIDInList(GameWorld.GetPlayerServerID(curPlayer), serverIDList):
                continue
            syncNewPlayerList.append(newP)
            __updXiangongCanLikeTime(curPlayer.GetPlayerID(), xiangongID, playerInfo["AddTime"])
        if not syncNewPlayerList:
            continue
        clientPack.NewPlayerList = syncNewPlayerList[-255:]
        clientPack.NewPlayerCount = len(clientPack.NewPlayerList)
        NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def __updXiangongCanLikeTime(playerID, xiangongID, addTime):
    if playerID not in PyGameData.g_xiangongCanLikeTimeDict:
        PyGameData.g_xiangongCanLikeTimeDict[playerID] = {}
    timeDict = PyGameData.g_xiangongCanLikeTimeDict[playerID]
    canLikeTime = timeDict.get(xiangongID, 0)
    if addTime > canLikeTime:
        timeDict[xiangongID] = addTime
        GameWorld.DebugLog("更新玩家对应仙宫可点赞的最新时间戳: xiangongID=%s,addTime=%s" % (xiangongID, addTime), playerID)
    return
def __Client_QueryXiangongPlayer(msgData):
    ## 子服收到 - 跨服同步的查询仙名录回包
    xiangongID = msgData["xiangongID"]
    playerInfoList = msgData["playerInfoList"]
    queryPlayerID = msgData.get("queryPlayerID", 0)
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(queryPlayerID)
    if not curPlayer:
        return
    recPlayerList = []
    for playerInfo in playerInfoList:
        if not playerInfo:
            continue
        recP = ChPyNetSendPack.tagGCXiangongRecPlayer()
        recP.AddTime = playerInfo["AddTime"]
        recP.ServerID = playerInfo["ServerID"]
        recP.PlayerID = playerInfo["PlayerID"]
        recP.Name = playerInfo["Name"]
        recP.NameLen = len(recP.Name)
        recP.LV = playerInfo["LV"]
        recP.Job = playerInfo["Job"]
        recP.RealmLV = playerInfo["RealmLV"]
        recPlayerList.append(recP)
    clientPack = ChPyNetSendPack.tagGCXiangongRecPlayerInfo()
    clientPack.XiangongID = xiangongID
    clientPack.RecPlayerList = recPlayerList
    clientPack.RecPlayerCount = len(clientPack.RecPlayerList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
@@ -499,6 +499,7 @@
                        ("list", "MemAwardItemList", 0),
                        ("DWORD", "NeedScore", 0),
                        ("dict", "ScoreAwardEx", 0),
                        ("WORD", "XiangongID", 0),
                        ),
                "CrossActBossTrial":(
@@ -549,6 +550,7 @@
                        ("list", "AwardItemList", 0),
                        ("DWORD", "NeedScore", 0),
                        ("dict", "ScoreAwardEx", 0),
                        ("WORD", "XiangongID", 0),
                        ),
                "ActGubao":(
@@ -581,6 +583,7 @@
                        ("list", "AwardItemList", 0),
                        ("DWORD", "NeedScore", 0),
                        ("dict", "ScoreAwardEx", 0),
                        ("WORD", "XiangongID", 0),
                        ),
                "ActXianXiaMJ":(
@@ -615,6 +618,7 @@
                        ("list", "AwardItemList", 0),
                        ("DWORD", "NeedScore", 0),
                        ("dict", "ScoreAwardEx", 0),
                        ("WORD", "XiangongID", 0),
                        ),
                "ActGodGift":(
@@ -851,6 +855,7 @@
                        ("BYTE", "Rank", 1),
                        ("list", "RankAwardItemList", 0),
                        ("WORD", "MainOfficialID", 0),
                        ("WORD", "XiangongID", 0),
                        ),
                "ChampionshipOfficial":(
@@ -1139,6 +1144,16 @@
                        ("BYTE", "WorshipDays", 0),
                        ("BYTE", "MoneyType", 0),
                        ("list", "MoneyRange", 0),
                        ),
                "Xiangong":(
                        ("WORD", "XiangongID", 1),
                        ("BYTE", "ShowDays", 0),
                        ("BYTE", "MoneyType", 0),
                        ("DWORD", "MoneyValue", 0),
                        ("DWORD", "TitleID", 0),
                        ("list", "AwardItemList", 0),
                        ("char", "MailKey", 0),
                        ),
                "FairyDomain":(
@@ -1840,7 +1855,8 @@
    def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品列表[[物品ID,个数,是否拍品], ...] 仙盟榜时为盟主奖励,如果没有配置,则统一取成员奖励 list
    def GetMemAwardItemList(self): return self.attrTuple[3] # 仙盟榜成员奖励物品信息列表[[物品ID,个数,是否拍品], ...] list
    def GetNeedScore(self): return self.attrTuple[4] # 上榜所需积分 DWORD
    def GetScoreAwardEx(self): return self.attrTuple[5] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict
    def GetScoreAwardEx(self): return self.attrTuple[5] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict
    def GetXiangongID(self): return self.attrTuple[6] # 晋升仙宫ID WORD
# Boss历练跨服活动表
class IPY_CrossActBossTrial():
@@ -1910,7 +1926,8 @@
    def GetRank(self): return self.attrTuple[1] # 名次 BYTE
    def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品列表[[物品ID,个数,是否拍品], ...] list
    def GetNeedScore(self): return self.attrTuple[3] # 上榜所需积分 DWORD
    def GetScoreAwardEx(self): return self.attrTuple[4] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict
    def GetScoreAwardEx(self): return self.attrTuple[4] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict
    def GetXiangongID(self): return self.attrTuple[5] # 晋升仙宫ID WORD
# 古宝养成活动时间表
class IPY_ActGubao():
@@ -1957,7 +1974,8 @@
    def GetRank(self): return self.attrTuple[1] # 名次 BYTE
    def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品列表[[物品ID,个数,是否拍品], ...] list
    def GetNeedScore(self): return self.attrTuple[3] # 上榜所需积分 DWORD
    def GetScoreAwardEx(self): return self.attrTuple[4] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict
    def GetScoreAwardEx(self): return self.attrTuple[4] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict
    def GetXiangongID(self): return self.attrTuple[5] # 晋升仙宫ID WORD
# 仙匣秘境活动时间表
class IPY_ActXianXiaMJ():
@@ -2006,7 +2024,8 @@
    def GetRank(self): return self.attrTuple[1] # 名次 BYTE
    def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品列表[[物品ID,个数,是否拍品], ...] list
    def GetNeedScore(self): return self.attrTuple[3] # 上榜所需积分 DWORD
    def GetScoreAwardEx(self): return self.attrTuple[4] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict
    def GetScoreAwardEx(self): return self.attrTuple[4] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict
    def GetXiangongID(self): return self.attrTuple[5] # 晋升仙宫ID WORD
# 天帝礼包活动时间表
class IPY_ActGodGift():
@@ -2347,7 +2366,8 @@
        
    def GetRank(self): return self.attrTuple[0] #  名次 BYTE
    def GetRankAwardItemList(self): return self.attrTuple[1] # 名次奖励物品列表 list
    def GetMainOfficialID(self): return self.attrTuple[2] # 主官职ID WORD
    def GetMainOfficialID(self): return self.attrTuple[2] # 主官职ID WORD
    def GetXiangongID(self): return self.attrTuple[3] # 晋升仙宫ID WORD
# 跨服排位官职表
class IPY_ChampionshipOfficial():
@@ -2777,6 +2797,21 @@
    def GetMoneyType(self): return self.attrTuple[3] # 膜拜货币类型 BYTE
    def GetMoneyRange(self): return self.attrTuple[4] # 货币值范围 list
# 仙宫表
class IPY_Xiangong():
    def __init__(self):
        self.attrTuple = None
        return
    def GetXiangongID(self): return self.attrTuple[0] # 仙宫ID WORD
    def GetShowDays(self): return self.attrTuple[1] # 展示天数 BYTE
    def GetMoneyType(self): return self.attrTuple[2] # 点赞货币类型 BYTE
    def GetMoneyValue(self): return self.attrTuple[3] # 货币值 DWORD
    def GetTitleID(self): return self.attrTuple[4] # 称号ID DWORD
    def GetAwardItemList(self): return self.attrTuple[5] # 晋级仙宫奖励物品列表 list
    def GetMailKey(self): return self.attrTuple[6] # 仙官通知邮件 char
# 缥缈仙域表
class IPY_FairyDomain():
    
@@ -2947,6 +2982,7 @@
        self.__LoadFileData("FamilyWarRankAward", onlyCheck)
        self.__LoadFileData("AssistThanksGift", onlyCheck)
        self.__LoadFileData("Worship", onlyCheck)
        self.__LoadFileData("Xiangong", onlyCheck)
        self.__LoadFileData("FairyDomain", onlyCheck)
        Log("IPY_DataMgr ReloadOK! onlyCheck=%s" % onlyCheck)
        return
@@ -3881,6 +3917,13 @@
        self.CheckLoadData("Worship")
        return self.ipyWorshipCache[index]
    def GetXiangongCount(self):
        self.CheckLoadData("Xiangong")
        return self.ipyXiangongLen
    def GetXiangongByIndex(self, index):
        self.CheckLoadData("Xiangong")
        return self.ipyXiangongCache[index]
    def GetFairyDomainCount(self):
        self.CheckLoadData("FairyDomain")
        return self.ipyFairyDomainLen
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -81,6 +81,7 @@
import GameWorldMineArea
import PlayerRecData
import GameWorship
import GameXiangong
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -666,6 +667,7 @@
    if not PlayerControl.GetIsTJG(curPlayer):
        playerID = curPlayer.GetPlayerID()
        PyGameData.g_unTJLogoffTime[playerID] = int(time.time())
        PyGameData.g_xiangongCanLikeTimeDict.pop(playerID, None)
        
        #在线状态变更,放最后
        __OnPlayerOnlineStateChange(curPlayer, False)
@@ -703,6 +705,15 @@
    
    isLogout = not isOnline
    PlayerViewCache.UpdCrossCacheBase(playerID, cacheBase, isLogout)
    serverID = GameWorld.GetAccIDServerID(cacheBase["AccID"])
    # 上线
    if isOnline:
        GameXiangong.OnPlayerLogin_CrossLogic(serverGroupID, serverID, playerID)
    # 下线
    else:
        pass
    
    SyncCrossPlayerOnlineStateToRelatedPlayer(playerID)
    return
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActBossTrial.py
@@ -27,6 +27,7 @@
import CrossBillboard
import PlayerFamily
import PyDataManager
import GameXiangong
def OnActStart(actNum):
    ## 活动开启
@@ -565,13 +566,14 @@
    
    PersonalTemplateID = ipyData.GetPersonalTemplateID()
    FamilyTemplateID = ipyData.GetFamilyTemplateID()
    serverIDRangeList = ipyData.GetServerIDRangeList()
    
    __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID, ShareDefine.Def_CBT_BossTrialSubmit)
    __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID, ShareDefine.Def_CBT_BossTrialSubmit, serverIDRangeList)
    __GiveCrossOrderAwardFamily(cfgID, zoneID, FamilyTemplateID, ShareDefine.Def_CBT_BossTrialSubmitFamily)
    GameWorld.Log("=================================================================================")
    return
    
def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID, billboardType):
def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID, billboardType, serverIDRangeList):
    
    groupValue1 = zoneID
    #billboardType = ShareDefine.Def_CBT_BossTrialSubmit #榜单类型改为参数传入,异常情况下可特殊处理用备份榜单发奖励
@@ -593,6 +595,7 @@
    if not orderIpyDataList:
        return
    
    syncNewXiangongDict = {}
    rankPre = 0
    billboardIndex = 0
    for ipyData in orderIpyDataList:
@@ -602,6 +605,7 @@
        scoreAwardExList = scoreAwardEx.keys()
        scoreAwardExList.sort()
        awardItemList = ipyData.GetAwardItemList()
        xiangongID = ipyData.GetXiangongID()
        orderCountTotal = rank - rankPre # 奖励名次数量
        rankPre = rank
        
@@ -632,6 +636,8 @@
            orderCountTotal -= 1
            billboardIndex += 1
            
            GameXiangong.AddXiangongPlayer(xiangongID, playerID, serverIDRangeList, playerRank, syncNewXiangongDict)
    GameXiangong.SendNewXiangongPlayerToClientServer(syncNewXiangongDict)
    return
def __GiveCrossOrderAwardFamily(cfgID, zoneID, templateID, billboardType):
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActGubao.py
@@ -26,6 +26,7 @@
import CrossBillboard
import PyDataManager
import CrossRealmMsg
import GameXiangong
import GameWorld
def OnActStart(actNum, ipyData):
@@ -316,12 +317,13 @@
    GameWorld.Log("=== 跨服古宝养成活动发放榜单奖励! === cfgID=%s,zoneID=%s" % (cfgID, zoneID))
    
    PersonalTemplateID = ipyData.GetPersonalTemplateID()
    serverIDRangeList = ipyData.GetServerIDRangeList()
    
    __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID, ShareDefine.Def_CBT_GubaoScore)
    __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID, ShareDefine.Def_CBT_GubaoScore, serverIDRangeList)
    GameWorld.Log("=================================================================================")
    return
    
def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID, billboardType):
def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID, billboardType, serverIDRangeList):
    
    groupValue1 = zoneID
    billboardMgr = PyDataManager.GetCrossBillboardManager()
@@ -342,6 +344,7 @@
    if not orderIpyDataList:
        return
    
    syncNewXiangongDict = {}
    rankPre = 0
    billboardIndex = 0
    for ipyData in orderIpyDataList:
@@ -351,6 +354,7 @@
        scoreAwardExList = scoreAwardEx.keys()
        scoreAwardExList.sort()
        awardItemList = ipyData.GetAwardItemList()
        xiangongID = ipyData.GetXiangongID()
        orderCountTotal = rank - rankPre # 奖励名次数量
        rankPre = rank
        
@@ -381,5 +385,7 @@
            orderCountTotal -= 1
            billboardIndex += 1
            
            GameXiangong.AddXiangongPlayer(xiangongID, playerID, serverIDRangeList, playerRank, syncNewXiangongDict)
    GameXiangong.SendNewXiangongPlayerToClientServer(syncNewXiangongDict)
    return
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActHorsePetTrain.py
@@ -25,6 +25,7 @@
import CrossBillboard
import PyDataManager
import CrossRealmMsg
import GameXiangong
import GameWorld
def OnActStart(actNum, ipyData):
@@ -315,12 +316,13 @@
    GameWorld.Log("=== 跨服骑宠养成活动发放榜单奖励! === cfgID=%s,zoneID=%s" % (cfgID, zoneID))
    
    PersonalTemplateID = ipyData.GetPersonalTemplateID()
    serverIDRangeList = ipyData.GetServerIDRangeList()
    
    __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID, ShareDefine.Def_CBT_HorsePetTrainScore)
    __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID, ShareDefine.Def_CBT_HorsePetTrainScore, serverIDRangeList)
    GameWorld.Log("=================================================================================")
    return
    
def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID, billboardType):
def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID, billboardType, serverIDRangeList):
    
    groupValue1 = zoneID
    billboardMgr = PyDataManager.GetCrossBillboardManager()
@@ -341,6 +343,7 @@
    if not orderIpyDataList:
        return
    
    syncNewXiangongDict = {}
    rankPre = 0
    billboardIndex = 0
    for ipyData in orderIpyDataList:
@@ -350,6 +353,7 @@
        scoreAwardExList = scoreAwardEx.keys()
        scoreAwardExList.sort()
        awardItemList = ipyData.GetAwardItemList()
        xiangongID = ipyData.GetXiangongID()
        orderCountTotal = rank - rankPre # 奖励名次数量
        rankPre = rank
        
@@ -379,6 +383,8 @@
            
            orderCountTotal -= 1
            billboardIndex += 1
            GameXiangong.AddXiangongPlayer(xiangongID, playerID, serverIDRangeList, playerRank, syncNewXiangongDict)
    GameXiangong.SendNewXiangongPlayerToClientServer(syncNewXiangongDict)
    return
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActXianXiaMJ.py
@@ -25,6 +25,7 @@
import CrossBillboard
import PyDataManager
import CrossRealmMsg
import GameXiangong
import GameWorld
def OnActStart(actNum, ipyData):
@@ -315,12 +316,13 @@
    GameWorld.Log("=== 跨服仙匣秘境活动发放榜单奖励! === cfgID=%s,zoneID=%s" % (cfgID, zoneID))
    
    PersonalTemplateID = ipyData.GetPersonalTemplateID()
    serverIDRangeList = ipyData.GetServerIDRangeList()
    
    __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID, ShareDefine.Def_CBT_XianXiaMJScore)
    __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID, ShareDefine.Def_CBT_XianXiaMJScore, serverIDRangeList)
    GameWorld.Log("=================================================================================")
    return
    
def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID, billboardType):
def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID, billboardType, serverIDRangeList):
    
    groupValue1 = zoneID
    billboardMgr = PyDataManager.GetCrossBillboardManager()
@@ -341,6 +343,7 @@
    if not orderIpyDataList:
        return
    
    syncNewXiangongDict = {}
    rankPre = 0
    billboardIndex = 0
    for ipyData in orderIpyDataList:
@@ -350,6 +353,7 @@
        scoreAwardExList = scoreAwardEx.keys()
        scoreAwardExList.sort()
        awardItemList = ipyData.GetAwardItemList()
        xiangongID = ipyData.GetXiangongID()
        orderCountTotal = rank - rankPre # 奖励名次数量
        rankPre = rank
        
@@ -380,5 +384,7 @@
            orderCountTotal -= 1
            billboardIndex += 1
            
            GameXiangong.AddXiangongPlayer(xiangongID, playerID, serverIDRangeList, playerRank, syncNewXiangongDict)
    GameXiangong.SendNewXiangongPlayerToClientServer(syncNewXiangongDict)
    return
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFuncTeam.py
@@ -70,7 +70,7 @@
    def GetSyncDict(self):
        # Value 暂时只同步1~2
        syncDict = {"PlayerID":self.GetPlayerID(), "Value1":self.GetValue1(), "Value2":self.GetValue2()}
        syncDict.update(PlayerViewCache.GetShotCahceDict(self.GetPlayerID(), False))
        syncDict.update(PlayerViewCache.GetShotCacheDict(self.GetPlayerID(), "PlayerID", "FightPower", "ServerID", "OfflineValue"))
        return syncDict
    
class PyFuncTeam():
@@ -127,7 +127,7 @@
        ApplyList = []
        if applyDetail:
            for applyID in ApplyIDList[::-1]:
                applyPlayerDict = PlayerViewCache.GetShotCahceDict(applyID, False)
                applyPlayerDict = PlayerViewCache.GetShotCacheDict(applyID, "PlayerID", "FightPower", "ServerID")
                if not applyPlayerDict:
                    ApplyIDList.remove(applyID)
                else:
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
@@ -20,6 +20,7 @@
import GameWorld
import GameWorship
import GameXiangong
import PlayerControl
import NetPackCommon
import GameWorldArena
@@ -67,6 +68,9 @@
        return True
    
    if PyDataManager.GetDBPyFuncTeamManager().IsTeamPlayer(playerID):
        return True
    if GameXiangong.IsXiangongPlayer(playerID):
        return True
    
    if GameWorldSkyTower.IsSkyTowerPassPlayer(playerID):
@@ -188,28 +192,33 @@
        curCache.PropDataDict = eval(curCache.PropData)
    return curCache.PropDataDict
def GetShotCahceDict(playerID, withEquip=False):
def GetShotCacheDict(playerID, *exAttrs):
    ## 获取玩家简短的缓存信息字典
    viewCache = FindViewCache(playerID)
    cacheDict = GetCachePropDataDict(viewCache)
    if not cacheDict:
        return {}
    olMgr = ChPlayer.GetOnlinePlayerMgr()
    shotCacheDict = {
                     "PlayerID":playerID,
                     "Name":cacheDict["Name"], 
                     "Job":cacheDict["Job"], 
                     "LV":cacheDict["LV"], 
                     "RealmLV":cacheDict["RealmLV"], 
                     "FightPower":cacheDict["FightPower"],
                     "ServerID":GameWorld.GetAccIDServerID(cacheDict["AccID"]),
                     "OfflineValue":olMgr.GetOfflineValue(playerID, viewCache)
                     }
    if withEquip:
    if "PlayerID" in exAttrs:
        shotCacheDict["PlayerID"] = playerID
    if "FightPower" in exAttrs:
        shotCacheDict["FightPower"] = cacheDict["FightPower"]
    if "ServerID" in exAttrs:
        shotCacheDict["ServerID"] = GameWorld.GetAccIDServerID(cacheDict["AccID"])
    if "OfflineValue" in exAttrs:
        olMgr = ChPlayer.GetOnlinePlayerMgr()
        shotCacheDict["OfflineValue"] = olMgr.GetOfflineValue(playerID, viewCache)
    # 附带外观模型展示相关
    if "Model" in exAttrs:
        shotCacheDict.update({
                              "TitleID":cacheDict.get("TitleID", 0),
                              "EquipShowSwitch":cacheDict.get("EquipShowSwitch", 0),
                              "EquipShowID":cacheDict.get("EquipShowID", 0),
                              "EquipShowID":cacheDict.get("EquipShowID", []),
                              })
    return shotCacheDict
@@ -229,7 +238,7 @@
                 "TitleID":cacheDict.get("TitleID", 0),
                 "FightPower":PlayerControl.GetFightPower(curPlayer),
                 "EquipShowSwitch":cacheDict.get("EquipShowSwitch", 0),
                 "EquipShowID":cacheDict.get("EquipShowID", 0),
                 "EquipShowID":cacheDict.get("EquipShowID", []),
                 "ServerGroupID":PlayerControl.GetPlayerServerGroupID(curPlayer),
                 }
    return cacheBase
ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
@@ -26,6 +26,7 @@
import CrossRealmPK
import AuctionHouse
import PlayerAssist
import GameRecData
import PlayerRecData
import GameWorldMineArea
import PyGameDataStruct
@@ -315,6 +316,7 @@
class PyGameDataManager(object):
    def __init__(self):
        self.DBGameRecDataManager = GameRecData.DBGameRecDataManager()
        self.DBPyFuncTeamManager = PlayerFuncTeam.DBPyFuncTeamManager()
        self.DBPyFuncTeamMemManager = PlayerFuncTeam.DBPyFuncTeamMemManager()
        self.DBPlayerRecDataManager = PlayerRecData.DBPlayerRecDataManager()
@@ -350,6 +352,7 @@
    def GetSaveData(self):
        buff = ""
        buff += self.DBGameRecDataManager.GetSaveData()
        buff += self.DBPyFuncTeamManager.GetSaveData()
        buff += self.DBPyFuncTeamMemManager.GetSaveData()
        buff += self.DBPlayerRecDataManager.GetSaveData()
@@ -384,6 +387,7 @@
        return buff
    
    def LoadGameData(self, gameBuffer, pos):
        pos = self.DBGameRecDataManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
        pos = self.DBPyFuncTeamManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
        pos = self.DBPyFuncTeamMemManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
        pos = self.DBPlayerRecDataManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
@@ -505,6 +509,11 @@
    pyGameDataMgr = GetPyGameDataManager()
    return pyGameDataMgr.familyStoreItemManager
def GetDBGameRecDataManager():
    # 通用记录表新管理
    pyGameDataMgr = GetPyGameDataManager()
    return pyGameDataMgr.DBGameRecDataManager
def GetDBPyFuncTeamManager():
    # 功能队伍管理
    pyGameDataMgr = GetPyGameDataManager()
ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
@@ -162,4 +162,6 @@
g_familyTalkCache = {} #{familyID:[[time,content,extras],..]}
g_worldTalkCache = [] #[[time,name, playerID, content,extras],..]
g_xiangongCanLikeTimeDict = {} # 本服玩家对应仙宫可点赞最新时间信息 {playerID:{仙宫ID:addTime, ...}, ...}
g_unTJLogoffTime = {} #非脱机离线时间 {playerID:time, ...}
ServerPython/CoreServerGroup/GameServer/Script/PyGameDataStruct.py
@@ -3395,4 +3395,134 @@
            self.TeamName = Str
        else:
            self.TeamName = Str[:33]
# 通用记录表新 #tagDBGameRec
class tagDBGameRec(Structure):
    _pack_ = 1
    _fields_ = [
        ('RecType', ctypes.c_ushort),
        ('RecID', ctypes.c_ulong),
        ('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.RecType = 0
        self.RecID = 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.RecType, pos = CommFunc.ReadWORD(buf, pos)
        self.RecID, pos = CommFunc.ReadDWORD(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.WriteWORD(buf, self.RecType)
        buf = CommFunc.WriteDWORD(buf, self.RecID)
        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_ushort)
        length += sizeof(ctypes.c_ulong)
        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 = '''// 通用记录表新 #tagDBGameRec:
            RecType = %s,
            RecID = %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.RecType,
                self.RecID,
                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
@@ -1146,7 +1146,8 @@
CDBPlayerRefresh_BossFinalHurtPer,  # Boss最终输出伤害百分比 264
CDBPlayerRefresh_HorsePetTrainScore, # 骑宠养成积分 265
CDBPlayerRefresh_GubaoTrainScore, # 古宝养成积分 266
) = range(146, 267)
CDBPlayerRefresh_TiandaoFruit, # 天道果 267
) = range(146, 268)
TYPE_Price_Gold_Paper_Money = 5    # 金钱类型,(先用礼券,再用金子)
TYPE_Price_Family_Contribution = 6 # 战盟贡献度(活跃度转换得来)
@@ -1181,6 +1182,7 @@
TYPE_Price_GatherSoul = 44    # 聚魂精华
TYPE_Price_HorsePetTrainScore = 45    # 骑宠养成积分
TYPE_Price_GubaoTrainScore = 46    # 古宝养成积分
TYPE_Price_TiandaoFruit = 47    # 天道果
TYPE_Price_PayCoin = 99    # 代币
#key可用于遍历所有货币,value仅GM相关会用到
@@ -1188,7 +1190,7 @@
                 1:"仙玉", 2:"绑玉", 3:"铜钱", 6:"战盟贡献度", 10:"战盟仓库积分", 13:"境界修行点", 14:"符印融合石", 15:"仙盟活跃令", 
                 16:"助战积分", 18:"荣誉", 19:"Boss积分", 23:"符印精华", 24:"符印碎片", 25:"寻宝积分", 26:"集市额度", 27:"丹精", 28:"魂尘", 
                 29:"聚魂碎片", 30:"核心环", 31:"功能特权令", 32:"环保值", 33:"GM令", 34:"古神币", 35:"功德点", 
                 39:"成就积分", 40:"万界积分", 43:"凭证积分", 44:"聚魂精华", 45:"骑宠养成积分", 46:"古宝养成积分", 99:"代币"
                 39:"成就积分", 40:"万界积分", 43:"凭证积分", 44:"聚魂精华", 45:"骑宠养成积分", 46:"古宝养成积分", 47:"天道果", 99:"代币"
                 }
#以下是旧的金钱类型
@@ -1224,6 +1226,7 @@
                           TYPE_Price_GatherSoul:CDBPlayerRefresh_GatherSoul,
                           TYPE_Price_HorsePetTrainScore:CDBPlayerRefresh_HorsePetTrainScore,
                           TYPE_Price_GubaoTrainScore:CDBPlayerRefresh_GubaoTrainScore,
                           TYPE_Price_TiandaoFruit:CDBPlayerRefresh_TiandaoFruit,
                           }
# 支持负值的货币及对应0418刷新类型
@@ -1364,6 +1367,15 @@
                         Def_PlayerRecType_WorshipDaily, # 玩家每日膜拜记录 2
                         Def_PlayerRecType_PayCoin, # 代币记录 3
                         ) = range(1, 1 + 3)
#通用信息记录类型 - 新 从 300 开始,原通用记录类型最大到255
Def_GameRecTypeList = (
                       Def_GameRecType_Xiangong, # 仙宫记录 300
                       ) = range(300, 1 + 300)
#通用信息记录新 - 字典key配置,如果有配置,则可额外按对应记录Value值存储字典,方便快速取值,可配置Value编号 1~8,配空默认 Value1
Def_GameRecValueKeyDict = {
                           Def_GameRecType_Xiangong:[1],
                           }
#通用信息记录类型
Def_UniversalGameRecTypeList = (
@@ -1611,6 +1623,7 @@
CrossServerMsg_FamilyFlagwarOver = "FamilyFlagwarOver"  # 逐鹿万界结算信息
CrossServerMsg_CrossBossTrialFamilyAward = "CrossBossTrialFamilyAward"  # 跨服boss历练仙盟奖励结算
CrossServerMsg_Worship = "Worship"  # 膜拜信息
CrossServerMsg_Xiangong = "Xiangong"  # 仙宫信息
CrossServerMsg_FuncTeamInfo = "FuncTeamInfo"  # 功能队伍信息同步
CrossServerMsg_FuncTeamDel = "FuncTeamDel"  # 功能队伍删除同步
CrossServerMsg_FuncTeamList = "FuncTeamList"  # 功能队伍列表同步
@@ -1659,6 +1672,7 @@
ClientServerMsg_QueryFuncTeam = "QueryFuncTeam"   # 查询功能队伍
ClientServerMsg_GubaoScore = "GubaoScore" # 古宝养成积分
ClientServerMsg_HorsePetTrainScore = "HorsePetTrainScore" # 骑宠养成积分
ClientServerMsg_QueryXiangong = "QueryXiangong" # 查看仙宫仙名录
#跨服广播类型定义
CrossNotify_CrossAct = "CrossAct"
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -524,6 +524,7 @@
Def_Effect_ItemCount = 267     #自动转化为对应物品ID的个数,不存背包
Def_Effect_GubaoPiece = 270     #古宝碎片效果ID, A值-古宝ID
Def_Effect_TrainRealmLV = 272     #境界培养卡,值A-功能(1-坐骑;2-灵宠;3-灵器), 值B-境界
Def_Effect_TiandaoQiyun = 273   #增加天道树气运;A值-增加值   效果值B: 领取是否默认直接使用
#----以下未使用或代码依然存在的---
Def_Effect_ItemGiveGongXun = 1920        #使用道具给予功勋
Def_Effect_ItemGiveRuneJH = 1925       #使用道具给予符印精华
@@ -4487,6 +4488,12 @@
Def_PDict_MineTreasureState = "MineTreasureState" # 聚宝盆激活状态,按类型位运算记录是否已激活
Def_PDict_MineTreasureAward = "MineTreasureAward" # 聚宝盆奖励状态,按类型位运算记录是否已领取
Def_PDict_MineTreasureProgess = "MineTreasureProgess_%s" # 聚宝盆进度值,参数(聚宝盆类型)
#仙宫
Def_PDict_XiangongLikeState = "XiangongLikeState_%s" # 指定仙宫今日是否已点赞,参数(仙宫ID),仙宫ID为0时代表每日的仙宫功能点赞
Def_PDict_TiandaoQiyun = "TiandaoQiyun" # 天道树当前气运
Def_PDict_TiandaoAward = "TiandaoAward_%s" # 天道树领奖记录,按奖励索引记录是否已领取,参数(key编号)
#-------------------------------------------------------------------------------
#可以从07 41封包购买的背包类型,和对应字典{背包类型:[字典key, 默认格子数]}
@@ -5979,7 +5986,8 @@
Def_RewardType_ActBuyCountGift, # 领取购买次数礼包活动 72
Def_RewardType_Guaji, # 领取挂机收益 73
Def_RewardType_FamilyCTGAssist, # 仙盟充值互助奖励 74
)= range(75)
Def_RewardType_TiandaoTree, # 仙宫天道树奖励 75
)= range(76)
#boss复活相关活动定义
BossRebornActIDList = (
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -1252,6 +1252,58 @@
#------------------------------------------------------
# A9 07 点赞仙宫 #tagCGLikeXiangong
class  tagCGLikeXiangong(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("XiangongID", c_ushort),    # 仙宫ID,为0时代表每日的仙宫点赞
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA9
        self.SubCmd = 0x07
        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 = 0xA9
        self.SubCmd = 0x07
        self.XiangongID = 0
        return
    def GetLength(self):
        return sizeof(tagCGLikeXiangong)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A9 07 点赞仙宫 //tagCGLikeXiangong:
                                Cmd:%s,
                                SubCmd:%s,
                                XiangongID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.XiangongID
                                )
        return DumpString
m_NAtagCGLikeXiangong=tagCGLikeXiangong()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGLikeXiangong.Cmd,m_NAtagCGLikeXiangong.SubCmd))] = m_NAtagCGLikeXiangong
#------------------------------------------------------
# A9 A5 查看竞技场对战玩家最新信息 #tagCGQueryArenaBattlePlayer
class  tagCGQueryArenaBattlePlayer(Structure):
@@ -1572,6 +1624,58 @@
#------------------------------------------------------
# A9 06 查看仙宫仙名录 #tagCGQueryXiangongRecPlayers
class  tagCGQueryXiangongRecPlayers(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("XiangongID", c_ushort),    # 仙宫ID
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA9
        self.SubCmd = 0x06
        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 = 0xA9
        self.SubCmd = 0x06
        self.XiangongID = 0
        return
    def GetLength(self):
        return sizeof(tagCGQueryXiangongRecPlayers)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A9 06 查看仙宫仙名录 //tagCGQueryXiangongRecPlayers:
                                Cmd:%s,
                                SubCmd:%s,
                                XiangongID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.XiangongID
                                )
        return DumpString
m_NAtagCGQueryXiangongRecPlayers=tagCGQueryXiangongRecPlayers()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryXiangongRecPlayers.Cmd,m_NAtagCGQueryXiangongRecPlayers.SubCmd))] = m_NAtagCGQueryXiangongRecPlayers
#------------------------------------------------------
#A9 A6 设置邮件(补偿)已读状态 #tagCGReadCompensation
class  tagCGReadCompensation(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -5736,6 +5736,356 @@
#------------------------------------------------------
# A9 27 仙宫新晋玩家信息 #tagGCXiangongNewPlayerInfo
class  tagGCXiangongNewPlayer(Structure):
    AddTime = 0    #(DWORD AddTime)// 新晋时间戳
    ServerID = 0    #(DWORD ServerID)
    PlayerID = 0    #(DWORD PlayerID)
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)// 玩家名,size = NameLen
    LV = 0    #(WORD LV)// 玩家等级
    Job = 0    #(BYTE Job)// 玩家职业
    RealmLV = 0    #(WORD RealmLV)// 玩家境界
    EquipShowSwitch = 0    #(DWORD EquipShowSwitch)
    EquipShowIDCount = 0    #(BYTE EquipShowIDCount)
    EquipShowID = list()    #(vector<DWORD> EquipShowID)
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.AddTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.EquipShowSwitch,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.EquipShowIDCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.EquipShowIDCount):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.EquipShowID.append(value)
        return _pos
    def Clear(self):
        self.AddTime = 0
        self.ServerID = 0
        self.PlayerID = 0
        self.NameLen = 0
        self.Name = ""
        self.LV = 0
        self.Job = 0
        self.RealmLV = 0
        self.EquipShowSwitch = 0
        self.EquipShowIDCount = 0
        self.EquipShowID = list()
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 4
        length += 4
        length += 1
        length += len(self.Name)
        length += 2
        length += 1
        length += 2
        length += 4
        length += 1
        length += 4 * self.EquipShowIDCount
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.AddTime)
        data = CommFunc.WriteDWORD(data, self.ServerID)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteBYTE(data, self.Job)
        data = CommFunc.WriteWORD(data, self.RealmLV)
        data = CommFunc.WriteDWORD(data, self.EquipShowSwitch)
        data = CommFunc.WriteBYTE(data, self.EquipShowIDCount)
        for i in range(self.EquipShowIDCount):
            data = CommFunc.WriteDWORD(data, self.EquipShowID[i])
        return data
    def OutputString(self):
        DumpString = '''
                                AddTime:%d,
                                ServerID:%d,
                                PlayerID:%d,
                                NameLen:%d,
                                Name:%s,
                                LV:%d,
                                Job:%d,
                                RealmLV:%d,
                                EquipShowSwitch:%d,
                                EquipShowIDCount:%d,
                                EquipShowID:%s
                                '''\
                                %(
                                self.AddTime,
                                self.ServerID,
                                self.PlayerID,
                                self.NameLen,
                                self.Name,
                                self.LV,
                                self.Job,
                                self.RealmLV,
                                self.EquipShowSwitch,
                                self.EquipShowIDCount,
                                "..."
                                )
        return DumpString
class  tagGCXiangongNewPlayerInfo(Structure):
    Head = tagHead()
    XiangongID = 0    #(WORD XiangongID)// 仙宫ID
    NewPlayerCount = 0    #(BYTE NewPlayerCount)
    NewPlayerList = list()    #(vector<tagGCXiangongNewPlayer> NewPlayerList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x27
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.XiangongID,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.NewPlayerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.NewPlayerCount):
            temNewPlayerList = tagGCXiangongNewPlayer()
            _pos = temNewPlayerList.ReadData(_lpData, _pos)
            self.NewPlayerList.append(temNewPlayerList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x27
        self.XiangongID = 0
        self.NewPlayerCount = 0
        self.NewPlayerList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 2
        length += 1
        for i in range(self.NewPlayerCount):
            length += self.NewPlayerList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteWORD(data, self.XiangongID)
        data = CommFunc.WriteBYTE(data, self.NewPlayerCount)
        for i in range(self.NewPlayerCount):
            data = CommFunc.WriteString(data, self.NewPlayerList[i].GetLength(), self.NewPlayerList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                XiangongID:%d,
                                NewPlayerCount:%d,
                                NewPlayerList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.XiangongID,
                                self.NewPlayerCount,
                                "..."
                                )
        return DumpString
m_NAtagGCXiangongNewPlayerInfo=tagGCXiangongNewPlayerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCXiangongNewPlayerInfo.Head.Cmd,m_NAtagGCXiangongNewPlayerInfo.Head.SubCmd))] = m_NAtagGCXiangongNewPlayerInfo
#------------------------------------------------------
# A9 28 仙宫仙名录玩家信息 #tagGCXiangongRecPlayerInfo
class  tagGCXiangongRecPlayer(Structure):
    AddTime = 0    #(DWORD AddTime)// 新晋时间戳
    ServerID = 0    #(DWORD ServerID)
    PlayerID = 0    #(DWORD PlayerID)
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)// 玩家名,size = NameLen
    LV = 0    #(WORD LV)// 玩家等级
    Job = 0    #(BYTE Job)// 玩家职业
    RealmLV = 0    #(WORD RealmLV)// 玩家境界
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.AddTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.AddTime = 0
        self.ServerID = 0
        self.PlayerID = 0
        self.NameLen = 0
        self.Name = ""
        self.LV = 0
        self.Job = 0
        self.RealmLV = 0
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 4
        length += 4
        length += 1
        length += len(self.Name)
        length += 2
        length += 1
        length += 2
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.AddTime)
        data = CommFunc.WriteDWORD(data, self.ServerID)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteBYTE(data, self.Job)
        data = CommFunc.WriteWORD(data, self.RealmLV)
        return data
    def OutputString(self):
        DumpString = '''
                                AddTime:%d,
                                ServerID:%d,
                                PlayerID:%d,
                                NameLen:%d,
                                Name:%s,
                                LV:%d,
                                Job:%d,
                                RealmLV:%d
                                '''\
                                %(
                                self.AddTime,
                                self.ServerID,
                                self.PlayerID,
                                self.NameLen,
                                self.Name,
                                self.LV,
                                self.Job,
                                self.RealmLV
                                )
        return DumpString
class  tagGCXiangongRecPlayerInfo(Structure):
    Head = tagHead()
    XiangongID = 0    #(WORD XiangongID)// 仙宫ID
    RecPlayerCount = 0    #(BYTE RecPlayerCount)
    RecPlayerList = list()    #(vector<tagGCXiangongRecPlayer> RecPlayerList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x28
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.XiangongID,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.RecPlayerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.RecPlayerCount):
            temRecPlayerList = tagGCXiangongRecPlayer()
            _pos = temRecPlayerList.ReadData(_lpData, _pos)
            self.RecPlayerList.append(temRecPlayerList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x28
        self.XiangongID = 0
        self.RecPlayerCount = 0
        self.RecPlayerList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 2
        length += 1
        for i in range(self.RecPlayerCount):
            length += self.RecPlayerList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteWORD(data, self.XiangongID)
        data = CommFunc.WriteBYTE(data, self.RecPlayerCount)
        for i in range(self.RecPlayerCount):
            data = CommFunc.WriteString(data, self.RecPlayerList[i].GetLength(), self.RecPlayerList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                XiangongID:%d,
                                RecPlayerCount:%d,
                                RecPlayerList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.XiangongID,
                                self.RecPlayerCount,
                                "..."
                                )
        return DumpString
m_NAtagGCXiangongRecPlayerInfo=tagGCXiangongRecPlayerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCXiangongRecPlayerInfo.Head.Cmd,m_NAtagGCXiangongRecPlayerInfo.Head.SubCmd))] = m_NAtagGCXiangongRecPlayerInfo
#------------------------------------------------------
# AC 10 仙盟抢Boss所有Boss伤血进度信息 #tagGCAllFamilyBossHurtInfoList
class  tagGCFamilyBossHurtInfo(Structure):
@@ -50177,6 +50527,80 @@
#------------------------------------------------------
# B1 15 天道树信息 #tagMCTiandaoTreeInfo
class  tagMCTiandaoTreeInfo(Structure):
    Head = tagHead()
    Qiyun = 0    #(DWORD Qiyun)// 当前气运值
    AwardCount = 0    #(BYTE AwardCount)// 天道果领取记录值个数
    AwardStateList = list()    #(vector<DWORD> AwardStateList)// 天道果领取记录值列表,按奖励索引位二进制记录是否已领取,一个值可存31位,如值1存0~30,值2存31~61,...
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x15
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Qiyun,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.AwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.AwardCount):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.AwardStateList.append(value)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x15
        self.Qiyun = 0
        self.AwardCount = 0
        self.AwardStateList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 4
        length += 1
        length += 4 * self.AwardCount
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteDWORD(data, self.Qiyun)
        data = CommFunc.WriteBYTE(data, self.AwardCount)
        for i in range(self.AwardCount):
            data = CommFunc.WriteDWORD(data, self.AwardStateList[i])
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Qiyun:%d,
                                AwardCount:%d,
                                AwardStateList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Qiyun,
                                self.AwardCount,
                                "..."
                                )
        return DumpString
m_NAtagMCTiandaoTreeInfo=tagMCTiandaoTreeInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTiandaoTreeInfo.Head.Cmd,m_NAtagMCTiandaoTreeInfo.Head.SubCmd))] = m_NAtagMCTiandaoTreeInfo
#------------------------------------------------------
# B1 12 培养功能境界信息 #tagMCTrainRealmLVInfo
class  tagMCTrainRealmLV(Structure):
@@ -50285,6 +50709,121 @@
#------------------------------------------------------
# B1 14 仙宫信息 #tagMCXiangongInfo
class  tagMCXiangong(Structure):
    _pack_ = 1
    _fields_ = [
                  ("XiangongID", c_ushort),    # 仙宫ID
                  ("LikeStateToday", c_ubyte),    # 今日是否已点赞
                  ]
    def __init__(self):
        self.Clear()
        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.XiangongID = 0
        self.LikeStateToday = 0
        return
    def GetLength(self):
        return sizeof(tagMCXiangong)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B1 14 仙宫信息 //tagMCXiangongInfo:
                                XiangongID:%d,
                                LikeStateToday:%d
                                '''\
                                %(
                                self.XiangongID,
                                self.LikeStateToday
                                )
        return DumpString
class  tagMCXiangongInfo(Structure):
    Head = tagHead()
    LikeStateToday = 0    #(BYTE LikeStateToday)// 今日是否已点赞,指仙宫的外层点赞,非某个指定仙宫
    XiangongCount = 0    #(BYTE XiangongCount)
    XiangongList = list()    #(vector<tagMCXiangong> XiangongList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x14
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.LikeStateToday,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.XiangongCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.XiangongCount):
            temXiangongList = tagMCXiangong()
            _pos = temXiangongList.ReadData(_lpData, _pos)
            self.XiangongList.append(temXiangongList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x14
        self.LikeStateToday = 0
        self.XiangongCount = 0
        self.XiangongList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        for i in range(self.XiangongCount):
            length += self.XiangongList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.LikeStateToday)
        data = CommFunc.WriteBYTE(data, self.XiangongCount)
        for i in range(self.XiangongCount):
            data = CommFunc.WriteString(data, self.XiangongList[i].GetLength(), self.XiangongList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                LikeStateToday:%d,
                                XiangongCount:%d,
                                XiangongList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.LikeStateToday,
                                self.XiangongCount,
                                "..."
                                )
        return DumpString
m_NAtagMCXiangongInfo=tagMCXiangongInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCXiangongInfo.Head.Cmd,m_NAtagMCXiangongInfo.Head.SubCmd))] = m_NAtagMCXiangongInfo
#------------------------------------------------------
# B1 20 战令信息 #tagMCZhanlingInfo
class  tagMCZhanling(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Xiangong.py
New file
@@ -0,0 +1,71 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.Xiangong
#
# @todo:仙宫
# @author hxp
# @date 2024-09-04
# @version 1.0
#
# 详细描述: 仙宫
#
#-------------------------------------------------------------------------------
#"""Version = 2024-09-04 16:30"""
#-------------------------------------------------------------------------------
import GameWorld
import PlayerControl
import IpyGameDataPY
import PlayerXiangong
import ChConfig
#-------------------------------------------------------------------------------
#逻辑实现
## GM命令执行入口
#  @param curPlayer 当前玩家
#  @param list 参数列表 [npcID]
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, msgList):
    if not msgList:
        GameWorld.DebugAnswer(curPlayer, "---------- %s" % GameWorld.GetCurrentDataTimeStr())
        GameWorld.DebugAnswer(curPlayer, "重置仙宫点赞: Xiangong 0 like")
        GameWorld.DebugAnswer(curPlayer, "重置气运奖励: Xiangong 0 tree")
        GameWorld.DebugAnswer(curPlayer, "设置当前气运: Xiangong q 气运值")
        return True
    if msgList[0] == 0:
        if len(msgList) == 1 or msgList[1] == "like":
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_XiangongLikeState % 0, 0)
            xiangongIDList = []
            ipyMgr = IpyGameDataPY.IPY_Data()
            for index in range(ipyMgr.GetXiangongCount()):
                ipyData = ipyMgr.GetXiangongByIndex(index)
                xiangongID = ipyData.GetXiangongID()
                if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_XiangongLikeState % xiangongID):
                    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_XiangongLikeState % xiangongID, 0)
                    xiangongIDList.append(xiangongID)
            PlayerXiangong.SyncXiangongInfo(curPlayer, xiangongIDList)
            GameWorld.DebugAnswer(curPlayer, "重置仙宫点赞:%s" % xiangongIDList)
        if len(msgList) == 1 or msgList[1] == "tree":
            for keyNum in range(50):
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TiandaoAward % keyNum, 0)
            PlayerXiangong.SyncTiandaoTreeInfo(curPlayer)
            GameWorld.DebugAnswer(curPlayer, "重置气运奖励:%s" % xiangongIDList)
        return
    if msgList[0] == "q":
        setQiyun = msgList[1] if len(msgList) > 1 else 0
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TiandaoQiyun, setQiyun)
        PlayerXiangong.SyncTiandaoTreeInfo(curPlayer)
        GameWorld.DebugAnswer(curPlayer, "设置当前气运:%s" % setQiyun)
        return
    return True
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -2435,6 +2435,16 @@
                        ("list", "ZLRewardItemList", 0),
                        ("list", "ZLRewardItemListH", 0),
                        ),
                "Xiangong":(
                        ("WORD", "XiangongID", 1),
                        ),
                "TiandaoTree":(
                        ("WORD", "AwardIndex", 1),
                        ("DWORD", "NeedQiyun", 0),
                        ("list", "AwardItemList", 0),
                        ),
                }
@@ -6080,6 +6090,26 @@
    def GetFreeRewardItemList(self): return self.attrTuple[3] # 免费奖励物品列表 [[物品ID,个数,是否拍品],...] list
    def GetZLRewardItemList(self): return self.attrTuple[4] # 战令奖励物品列表 [[物品ID,个数,是否拍品],...] list
    def GetZLRewardItemListH(self): return self.attrTuple[5] # 高级战令奖励物品列表 [[物品ID,个数,是否拍品],...] list
# 仙宫表
class IPY_Xiangong():
    def __init__(self):
        self.attrTuple = None
        return
    def GetXiangongID(self): return self.attrTuple[0] # 仙宫ID WORD
# 仙宫天道树
class IPY_TiandaoTree():
    def __init__(self):
        self.attrTuple = None
        return
    def GetAwardIndex(self): return self.attrTuple[0] # 奖励索引 WORD
    def GetNeedQiyun(self): return self.attrTuple[1] # 所需气运值 DWORD
    def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品列表 list
def Log(msg, playerID=0, par=0):
@@ -6384,6 +6414,8 @@
        self.__LoadFileData("HistoryRechargeAward", onlyCheck)
        self.__LoadFileData("CustomAward", onlyCheck)
        self.__LoadFileData("Zhanling", onlyCheck)
        self.__LoadFileData("Xiangong", onlyCheck)
        self.__LoadFileData("TiandaoTree", onlyCheck)
        Log("IPY_DataMgr ReloadOK! onlyCheck=%s" % onlyCheck)
        return
    
@@ -8324,6 +8356,20 @@
    def GetZhanlingByIndex(self, index):
        self.CheckLoadData("Zhanling")
        return self.ipyZhanlingCache[index]
    def GetXiangongCount(self):
        self.CheckLoadData("Xiangong")
        return self.ipyXiangongLen
    def GetXiangongByIndex(self, index):
        self.CheckLoadData("Xiangong")
        return self.ipyXiangongCache[index]
    def GetTiandaoTreeCount(self):
        self.CheckLoadData("TiandaoTree")
        return self.ipyTiandaoTreeLen
    def GetTiandaoTreeByIndex(self, index):
        self.CheckLoadData("TiandaoTree")
        return self.ipyTiandaoTreeCache[index]
IPYData = IPY_DataMgr()
def IPY_Data(): return IPYData
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
@@ -726,6 +726,7 @@
                            ChConfig.Def_Effect_PrizeCoin:"Item_PrizeCoin", # 奖励充值点券
                            ChConfig.Def_Effect_AddVIPExp:"Item_AddVIPExp", # 增加VIP经验
                            ChConfig.Def_Effect_VIPLVCard:"Item_VIPLVCard", # VIP等级直升卡
                            ChConfig.Def_Effect_TiandaoQiyun:"Item_TiandaoQiyun", # 天道树气运
                            ChConfig.Def_Effect_GubaoPiece:"Item_GubaoPiece", # 古宝碎片效果ID
                            ChConfig.Def_Effect_TrainRealmLV:"Item_TrainRealmLV", # 境界培养卡
                            ChConfig.Def_Effect_ResetBossKillCnt:"Item_ResetBossKillCnt", # 重置boss击杀疲劳
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
@@ -34,6 +34,7 @@
import PlayerFairyCeremony
import PlayerActBossTrial
import PlayerMagicWeapon
import PlayerXiangong
import IpyGameDataPY
import DataRecordPack
import PlayerGubao
@@ -1138,6 +1139,14 @@
                PlayerGubao.AddGubaoPiece(curPlayer, gubaoID, tagItemCount, itemID)
                tagItem.Clear()
                return True
        #气运
        if itemEff.GetEffectID() == ChConfig.Def_Effect_TiandaoQiyun:
            isAutoUse = itemEff.GetEffectValue(1)
            if isAutoUse:
                addQiyun = itemEff.GetEffectValue(0) * tagItemCount
                PlayerXiangong.AddTiandaoQiyun(curPlayer, addQiyun, {"ItemID":itemID, "ItemCount":tagItemCount, "isAutoUse":1})
                tagItem.Clear()
                return True
        #直升VIP
        if itemEff.GetEffectID() == ChConfig.Def_Effect_VIPLVCard:
            isAutoUse = itemEff.GetEffectValue(1)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_TiandaoQiyun.py
New file
@@ -0,0 +1,34 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package UseItem.Item_TiandaoQiyun
#
# @todo:天道气运
# @author hxp
# @date 2024-09-04
# @version 1.0
#
# 详细描述: 天道气运
#
#-------------------------------------------------------------------------------
#"""Version = 2024-09-04 16:30"""
#-------------------------------------------------------------------------------
import ItemCommon
import PlayerXiangong
def BatchUseItem(curPlayer, curRoleItem, tick, useCnt, exData):
    ##批量使用物品
    curEff = curRoleItem.GetEffectByIndex(0)
    addValue = curEff.GetEffectValue(0) * useCnt
    PlayerXiangong.AddTiandaoQiyun(curPlayer, addValue, {"ItemID":curRoleItem.GetItemTypeID(), "ItemCount":useCnt})
    succCnt = useCnt # 默认值使用1个
    ItemCommon.DelItem(curPlayer, curRoleItem, succCnt)
    return True, succCnt
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -161,6 +161,7 @@
import GameObj
import PlayerChangeJob
import PlayerGuaji
import PlayerXiangong
import PlayerMineArea
import PlayerActLoginNew
import PlayerActBuyCountGift
@@ -988,6 +989,7 @@
        pass
    
    else:
        PlayerXiangong.OnPlayerLogin(curPlayer)
        PlayerGubao.OnPlayerLogin(curPlayer)
        PlayerShentong.OnPlayerLogin(curPlayer)
        PlayerZhanling.OnPlayerLogin(curPlayer)
@@ -5728,6 +5730,9 @@
    # 仙盟充值互助活动奖励
    elif rewardType == ChConfig.Def_RewardType_FamilyCTGAssist:
        PlayerActFamilyCTGAssist.GetFamilyCTGAssistAward(curPlayer, dataEx, dataExStr)
    # 天道树奖励
    elif rewardType == ChConfig.Def_RewardType_TiandaoTree:
        PlayerXiangong.GetTiandaoTreeAward(curPlayer, dataEx)
    #缥缈奇遇领取
    elif rewardType == ChConfig.Def_RewardType_FairyAdventuresAward:
        PlayerFairyDomain.GetFairyAdventuresAward(curPlayer, dataEx, dataExStr)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -134,6 +134,7 @@
import PyGameData
import PlayerTJG
import PlayerGuaji
import PlayerXiangong
import PlayerFuncTeam
import PlayerMineArea
@@ -561,6 +562,8 @@
        PlayerActTurntable.PlayerOnDay(curPlayer)
        #情缘
        PlayerLove.DoPlayerOnDay(curPlayer)
        #仙宫
        PlayerXiangong.PlayerOnDay(curPlayer)
        #玩法前瞻奖励
        gameNoticeAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GameNoticeAwardState)
        if gameNoticeAwardState:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerXiangong.py
New file
@@ -0,0 +1,169 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.PlayerXiangong
#
# @todo:仙宫
# @author hxp
# @date 2024-09-04
# @version 1.0
#
# 详细描述: 仙宫
#
#-------------------------------------------------------------------------------
#"""Version = 2024-09-04 16:30"""
#-------------------------------------------------------------------------------
import ChConfig
import IpyGameDataPY
import PlayerControl
import ChPyNetSendPack
import DataRecordPack
import NetPackCommon
import ItemControler
import GameWorld
def OnPlayerLogin(curPlayer):
    SyncXiangongInfo(curPlayer)
    SyncTiandaoTreeInfo(curPlayer, True)
    return
def PlayerOnDay(curPlayer):
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_XiangongLikeState % 0, 0)
    xiangongIDList = []
    ipyMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyMgr.GetXiangongCount()):
        ipyData = ipyMgr.GetXiangongByIndex(index)
        xiangongID = ipyData.GetXiangongID()
        if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_XiangongLikeState % xiangongID):
            continue
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_XiangongLikeState % xiangongID, 0)
        xiangongIDList.append(xiangongID)
    if xiangongIDList:
        SyncXiangongInfo(curPlayer, xiangongIDList)
    return
def AddTiandaoQiyun(curPlayer, addValue, addDict={}):
    curQiyun = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TiandaoQiyun)
    updQiyun = min(curQiyun + addValue, ChConfig.Def_UpperLimit_DWord)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TiandaoQiyun, updQiyun)
    dataDict = {'PlayerID':curPlayer.GetPlayerID(), "PlayerName":curPlayer.GetPlayerName(),
                'AccID':curPlayer.GetAccID(), "updQiyun":updQiyun, "addValue":addValue}
    dataDict.update(addDict)
    DataRecordPack.SendEventPack("AddTiandaoQiyun", dataDict, curPlayer)
    SyncTiandaoTreeInfo(curPlayer)
    return updQiyun
def GameServer_Xiangong_DoResult(curPlayer, msgData):
    msgType = msgData[0]
    dataMsg = msgData[1]
    ## 点赞仙宫
    if msgType == "LikeXiangong":
        __DoLikeXiangong(curPlayer, dataMsg)
    return
def __DoLikeXiangong(curPlayer, dataMsg):
    xiangongID, moneyType, moneyValue = dataMsg
    playerID = curPlayer.GetPlayerID()
    likeState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_XiangongLikeState % xiangongID)
    if likeState:
        GameWorld.DebugLog("该仙宫已点赞! xiangongID=%s" % xiangongID, playerID)
        return
    GameWorld.DebugLog("仙宫点赞! xiangongID=%s,moneyType=%s,moneyValue=%s" % (xiangongID, moneyType, moneyValue), playerID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_XiangongLikeState % xiangongID, 1)
    SyncXiangongInfo(curPlayer, [xiangongID])
    PlayerControl.GiveMoney(curPlayer, moneyType, moneyValue, "LikeXiangong", {"xiangongID":xiangongID})
    return
def GetTiandaoTreeAward(curPlayer, awardIndex):
    ## 领取天道树奖励
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("TiandaoTree", awardIndex)
    if not ipyData:
        return
    if GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_TiandaoAward, awardIndex):
        GameWorld.DebugLog("该天道树奖励已领奖! awardIndex=%s" % awardIndex, playerID)
        return
    needQiyun = ipyData.GetNeedQiyun()
    awardItemList = ipyData.GetAwardItemList()
    qiyun = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TiandaoQiyun)
    if qiyun < needQiyun:
        GameWorld.DebugLog("当前天道树气运不足,无法领奖! awardIndex=%s,qiyun=%s < %s" % (awardIndex, qiyun, needQiyun), playerID)
        return
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_TiandaoAward, awardIndex, 1)
    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList)
    SyncTiandaoTreeInfo(curPlayer)
    return
def SyncXiangongInfo(curPlayer, xiangongIDList=None):
    syncXiangongIDList = []
    if xiangongIDList == None:
        ipyMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyMgr.GetXiangongCount()):
            ipyData = ipyMgr.GetXiangongByIndex(index)
            syncXiangongIDList.append(ipyData.GetXiangongID())
    else:
        syncXiangongIDList = xiangongIDList
    xiangongList = []
    for xiangongID in syncXiangongIDList:
        if not xiangongID:
            continue
        likeState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_XiangongLikeState % xiangongID)
        if not likeState and xiangongIDList == None:
            continue
        xg = ChPyNetSendPack.tagMCXiangong()
        xg.XiangongID = xiangongID
        xg.LikeStateToday = likeState
        xiangongList.append(xg)
    likeStateToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_XiangongLikeState % 0)
    if xiangongIDList == None and not xiangongList and not likeStateToday:
        return
    clientPack = ChPyNetSendPack.tagMCXiangongInfo()
    clientPack.LikeStateToday = likeStateToday
    clientPack.XiangongList = xiangongList
    clientPack.XiangongCount = len(clientPack.XiangongList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def SyncTiandaoTreeInfo(curPlayer, isLogin=False):
    ipyMgr = IpyGameDataPY.IPY_Data()
    treeCount = ipyMgr.GetTiandaoTreeCount()
    if not treeCount:
        return
    lastIpyData = ipyMgr.GetTiandaoTreeByIndex(treeCount - 1)
    if not lastIpyData:
        return
    keyNumMax = lastIpyData.GetAwardIndex() / 31 + 1
    awardStateList = []
    for keyNum in range(keyNumMax):
        awardStateList.append(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TiandaoAward % keyNum))
    qiyun = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TiandaoQiyun)
    if isLogin and not qiyun and awardStateList.count(0) == len(awardStateList):
        return
    clientPack = ChPyNetSendPack.tagMCTiandaoTreeInfo()
    clientPack.Qiyun = qiyun
    clientPack.AwardStateList = awardStateList
    clientPack.AwardCount = len(clientPack.AwardStateList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_Xiangong.py
New file
@@ -0,0 +1,48 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.RemoteQuery.GY_Query_Xiangong
#
# @todo:仙宫
# @author hxp
# @date 2024-09-04
# @version 1.0
#
# 详细描述: 仙宫
#
#-------------------------------------------------------------------------------
#"""Version = 2024-09-04 16:30"""
#-------------------------------------------------------------------------------
import GameWorld
import PlayerXiangong
#------------------------------------------------------------------------------
## 跨服赛报名调用接口
#  @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.DebugLog("GY_Query_Xiangong DoResult %s" % str(funResult), curPlayer.GetPlayerID())
    if funResult != "":
        PlayerXiangong.GameServer_Xiangong_DoResult(curPlayer, eval(funResult))
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1146,7 +1146,8 @@
CDBPlayerRefresh_BossFinalHurtPer,  # Boss最终输出伤害百分比 264
CDBPlayerRefresh_HorsePetTrainScore, # 骑宠养成积分 265
CDBPlayerRefresh_GubaoTrainScore, # 古宝养成积分 266
) = range(146, 267)
CDBPlayerRefresh_TiandaoFruit, # 天道果 267
) = range(146, 268)
TYPE_Price_Gold_Paper_Money = 5    # 金钱类型,(先用礼券,再用金子)
TYPE_Price_Family_Contribution = 6 # 战盟贡献度(活跃度转换得来)
@@ -1181,6 +1182,7 @@
TYPE_Price_GatherSoul = 44    # 聚魂精华
TYPE_Price_HorsePetTrainScore = 45    # 骑宠养成积分
TYPE_Price_GubaoTrainScore = 46    # 古宝养成积分
TYPE_Price_TiandaoFruit = 47    # 天道果
TYPE_Price_PayCoin = 99    # 代币
#key可用于遍历所有货币,value仅GM相关会用到
@@ -1188,7 +1190,7 @@
                 1:"仙玉", 2:"绑玉", 3:"铜钱", 6:"战盟贡献度", 10:"战盟仓库积分", 13:"境界修行点", 14:"符印融合石", 15:"仙盟活跃令", 
                 16:"助战积分", 18:"荣誉", 19:"Boss积分", 23:"符印精华", 24:"符印碎片", 25:"寻宝积分", 26:"集市额度", 27:"丹精", 28:"魂尘", 
                 29:"聚魂碎片", 30:"核心环", 31:"功能特权令", 32:"环保值", 33:"GM令", 34:"古神币", 35:"功德点", 
                 39:"成就积分", 40:"万界积分", 43:"凭证积分", 44:"聚魂精华", 45:"骑宠养成积分", 46:"古宝养成积分", 99:"代币"
                 39:"成就积分", 40:"万界积分", 43:"凭证积分", 44:"聚魂精华", 45:"骑宠养成积分", 46:"古宝养成积分", 47:"天道果", 99:"代币"
                 }
#以下是旧的金钱类型
@@ -1224,6 +1226,7 @@
                           TYPE_Price_GatherSoul:CDBPlayerRefresh_GatherSoul,
                           TYPE_Price_HorsePetTrainScore:CDBPlayerRefresh_HorsePetTrainScore,
                           TYPE_Price_GubaoTrainScore:CDBPlayerRefresh_GubaoTrainScore,
                           TYPE_Price_TiandaoFruit:CDBPlayerRefresh_TiandaoFruit,
                           }
# 支持负值的货币及对应0418刷新类型
@@ -1364,6 +1367,15 @@
                         Def_PlayerRecType_WorshipDaily, # 玩家每日膜拜记录 2
                         Def_PlayerRecType_PayCoin, # 代币记录 3
                         ) = range(1, 1 + 3)
#通用信息记录类型 - 新 从 300 开始,原通用记录类型最大到255
Def_GameRecTypeList = (
                       Def_GameRecType_Xiangong, # 仙宫记录 300
                       ) = range(300, 1 + 300)
#通用信息记录新 - 字典key配置,如果有配置,则可额外按对应记录Value值存储字典,方便快速取值,可配置Value编号 1~8,配空默认 Value1
Def_GameRecValueKeyDict = {
                           Def_GameRecType_Xiangong:[1],
                           }
#通用信息记录类型
Def_UniversalGameRecTypeList = (
@@ -1611,6 +1623,7 @@
CrossServerMsg_FamilyFlagwarOver = "FamilyFlagwarOver"  # 逐鹿万界结算信息
CrossServerMsg_CrossBossTrialFamilyAward = "CrossBossTrialFamilyAward"  # 跨服boss历练仙盟奖励结算
CrossServerMsg_Worship = "Worship"  # 膜拜信息
CrossServerMsg_Xiangong = "Xiangong"  # 仙宫信息
CrossServerMsg_FuncTeamInfo = "FuncTeamInfo"  # 功能队伍信息同步
CrossServerMsg_FuncTeamDel = "FuncTeamDel"  # 功能队伍删除同步
CrossServerMsg_FuncTeamList = "FuncTeamList"  # 功能队伍列表同步
@@ -1659,6 +1672,7 @@
ClientServerMsg_QueryFuncTeam = "QueryFuncTeam"   # 查询功能队伍
ClientServerMsg_GubaoScore = "GubaoScore" # 古宝养成积分
ClientServerMsg_HorsePetTrainScore = "HorsePetTrainScore" # 骑宠养成积分
ClientServerMsg_QueryXiangong = "QueryXiangong" # 查看仙宫仙名录
#跨服广播类型定义
CrossNotify_CrossAct = "CrossAct"