263 【主界面】头像系统(内政-幻境阁系统)-服务端(形象、头像、头像框、气泡、称号)
20个文件已修改
9个文件已删除
3个文件已添加
4528 ■■■■■ 已修改文件
PySysDB/PySysDBPY.h 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script.ini 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 424 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 572 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/AddTitle.py 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ChatBox.py 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearTitle.py 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Face.py 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/HJG.py 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 299 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_AddDienstgrad.py 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_ChatBubbleBox.py 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_Face.py 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerChatBox.py 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerDienstgrad.py 687 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFace.py 488 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHJG.py 684 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTalk.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_AddDienstgrad.py 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTAddTitle.py 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTFace.py 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_Face.py 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h
@@ -343,75 +343,84 @@
    BYTE        SkillExCnt;    //随机附加技能数,0为所有
};
//称号表 #tagDienstgrad
//称号表
struct    tagDienstgrad
struct    Title
{
    DWORD        _ID;    //头衔id
    WORD        Type;    //头衔类型
    DWORD        ExpireTime;    //有效时间
    list        LightType;    //点亮属性类型
    list        LightAttribute;    //点亮属性值
    list        Skills;        //被动技能
    DWORD        InitFightPower;    //初始战力
    DWORD        _TitleID;    //称号ID
    DWORD        ExpireMinutes;    //时效分钟,0永久
    BYTE        UnlockWay;    //解锁方式
    DWORD        UnlockValue;    //解锁方式值
    BYTE        UnlockNeedCnt;    //解锁所需个数
    BYTE        UpNeedCnt;    //升级所需个数
    BYTE        StarMax;    //最高星级
    list        AttrIDList;    //属性ID列表
    list        InitAttrValueList;    //初始属性值列表
    list        AttrPerStarAddList;    //每星加成值列表
};
//称号升星表
//形象表
struct tagTitleStarUp
struct    Model
{
    DWORD        _TitleID;    //称号NPCID
    BYTE        _TitleStar;    //称号星级
    list        StarUpNeedItemList;    //升下一星所需道具 [[物品ID,个数], ...]
    list        StarAttrType;    //累计总属性类型
    list        StarAttrValue;    //累计总属性值
    DWORD        _ModelID;    //形象ID
    DWORD        ExpireMinutes;    //时效分钟,0永久
    BYTE        UnlockWay;    //解锁方式
    DWORD        UnlockValue;    //解锁方式值
    BYTE        UnlockNeedCnt;    //解锁所需个数
    BYTE        UpNeedCnt;    //升级所需个数
    BYTE        StarMax;    //最高星级
    list        AttrIDList;    //属性ID列表
    list        InitAttrValueList;    //初始属性值列表
    list        AttrPerStarAddList;    //每星加成值列表
};
//头像表
struct    tagPlayerFace
struct    PlayerFace
{
    DWORD        _FaceID;    //头像ID
    BYTE        UnlockDefault;    //是否默认激活
    DWORD        ExpireMinutes;    //时效分钟,0永久
    DWORD        CustomPlayerID;    //定制玩家ID
    list        LightAttrType;    //点亮属性类型
    list        LightAttrValue;    //点亮属性值
    DWORD        LightFightPower;    //点亮附加战力
};
//头像升星表
struct tagPlayerFaceStar
{
    DWORD        _FaceID;    //头像ID
    BYTE        _FaceStar;    //头像星级
    list        StarUpNeedItemList;    //升该星所需物品 [[物品ID,个数], ...]
    list        StarAttrType;    //累计总属性类型
    list        StarAttrValue;    //累计总属性值
    BYTE        UnlockWay;    //解锁方式
    DWORD        UnlockValue;    //解锁方式值
    BYTE        UnlockNeedCnt;    //解锁所需个数
    BYTE        UpNeedCnt;    //升级所需个数
    BYTE        StarMax;    //最高星级
    list        AttrIDList;    //属性ID列表
    list        InitAttrValueList;    //初始属性值列表
    list        AttrPerStarAddList;    //每星加成值列表
};
//头像框表
struct    tagPlayerFacePic
struct    PlayerFacePic
{
    DWORD        _FacePicID;    //头像框ID
    BYTE        UnlockDefault;    //是否默认激活
    DWORD        ExpireMinutes;    //时效分钟,0永久
    list        LightAttrType;    //点亮属性类型
    list        LightAttrValue;    //点亮属性值
    DWORD        LightFightPower;    //点亮附加战力
    BYTE        UnlockWay;    //解锁方式
    DWORD        UnlockValue;    //解锁方式值
    BYTE        UnlockNeedCnt;    //解锁所需个数
    BYTE        UpNeedCnt;    //升级所需个数
    BYTE        StarMax;    //最高星级
    list        AttrIDList;    //属性ID列表
    list        InitAttrValueList;    //初始属性值列表
    list        AttrPerStarAddList;    //每星加成值列表
};
//头像框升星表
//气泡表
struct tagPlayerFacePicStar
struct ChatBox
{
    DWORD        _FacePicID;    //头像框ID
    BYTE        _FacePicStar;    //头像框星级
    list        StarUpNeedItemList;    //升该星所需物品 [[物品ID,个数], ...]
    list        StarAttrType;    //累计总属性类型
    list        StarAttrValue;    //累计总属性值
    BYTE        _BoxID;    //气泡框ID
    DWORD        ExpireMinutes;    //时效分钟,0永久
    BYTE        UnlockWay;    //解锁方式
    DWORD        UnlockValue;    //解锁方式值
    BYTE        UnlockNeedCnt;    //解锁所需个数
    BYTE        UpNeedCnt;    //升级所需个数
    BYTE        StarMax;    //最高星级
    list        AttrIDList;    //属性ID列表
    list        InitAttrValueList;    //初始属性值列表
    list        AttrPerStarAddList;    //每星加成值列表
};
//技能搭配表
@@ -2244,31 +2253,6 @@
{
    DWORD        _FuncID;    //功能ID
    dict        Award;    //属性类型
};
//聊天气泡表
struct tagChatBubbleBox
{
    BYTE        _BoxID;    //气泡框ID
    WORD        NeedLV;    //所需等级
    BYTE        NeedVIPLVGift;    //所需购买VIP等级礼包
    BYTE        UnlockDefault;    //是否默认激活
    DWORD        ExpireMinutes;    //时效分钟,0永久
    list        LightAttrType;    //点亮属性类型
    list        LightAttrValue;    //点亮属性值
    DWORD        LightFightPower;    //点亮附加战力
};
//聊天气泡升星表
struct tagChatBubbleBoxStar
{
    BYTE        _BoxID;    //气泡框ID
    BYTE        _BoxStar;    //气泡框星级
    list        StarUpNeedItemList;    //升该星所需物品 [[物品ID,个数], ...]
    list        StarAttrType;    //累计总属性类型
    list        StarAttrValue;    //累计总属性值
};
//表情包表
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -334,57 +334,17 @@
PacketSubCMD_4=0x06
PacketCallFunc_4=OnPetStarUp
;称号
[PlayerDienstgrad]
ScriptName = Player\PlayerDienstgrad.py
;幻境阁
[PlayerHJG]
ScriptName = Player\PlayerHJG.py
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 1
PacketCMD_1=0xA5
PacketSubCMD_1=0x36
PacketCallFunc_1=OnTitleStarUp
;头像
[PlayerFace]
ScriptName = Player\PlayerFace.py
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 4
PacketCMD_1=0xB2
PacketSubCMD_1=0x26
PacketCallFunc_1=OnFaceChange
PacketCMD_2=0xB2
PacketSubCMD_2=0x27
PacketCallFunc_2=OnFaceStarUP
PacketCMD_3=0xB2
PacketSubCMD_3=0x28
PacketCallFunc_3=OnFacePicChange
PacketCMD_4=0xB2
PacketSubCMD_4=0x29
PacketCallFunc_4=OnFacePicStarUP
;聊天框
[PlayerChatBox]
ScriptName = Player\PlayerChatBox.py
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 2
PacketCMD_1=0xA2
PacketSubCMD_1=0x30
PacketCallFunc_1=OnSetChatBubbleBox
PacketCMD_2=0xA2
PacketSubCMD_2=0x36
PacketCallFunc_2=OnChatBubbleBoxStarUP
PacketSubCMD_1=0x25
PacketCallFunc_1=OnHJGOP
;事件
[EventShell]
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script.ini
@@ -570,22 +570,6 @@
PacketSubCMD_1=0xFE
PacketCallFunc_1=RecNetPack
;玩家称号
[PlayerDienstgrad]
ScriptName = Player\PlayerDienstgrad
Writer = xmnathan
Releaser = xmnathan
RegType = 0
RegisterPackCount = 2
PacketCMD_1=0x3
PacketSubCMD_1=0x35
PacketCallFunc_1=OnCPlayerDienstgradRefresh
PacketCMD_2=0x3
PacketSubCMD_2=0x37
PacketCallFunc_2=OnCPlayerChangeDienstgrad
;任务
[QuestLogic]
ScriptName = Event\QuestLogic.py
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -215,7 +215,8 @@
Def_CalcAttr_HeroBook, # 武将图鉴 2
Def_CalcAttr_Realm, # 官职 3
Def_CalcAttr_Gubao, # 古宝 4
) = range(5)
Def_CalcAttr_HJG, # 幻境阁 5
) = range(6)
CalcAttrName = {
                Def_CalcAttr_LV:"主公等级",
@@ -223,6 +224,7 @@
                Def_CalcAttr_HeroBook:"武将图鉴",
                Def_CalcAttr_Realm:"官职",
                Def_CalcAttr_Gubao:"古宝",
                Def_CalcAttr_HJG:"幻境阁",
                }
##-----------------------------------------------------------------------------------------------
@@ -3584,6 +3586,16 @@
Def_PDict_WishingWellItem = "WishingWellItem_%s_%s"  # 物品ID,是否极品、是否绑定信息 参数(类型,物品数据)
Def_PDict_WishingWellItemCnt = "WishingWellItemCnt_%s_%s"  # 物品数量记录 参数(类型,物品数据)
# 称号
Def_PDict_TitleState = "TitleState_%s"  # 称号状态,参数(key编号)
Def_PDict_TitleEndTime = "TitleEndTime_%s"  # 称号到期时间戳,0为永久,参数(称号ID)
Def_PDict_TitleStar = "TitleStar_%s"  # 称号星级,参数(称号ID)
# 形象
Def_PDict_ModelState = "ModelState_%s"  # 形象状态,参数(key编号)
Def_PDict_ModelEndTime = "ModelEndTime_%s"  # 形象到期时间戳,0为永久,参数(形象ID)
Def_PDict_ModelStar = "ModelStar_%s"  # 形象星级,参数(形象ID)
#头像
Def_PDict_FaceState = "FaceState_%s"  # 头像状态,参数(key编号)
Def_PDict_FaceEndTime = "FaceEndTime_%s"  # 头像到期时间戳,0为永久,参数(头像ID)
@@ -3593,7 +3605,7 @@
Def_PDict_FacePicStar = "FacePicStar_%s"  # 头像框星级,参数(头像框ID)
#聊天气泡
Def_PDict_ChatBubbleBoxState = "ChatBubbleBoxState_%s"  # 聊天气泡状态, 参数(key编号)
Def_PDict_ChatBoxState = "ChatBoxState_%s"  # 聊天气泡状态, 参数(key编号)
Def_PDict_ChatBoxEndTime = "ChatBoxEndTime_%s"  # 到期时间戳,0为永久,参数(气泡ID)
Def_PDict_ChatBoxStar = "ChatBoxStar_%s"  # 星级,参数(气泡ID)
Def_PDict_EmojiPackState = "EmojiPackState_%s"  # 表情包状态,参数(key编号)
@@ -3771,9 +3783,6 @@
#骑宠觉醒
Def_PDict_HorsePetSkinData = "HorsePetSkinData%d_%s"  #觉醒等级*100+外观索引  参数(类型,关联ID) 1-坐骑 2-灵宠
Def_PDict_HorsePetSkinExp = "HorsePetSkinExp%d_%s"  #经验  参数(类型,关联ID) 1-坐骑 2-灵宠
# 称号
Def_PDict_TitleStar = "TitleStar_%s"  # 称号星级,参数(称号ID)
# 符印
Def_PDict_Rune_HoleOpenState = "Rune_HoleOpenState"  # 符印解锁状态
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -1031,58 +1031,6 @@
#------------------------------------------------------
# A2 36 聊天气泡框升星 #tagCMChatBubbleBoxStarUP
class  tagCMChatBubbleBoxStarUP(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("BoxID", c_ubyte),    #气泡ID
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA2
        self.SubCmd = 0x36
        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 = 0xA2
        self.SubCmd = 0x36
        self.BoxID = 0
        return
    def GetLength(self):
        return sizeof(tagCMChatBubbleBoxStarUP)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A2 36 聊天气泡框升星 //tagCMChatBubbleBoxStarUP:
                                Cmd:%s,
                                SubCmd:%s,
                                BoxID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.BoxID
                                )
        return DumpString
m_NAtagCMChatBubbleBoxStarUP=tagCMChatBubbleBoxStarUP()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMChatBubbleBoxStarUP.Cmd,m_NAtagCMChatBubbleBoxStarUP.SubCmd))] = m_NAtagCMChatBubbleBoxStarUP
#------------------------------------------------------
# A2 24 触碰NPC #tagCMTouchNPC
class  tagCMTouchNPC(Structure):
@@ -1962,58 +1910,6 @@
m_NAtagCMSelectRealmDifficulty=tagCMSelectRealmDifficulty()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMSelectRealmDifficulty.Cmd,m_NAtagCMSelectRealmDifficulty.SubCmd))] = m_NAtagCMSelectRealmDifficulty
#------------------------------------------------------
# A2 30 设置聊天气泡框 #tagCMSetChatBubbleBox
class  tagCMSetChatBubbleBox(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("BubbleBoxType", c_ubyte),    #气泡框类型
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA2
        self.SubCmd = 0x30
        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 = 0xA2
        self.SubCmd = 0x30
        self.BubbleBoxType = 0
        return
    def GetLength(self):
        return sizeof(tagCMSetChatBubbleBox)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A2 30 设置聊天气泡框 //tagCMSetChatBubbleBox:
                                Cmd:%s,
                                SubCmd:%s,
                                BubbleBoxType:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.BubbleBoxType
                                )
        return DumpString
m_NAtagCMSetChatBubbleBox=tagCMSetChatBubbleBox()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMSetChatBubbleBox.Cmd,m_NAtagCMSetChatBubbleBox.SubCmd))] = m_NAtagCMSetChatBubbleBox
#------------------------------------------------------
@@ -8237,58 +8133,6 @@
#------------------------------------------------------
# A5 36 称号升星 #tagCMTitleStarUp
class  tagCMTitleStarUp(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("TitleID", c_int),    #称号ID
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA5
        self.SubCmd = 0x36
        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 = 0xA5
        self.SubCmd = 0x36
        self.TitleID = 0
        return
    def GetLength(self):
        return sizeof(tagCMTitleStarUp)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A5 36 称号升星 //tagCMTitleStarUp:
                                Cmd:%s,
                                SubCmd:%s,
                                TitleID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.TitleID
                                )
        return DumpString
m_NAtagCMTitleStarUp=tagCMTitleStarUp()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMTitleStarUp.Cmd,m_NAtagCMTitleStarUp.SubCmd))] = m_NAtagCMTitleStarUp
#------------------------------------------------------
# A5 73 解锁命格孔 #tagCMUnLockBirthChartHole
class  tagCMUnLockBirthChartHole(Structure):
@@ -13062,214 +12906,6 @@
#------------------------------------------------------
# B2 26 头像幻化 #tagCMFaceChange
class  tagCMFaceChange(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("FaceID", c_int),    # 幻化的ID
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB2
        self.SubCmd = 0x26
        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 = 0xB2
        self.SubCmd = 0x26
        self.FaceID = 0
        return
    def GetLength(self):
        return sizeof(tagCMFaceChange)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 26 头像幻化 //tagCMFaceChange:
                                Cmd:%s,
                                SubCmd:%s,
                                FaceID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.FaceID
                                )
        return DumpString
m_NAtagCMFaceChange=tagCMFaceChange()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMFaceChange.Cmd,m_NAtagCMFaceChange.SubCmd))] = m_NAtagCMFaceChange
#------------------------------------------------------
# B2 28 头像框幻化 #tagCMFacePicChange
class  tagCMFacePicChange(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("FacePicID", c_int),    # 幻化的ID
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB2
        self.SubCmd = 0x28
        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 = 0xB2
        self.SubCmd = 0x28
        self.FacePicID = 0
        return
    def GetLength(self):
        return sizeof(tagCMFacePicChange)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 28 头像框幻化 //tagCMFacePicChange:
                                Cmd:%s,
                                SubCmd:%s,
                                FacePicID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.FacePicID
                                )
        return DumpString
m_NAtagCMFacePicChange=tagCMFacePicChange()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMFacePicChange.Cmd,m_NAtagCMFacePicChange.SubCmd))] = m_NAtagCMFacePicChange
#------------------------------------------------------
# B2 29 头像框升星 #tagCMFacePicStarUP
class  tagCMFacePicStarUP(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("FacePicID", c_int),
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB2
        self.SubCmd = 0x29
        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 = 0xB2
        self.SubCmd = 0x29
        self.FacePicID = 0
        return
    def GetLength(self):
        return sizeof(tagCMFacePicStarUP)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 29 头像框升星 //tagCMFacePicStarUP:
                                Cmd:%s,
                                SubCmd:%s,
                                FacePicID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.FacePicID
                                )
        return DumpString
m_NAtagCMFacePicStarUP=tagCMFacePicStarUP()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMFacePicStarUP.Cmd,m_NAtagCMFacePicStarUP.SubCmd))] = m_NAtagCMFacePicStarUP
#------------------------------------------------------
# B2 27 头像升星 #tagCMFaceStarUP
class  tagCMFaceStarUP(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("FaceID", c_int),
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB2
        self.SubCmd = 0x27
        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 = 0xB2
        self.SubCmd = 0x27
        self.FaceID = 0
        return
    def GetLength(self):
        return sizeof(tagCMFaceStarUP)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 27 头像升星 //tagCMFaceStarUP:
                                Cmd:%s,
                                SubCmd:%s,
                                FaceID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.FaceID
                                )
        return DumpString
m_NAtagCMFaceStarUP=tagCMFaceStarUP()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMFaceStarUP.Cmd,m_NAtagCMFaceStarUP.SubCmd))] = m_NAtagCMFaceStarUP
#------------------------------------------------------
# B2 12 领取功能系统特权奖励 #tagCMGetFuncSysPrivilegeAward
class  tagCMGetFuncSysPrivilegeAward(Structure):
@@ -14118,6 +13754,66 @@
#------------------------------------------------------
# B2 25 幻境阁操作 #tagCSHJGOP
class  tagCSHJGOP(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Type", c_ubyte),    # 类型 1-形象;2-头像;3-头像框;4-气泡;5-称号
                  ("OPType", c_ubyte),    # 操作 1-激活;2-佩戴;3-卸下;4-升星
                  ("OPID", c_int),    # 操作对应的ID,如形象ID等
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB2
        self.SubCmd = 0x25
        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 = 0xB2
        self.SubCmd = 0x25
        self.Type = 0
        self.OPType = 0
        self.OPID = 0
        return
    def GetLength(self):
        return sizeof(tagCSHJGOP)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 25 幻境阁操作 //tagCSHJGOP:
                                Cmd:%s,
                                SubCmd:%s,
                                Type:%d,
                                OPType:%d,
                                OPID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Type,
                                self.OPType,
                                self.OPID
                                )
        return DumpString
m_NAtagCSHJGOP=tagCSHJGOP()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSHJGOP.Cmd,m_NAtagCSHJGOP.SubCmd))] = m_NAtagCSHJGOP
#------------------------------------------------------
# B2 07 重置加点 #tagCMResetAttrPoint
class  tagCMResetAttrPoint(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -9466,114 +9466,6 @@
#------------------------------------------------------
# A3 CE 称号星级信息 #tagMCTitleStarInfo
class  tagMCTitleStar(Structure):
    _pack_ = 1
    _fields_ = [
                  ("TitleID", c_int),    # 称号ID
                  ("Star", 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.TitleID = 0
        self.Star = 0
        return
    def GetLength(self):
        return sizeof(tagMCTitleStar)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A3 CE 称号星级信息 //tagMCTitleStarInfo:
                                TitleID:%d,
                                Star:%d
                                '''\
                                %(
                                self.TitleID,
                                self.Star
                                )
        return DumpString
class  tagMCTitleStarInfo(Structure):
    Head = tagHead()
    Count = 0    #(BYTE Count)
    TitleStarList = list()    #(vector<tagMCTitleStar> TitleStarList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0xCE
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.Count):
            temTitleStarList = tagMCTitleStar()
            _pos = temTitleStarList.ReadData(_lpData, _pos)
            self.TitleStarList.append(temTitleStarList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0xCE
        self.Count = 0
        self.TitleStarList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        for i in range(self.Count):
            length += self.TitleStarList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.TitleStarList[i].GetLength(), self.TitleStarList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                TitleStarList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagMCTitleStarInfo=tagMCTitleStarInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTitleStarInfo.Head.Cmd,m_NAtagMCTitleStarInfo.Head.SubCmd))] = m_NAtagMCTitleStarInfo
#------------------------------------------------------
# A3 56 通天令信息 #tagMCTongTianLingInfo
class  tagMCTongTianLingInfo(Structure):
@@ -14752,122 +14644,6 @@
m_NAtagMCBossHurtList=tagMCBossHurtList()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCBossHurtList.Head.Cmd,m_NAtagMCBossHurtList.Head.SubCmd))] = m_NAtagMCBossHurtList
#------------------------------------------------------
# A7 17 聊天气泡框状态 #tagMCChatBubbleBoxState
class  tagMCChatBubbleBox(Structure):
    _pack_ = 1
    _fields_ = [
                  ("BoxID", c_ubyte),    #气泡ID
                  ("State", c_ubyte),    #是否已激活
                  ("EndTime", c_int),    #到期时间戳,0为永久
                  ("Star", 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.BoxID = 0
        self.State = 0
        self.EndTime = 0
        self.Star = 0
        return
    def GetLength(self):
        return sizeof(tagMCChatBubbleBox)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A7 17 聊天气泡框状态 //tagMCChatBubbleBoxState:
                                BoxID:%d,
                                State:%d,
                                EndTime:%d,
                                Star:%d
                                '''\
                                %(
                                self.BoxID,
                                self.State,
                                self.EndTime,
                                self.Star
                                )
        return DumpString
class  tagMCChatBubbleBoxState(Structure):
    Head = tagHead()
    Count = 0    #(BYTE Count)
    BoxList = list()    #(vector<tagMCChatBubbleBox> BoxList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA7
        self.Head.SubCmd = 0x17
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.Count):
            temBoxList = tagMCChatBubbleBox()
            _pos = temBoxList.ReadData(_lpData, _pos)
            self.BoxList.append(temBoxList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA7
        self.Head.SubCmd = 0x17
        self.Count = 0
        self.BoxList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        for i in range(self.Count):
            length += self.BoxList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.BoxList[i].GetLength(), self.BoxList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                BoxList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagMCChatBubbleBoxState=tagMCChatBubbleBoxState()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCChatBubbleBoxState.Head.Cmd,m_NAtagMCChatBubbleBoxState.Head.SubCmd))] = m_NAtagMCChatBubbleBoxState
#------------------------------------------------------
@@ -35765,6 +35541,122 @@
#------------------------------------------------------
# B1 27 聊天气泡框信息 #tagSCChatBoxInfo
class  tagSCChatBox(Structure):
    _pack_ = 1
    _fields_ = [
                  ("BoxID", c_int),    #气泡框ID
                  ("State", c_ubyte),    #是否已激活
                  ("EndTime", c_int),    #到期时间戳,0为永久
                  ("Star", 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.BoxID = 0
        self.State = 0
        self.EndTime = 0
        self.Star = 0
        return
    def GetLength(self):
        return sizeof(tagSCChatBox)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B1 27 聊天气泡框信息 //tagSCChatBoxInfo:
                                BoxID:%d,
                                State:%d,
                                EndTime:%d,
                                Star:%d
                                '''\
                                %(
                                self.BoxID,
                                self.State,
                                self.EndTime,
                                self.Star
                                )
        return DumpString
class  tagSCChatBoxInfo(Structure):
    Head = tagHead()
    Count = 0    #(BYTE Count)
    BoxList = list()    #(vector<tagSCChatBox> BoxList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x27
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.Count):
            temBoxList = tagSCChatBox()
            _pos = temBoxList.ReadData(_lpData, _pos)
            self.BoxList.append(temBoxList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x27
        self.Count = 0
        self.BoxList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        for i in range(self.Count):
            length += self.BoxList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.BoxList[i].GetLength(), self.BoxList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                BoxList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagSCChatBoxInfo=tagSCChatBoxInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCChatBoxInfo.Head.Cmd,m_NAtagSCChatBoxInfo.Head.SubCmd))] = m_NAtagSCChatBoxInfo
#------------------------------------------------------
# B1 02 玩家时装皮肤激活状态 #tagMCClothesCoatSkinState
class  tagMCClothesCoatLVInfo(Structure):
@@ -36598,6 +36490,122 @@
#------------------------------------------------------
# B1 19 形象信息 #tagSCModelInfo
class  tagSCModel(Structure):
    _pack_ = 1
    _fields_ = [
                  ("ModelID", c_int),    #形象ID
                  ("State", c_ubyte),    #是否已激活
                  ("EndTime", c_int),    #到期时间戳,0为永久
                  ("Star", 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.ModelID = 0
        self.State = 0
        self.EndTime = 0
        self.Star = 0
        return
    def GetLength(self):
        return sizeof(tagSCModel)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B1 19 形象信息 //tagSCModelInfo:
                                ModelID:%d,
                                State:%d,
                                EndTime:%d,
                                Star:%d
                                '''\
                                %(
                                self.ModelID,
                                self.State,
                                self.EndTime,
                                self.Star
                                )
        return DumpString
class  tagSCModelInfo(Structure):
    Head = tagHead()
    Count = 0    #(BYTE Count)
    ModelList = list()    #(vector<tagSCModel> ModelList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x19
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.Count):
            temModelList = tagSCModel()
            _pos = temModelList.ReadData(_lpData, _pos)
            self.ModelList.append(temModelList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x19
        self.Count = 0
        self.ModelList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        for i in range(self.Count):
            length += self.ModelList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.ModelList[i].GetLength(), self.ModelList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                ModelList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagSCModelInfo=tagSCModelInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCModelInfo.Head.Cmd,m_NAtagSCModelInfo.Head.SubCmd))] = m_NAtagSCModelInfo
#------------------------------------------------------
# B1 06 通知玩家向目标点移动 #tagMCNotifyPlayerMove
class  tagMCNotifyPlayerMove(Structure):
@@ -37297,6 +37305,122 @@
#------------------------------------------------------
# B1 26 称号信息 #tagSCTitleInfo
class  tagSCTitle(Structure):
    _pack_ = 1
    _fields_ = [
                  ("TitleID", c_int),    #称号ID
                  ("State", c_ubyte),    #是否已激活
                  ("EndTime", c_int),    #到期时间戳,0为永久
                  ("Star", 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.TitleID = 0
        self.State = 0
        self.EndTime = 0
        self.Star = 0
        return
    def GetLength(self):
        return sizeof(tagSCTitle)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B1 26 称号信息 //tagSCTitleInfo:
                                TitleID:%d,
                                State:%d,
                                EndTime:%d,
                                Star:%d
                                '''\
                                %(
                                self.TitleID,
                                self.State,
                                self.EndTime,
                                self.Star
                                )
        return DumpString
class  tagSCTitleInfo(Structure):
    Head = tagHead()
    Count = 0    #(BYTE Count)
    TitleList = list()    #(vector<tagSCTitle> TitleList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x26
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.Count):
            temTitleList = tagSCTitle()
            _pos = temTitleList.ReadData(_lpData, _pos)
            self.TitleList.append(temTitleList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB1
        self.Head.SubCmd = 0x26
        self.Count = 0
        self.TitleList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        for i in range(self.Count):
            length += self.TitleList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.TitleList[i].GetLength(), self.TitleList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                TitleList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagSCTitleInfo=tagSCTitleInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCTitleInfo.Head.Cmd,m_NAtagSCTitleInfo.Head.SubCmd))] = m_NAtagSCTitleInfo
#------------------------------------------------------
# B1 12 培养功能境界信息 #tagMCTrainRealmLVInfo
class  tagMCTrainRealmLV(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/AddTitle.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ChatBox.py
@@ -34,8 +34,8 @@
        GameWorld.DebugAnswer(curPlayer, "添加气泡框: ChatBox b1 气泡框ID [有效秒]")
        GameWorld.DebugAnswer(curPlayer, "删除气泡框: ChatBox b0 [气泡框ID]")
        GameWorld.DebugAnswer(curPlayer, "气泡框星级: ChatBox bs 气泡框ID 星级")
        GameWorld.DebugAnswer(curPlayer, "添加表情包: ChatBox e1 表情包ID [有效秒]")
        GameWorld.DebugAnswer(curPlayer, "删除表情包: ChatBox e0 [表情包ID]")
        #GameWorld.DebugAnswer(curPlayer, "添加表情包: ChatBox e1 表情包ID [有效秒]")
        #GameWorld.DebugAnswer(curPlayer, "删除表情包: ChatBox e0 [表情包ID]")
        GameWorld.DebugAnswer(curPlayer, "有效秒:不填读表,0-永久,>0指定有效秒")
        return
    
@@ -48,26 +48,21 @@
    if value1 == "b0":
        boxID = msgList[1] if len(msgList) > 1 else 0
        if not boxID:
            for index in range(ipyDataMgr.GetChatBubbleBoxCount()):
                ipyData = ipyDataMgr.GetChatBubbleBoxByIndex(index)
            for index in range(ipyDataMgr.GetChatBoxCount()):
                ipyData = ipyDataMgr.GetChatBoxByIndex(index)
                boxID = ipyData.GetBoxID()
                if ipyData.GetUnlockDefault():
                if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBoxState, boxID):
                    continue
                if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBubbleBoxState, boxID):
                    continue
                GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBubbleBoxState, boxID, 0)
                GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBoxState, boxID, 0)
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChatBoxEndTime % boxID, 0)
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChatBoxStar % boxID, 0)
                syncBoxIDList.append(boxID)
        else:
            ipyData = IpyGameDataPY.GetIpyGameData("ChatBubbleBox", boxID)
            ipyData = IpyGameDataPY.GetIpyGameData("ChatBox", boxID)
            if not ipyData:
                GameWorld.DebugAnswer(curPlayer, "该气泡框不存在:%s" % boxID)
                return
            if ipyData.GetUnlockDefault():
                GameWorld.DebugAnswer(curPlayer, "该气泡框默认激活:%s" % boxID)
                return
            GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBubbleBoxState, boxID, 0)
            GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBoxState, boxID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChatBoxEndTime % boxID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChatBoxStar % boxID, 0)
            syncBoxIDList.append(boxID)
@@ -77,7 +72,7 @@
    elif value1 == "b1":
        boxID = msgList[1] if len(msgList) > 1 else 0
        expireTimes = msgList[2] if len(msgList) > 2 else None
        if PlayerChatBox.AddChatBox(curPlayer, boxID, expireTimes):
        if PlayerChatBox.AddChatBox(curPlayer, boxID, expireTimes, True):
            endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ChatBoxEndTime % boxID)
            endTimeStr = "永久" if not endTime else GameWorld.ChangeTimeNumToStr(endTime)
            GameWorld.DebugAnswer(curPlayer, "添加气泡框成功:%s,到期:%s" % (boxID, endTimeStr))
@@ -88,11 +83,11 @@
    elif value1 == "bs":
        boxID = msgList[1] if len(msgList) > 1 else 0
        boxStar = msgList[2] if len(msgList) > 2 else 0
        if boxStar:
            starIpyData = IpyGameDataPY.GetIpyGameData("ChatBubbleBoxStar", boxID, boxStar)
            if not starIpyData:
                GameWorld.DebugAnswer(curPlayer, "气泡框星级不存在:%s,star:%s" % (boxID, boxStar))
                return
        ipyData = IpyGameDataPY.GetIpyGameData("ChatBox", boxID)
        if not ipyData:
            GameWorld.DebugAnswer(curPlayer, "该气泡框不存在:%s" % boxID)
            return
        boxStar = min(boxStar, ipyData.GetStarMax())
        GameWorld.DebugAnswer(curPlayer, "设置气泡框星级:%s,星:%s" % (boxID, boxStar))
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChatBoxStar % boxID, boxStar)
        syncBoxIDList.append(boxID)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearTitle.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Face.py
@@ -52,10 +52,6 @@
            for index in range(ipyDataMgr.GetPlayerFaceCount()):
                ipyData = ipyDataMgr.GetPlayerFaceByIndex(index)
                faceID = ipyData.GetFaceID()
                if ipyData.GetUnlockDefault():
                    continue
                if ipyData.GetCustomPlayerID():
                    continue
                if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FaceState, faceID):
                    continue
                GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_FaceState, faceID, 0)
@@ -67,12 +63,6 @@
            if not ipyData:
                GameWorld.DebugAnswer(curPlayer, "该头像不存在:%s" % faceID)
                return
            if ipyData.GetUnlockDefault():
                GameWorld.DebugAnswer(curPlayer, "该头像默认激活:%s" % faceID)
                return
            if ipyData.GetCustomPlayerID():
                GameWorld.DebugAnswer(curPlayer, "定制头像不处理:%s" % faceID)
                return
            GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_FaceState, faceID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FaceEndTime % faceID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FaceStar % faceID, 0)
@@ -83,21 +73,22 @@
    elif value1 == "f1":
        faceID = msgList[1] if len(msgList) > 1 else 0
        expireTimes = msgList[2] if len(msgList) > 2 else None
        if PlayerFace.AddFace(curPlayer, faceID, expireTimes):
        if PlayerFace.AddFace(curPlayer, faceID, expireTimes, True):
            endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceEndTime % faceID)
            endTimeStr = "永久" if not endTime else GameWorld.ChangeTimeNumToStr(endTime)
            GameWorld.DebugAnswer(curPlayer, "添加头像成功:%s,到期:%s" % (faceID, endTimeStr))
        else:
            GameWorld.DebugAnswer(curPlayer, "添加头像失败:%s" % (faceID))
    # 头像星级
    elif value1 == "fs":
        faceID = msgList[1] if len(msgList) > 1 else 0
        faceStar = msgList[2] if len(msgList) > 2 else 0
        starIpyData = IpyGameDataPY.GetIpyGameData("PlayerFaceStar", faceID, faceStar)
        if not starIpyData:
            GameWorld.DebugAnswer(curPlayer, "头像星级不存在:%s,star:%s" % (faceID, faceStar))
        ipyData = IpyGameDataPY.GetIpyGameData("PlayerFace", faceID)
        if not ipyData:
            GameWorld.DebugAnswer(curPlayer, "该头像不存在:%s" % faceID)
            return
        faceStar = min(faceStar, ipyData.GetStarMax())
        GameWorld.DebugAnswer(curPlayer, "设置头像星级:%s,星:%s" % (faceID, faceStar))
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FaceStar % faceID, faceStar)
        syncFaceIDList.append(faceID)
@@ -109,8 +100,6 @@
            for index in range(ipyDataMgr.GetPlayerFacePicCount()):
                ipyData = ipyDataMgr.GetPlayerFacePicByIndex(index)
                facePicID = ipyData.GetFacePicID()
                if ipyData.GetUnlockDefault():
                    continue
                if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FacePicState, facePicID):
                    continue
                GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_FacePicState, facePicID, 0)
@@ -122,9 +111,6 @@
            if not ipyData:
                GameWorld.DebugAnswer(curPlayer, "该头像框不存在:%s" % facePicID)
                return
            if ipyData.GetUnlockDefault():
                GameWorld.DebugAnswer(curPlayer, "该头像框默认激活:%s" % facePicID)
                return
            GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_FacePicState, facePicID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FacePicEndTime % facePicID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FacePicStar % facePicID, 0)
@@ -135,7 +121,7 @@
    elif value1 == "p1":
        facePicID = msgList[1] if len(msgList) > 1 else 0
        expireTimes = msgList[2] if len(msgList) > 2 else None
        if PlayerFace.AddFacePic(curPlayer, facePicID, expireTimes):
        if PlayerFace.AddFacePic(curPlayer, facePicID, expireTimes, True):
            endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FacePicEndTime % facePicID)
            endTimeStr = "永久" if not endTime else GameWorld.ChangeTimeNumToStr(endTime)
            GameWorld.DebugAnswer(curPlayer, "添加头像框成功:%s,到期:%s" % (facePicID, endTimeStr))
@@ -146,10 +132,11 @@
    elif value1 == "ps":
        facePicID = msgList[1] if len(msgList) > 1 else 0
        facePicStar = msgList[2] if len(msgList) > 2 else 0
        starIpyData = IpyGameDataPY.GetIpyGameData("PlayerFacePicStar", facePicID, facePicStar)
        if not starIpyData:
            GameWorld.DebugAnswer(curPlayer, "头像框星级不存在:%s,star:%s" % (facePicID, facePicStar))
        ipyData = IpyGameDataPY.GetIpyGameData("PlayerFacePic", facePicID)
        if not ipyData:
            GameWorld.DebugAnswer(curPlayer, "该头像框不存在:%s" % facePicID)
            return
        facePicStar = min(facePicStar, ipyData.GetStarMax())
        GameWorld.DebugAnswer(curPlayer, "设置头像框星级:%s,星:%s" % (facePicID, facePicStar))
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FacePicStar % facePicID, facePicStar)
        syncFacePicIDList.append(facePicID)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/HJG.py
New file
@@ -0,0 +1,149 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.HJG
#
# @todo:幻境阁
# @author hxp
# @date 2025-10-15
# @version 1.0
#
# 详细描述: 幻境阁
#
#-------------------------------------------------------------------------------
#"""Version = 2025-10-15 09:30"""
#-------------------------------------------------------------------------------
import ChConfig
import GameWorld
import IpyGameDataPY
import PlayerControl
import PlayerHJG
import ChatBox
import Face
def OnExec(curPlayer, msgList):
    if not msgList:
        GameWorld.DebugAnswer(curPlayer, "---------- %s" % GameWorld.GetCurrentDataTimeStr())
        GameWorld.DebugAnswer(curPlayer, "添加称号: HJG t1 称号ID [有效秒]")
        GameWorld.DebugAnswer(curPlayer, "删除称号: HJG t0 [称号ID]")
        GameWorld.DebugAnswer(curPlayer, "称号星级: HJG ts 称号ID 星级")
        GameWorld.DebugAnswer(curPlayer, "添加形象: HJG m1 形象ID [有效秒]")
        GameWorld.DebugAnswer(curPlayer, "删除形象: HJG m0 [形象ID]")
        GameWorld.DebugAnswer(curPlayer, "形象星级: HJG ms 形象ID 星级")
        GameWorld.DebugAnswer(curPlayer, "有效秒:不填读表,0-永久,>0指定有效秒")
        Face.OnExec(curPlayer, msgList)
        ChatBox.OnExec(curPlayer, msgList)
        return
    syncTitleIDList = []
    syncModelIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    value1 = msgList[0]
    # 删除称号
    if value1 == "t1":
        titleID = msgList[1] if len(msgList) > 1 else 0
        if not titleID:
            for index in range(ipyDataMgr.GetTitleCount()):
                ipyData = ipyDataMgr.GetTitleByIndex(index)
                titleID = ipyData.GetTitleID()
                if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, titleID):
                    continue
                GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, titleID, 0)
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TitleEndTime % titleID, 0)
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TitleStar % titleID, 0)
                syncTitleIDList.append(titleID)
        else:
            ipyData = IpyGameDataPY.GetIpyGameData("Title", titleID)
            if not ipyData:
                GameWorld.DebugAnswer(curPlayer, "该称号不存在:%s" % titleID)
                return
            GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, titleID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TitleEndTime % titleID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TitleStar % titleID, 0)
            syncTitleIDList.append(titleID)
        GameWorld.DebugAnswer(curPlayer, "删除称号:%s" % syncTitleIDList)
    # 添加称号
    elif value1 == "t1":
        titleID = msgList[1] if len(msgList) > 1 else 0
        expireTimes = msgList[2] if len(msgList) > 2 else None
        if PlayerHJG.AddTitle(curPlayer, titleID, expireTimes, True):
            endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TitleEndTime % titleID)
            endTimeStr = "永久" if not endTime else GameWorld.ChangeTimeNumToStr(endTime)
            GameWorld.DebugAnswer(curPlayer, "添加称号成功:%s,到期:%s" % (titleID, endTimeStr))
        else:
            GameWorld.DebugAnswer(curPlayer, "添加称号失败:%s" % (titleID))
    # 称号星级
    elif value1 == "ts":
        titleID = msgList[1] if len(msgList) > 1 else 0
        setStar = msgList[2] if len(msgList) > 2 else 0
        ipyData = IpyGameDataPY.GetIpyGameData("Title", titleID)
        if not ipyData:
            GameWorld.DebugAnswer(curPlayer, "该称号不存在:%s" % titleID)
            return
        setStar = min(setStar, ipyData.GetStarMax())
        GameWorld.DebugAnswer(curPlayer, "设置称号星级:%s,星:%s" % (titleID, setStar))
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TitleStar % titleID, setStar)
        syncTitleIDList.append(titleID)
    # 删除形象
    elif value1 == "m0":
        modelID = msgList[1] if len(msgList) > 1 else 0
        if not modelID:
            for index in range(ipyDataMgr.GetModelCount()):
                ipyData = ipyDataMgr.GetModelByIndex(index)
                modelID = ipyData.GetModelID()
                if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ModelState, modelID):
                    continue
                GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ModelState, modelID, 0)
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ModelEndTime % modelID, 0)
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ModelStar % modelID, 0)
                syncModelIDList.append(modelID)
        else:
            ipyData = IpyGameDataPY.GetIpyGameData("Model", modelID)
            if not ipyData:
                GameWorld.DebugAnswer(curPlayer, "该形象不存在:%s" % modelID)
                return
            GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ModelState, modelID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ModelEndTime % modelID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ModelStar % modelID, 0)
            syncModelIDList.append(modelID)
        GameWorld.DebugAnswer(curPlayer, "删除形象:%s" % syncModelIDList)
    # 添加形象
    elif value1 == "m1":
        modelID = msgList[1] if len(msgList) > 1 else 0
        expireTimes = msgList[2] if len(msgList) > 2 else None
        if PlayerHJG.AddModel(curPlayer, modelID, expireTimes, True):
            endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ModelEndTime % modelID)
            endTimeStr = "永久" if not endTime else GameWorld.ChangeTimeNumToStr(endTime)
            GameWorld.DebugAnswer(curPlayer, "添加形象成功:%s,到期:%s" % (modelID, endTimeStr))
        else:
            GameWorld.DebugAnswer(curPlayer, "添加形象失败:%s" % (modelID))
    # 形象星级
    elif value1 == "ms":
        modelID = msgList[1] if len(msgList) > 1 else 0
        setStar = msgList[2] if len(msgList) > 2 else 0
        ipyData = IpyGameDataPY.GetIpyGameData("Model", modelID)
        if not ipyData:
            GameWorld.DebugAnswer(curPlayer, "该形象不存在:%s" % modelID)
            return
        setStar = min(setStar, ipyData.GetStarMax())
        GameWorld.DebugAnswer(curPlayer, "设置形象星级:%s,星:%s" % (modelID, setStar))
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ModelStar % modelID, setStar)
        syncModelIDList.append(modelID)
    if syncTitleIDList:
        PlayerHJG.RefreshHJGAttr(curPlayer)
        PlayerHJG.SyncTitleInfo(curPlayer, syncTitleIDList)
    if syncModelIDList:
        PlayerHJG.RefreshHJGAttr(curPlayer)
        PlayerHJG.SyncModelInfo(curPlayer, syncModelIDList)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -333,57 +333,69 @@
                        ("BYTE", "SkillExCnt", 0),
                        ),
                "Dienstgrad":(
                        ("DWORD", "ID", 1),
                        ("WORD", "Type", 0),
                        ("DWORD", "ExpireTime", 0),
                        ("list", "LightType", 0),
                        ("list", "LightAttribute", 0),
                        ("list", "Skills", 0),
                        ("DWORD", "InitFightPower", 0),
                "Title":(
                        ("DWORD", "TitleID", 1),
                        ("DWORD", "ExpireMinutes", 0),
                        ("BYTE", "UnlockWay", 0),
                        ("DWORD", "UnlockValue", 0),
                        ("BYTE", "UnlockNeedCnt", 0),
                        ("BYTE", "UpNeedCnt", 0),
                        ("BYTE", "StarMax", 0),
                        ("list", "AttrIDList", 0),
                        ("list", "InitAttrValueList", 0),
                        ("list", "AttrPerStarAddList", 0),
                        ),
                "TitleStarUp":(
                        ("DWORD", "TitleID", 1),
                        ("BYTE", "TitleStar", 1),
                        ("list", "StarUpNeedItemList", 0),
                        ("list", "StarAttrType", 0),
                        ("list", "StarAttrValue", 0),
                "Model":(
                        ("DWORD", "ModelID", 1),
                        ("DWORD", "ExpireMinutes", 0),
                        ("BYTE", "UnlockWay", 0),
                        ("DWORD", "UnlockValue", 0),
                        ("BYTE", "UnlockNeedCnt", 0),
                        ("BYTE", "UpNeedCnt", 0),
                        ("BYTE", "StarMax", 0),
                        ("list", "AttrIDList", 0),
                        ("list", "InitAttrValueList", 0),
                        ("list", "AttrPerStarAddList", 0),
                        ),
                "PlayerFace":(
                        ("DWORD", "FaceID", 1),
                        ("BYTE", "UnlockDefault", 0),
                        ("DWORD", "ExpireMinutes", 0),
                        ("DWORD", "CustomPlayerID", 0),
                        ("list", "LightAttrType", 0),
                        ("list", "LightAttrValue", 0),
                        ("DWORD", "LightFightPower", 0),
                        ),
                "PlayerFaceStar":(
                        ("DWORD", "FaceID", 1),
                        ("BYTE", "FaceStar", 1),
                        ("list", "StarUpNeedItemList", 0),
                        ("list", "StarAttrType", 0),
                        ("list", "StarAttrValue", 0),
                        ("BYTE", "UnlockWay", 0),
                        ("DWORD", "UnlockValue", 0),
                        ("BYTE", "UnlockNeedCnt", 0),
                        ("BYTE", "UpNeedCnt", 0),
                        ("BYTE", "StarMax", 0),
                        ("list", "AttrIDList", 0),
                        ("list", "InitAttrValueList", 0),
                        ("list", "AttrPerStarAddList", 0),
                        ),
                "PlayerFacePic":(
                        ("DWORD", "FacePicID", 1),
                        ("BYTE", "UnlockDefault", 0),
                        ("DWORD", "ExpireMinutes", 0),
                        ("list", "LightAttrType", 0),
                        ("list", "LightAttrValue", 0),
                        ("DWORD", "LightFightPower", 0),
                        ("BYTE", "UnlockWay", 0),
                        ("DWORD", "UnlockValue", 0),
                        ("BYTE", "UnlockNeedCnt", 0),
                        ("BYTE", "UpNeedCnt", 0),
                        ("BYTE", "StarMax", 0),
                        ("list", "AttrIDList", 0),
                        ("list", "InitAttrValueList", 0),
                        ("list", "AttrPerStarAddList", 0),
                        ),
                "PlayerFacePicStar":(
                        ("DWORD", "FacePicID", 1),
                        ("BYTE", "FacePicStar", 1),
                        ("list", "StarUpNeedItemList", 0),
                        ("list", "StarAttrType", 0),
                        ("list", "StarAttrValue", 0),
                "ChatBox":(
                        ("BYTE", "BoxID", 1),
                        ("DWORD", "ExpireMinutes", 0),
                        ("BYTE", "UnlockWay", 0),
                        ("DWORD", "UnlockValue", 0),
                        ("BYTE", "UnlockNeedCnt", 0),
                        ("BYTE", "UpNeedCnt", 0),
                        ("BYTE", "StarMax", 0),
                        ("list", "AttrIDList", 0),
                        ("list", "InitAttrValueList", 0),
                        ("list", "AttrPerStarAddList", 0),
                        ),
                "SkillMatch":(
@@ -1790,25 +1802,6 @@
                        ("dict", "Award", 0),
                        ),
                "ChatBubbleBox":(
                        ("BYTE", "BoxID", 1),
                        ("WORD", "NeedLV", 0),
                        ("BYTE", "NeedVIPLVGift", 0),
                        ("BYTE", "UnlockDefault", 0),
                        ("DWORD", "ExpireMinutes", 0),
                        ("list", "LightAttrType", 0),
                        ("list", "LightAttrValue", 0),
                        ("DWORD", "LightFightPower", 0),
                        ),
                "ChatBubbleBoxStar":(
                        ("BYTE", "BoxID", 1),
                        ("BYTE", "BoxStar", 1),
                        ("list", "StarUpNeedItemList", 0),
                        ("list", "StarAttrType", 0),
                        ("list", "StarAttrValue", 0),
                        ),
                "EmojiPack":(
                        ("DWORD", "EmojiPackID", 1),
                        ("BYTE", "UnlockDefault", 0),
@@ -2923,32 +2916,40 @@
    def GetSkillExCnt(self): return self.attrTuple[10] # 随机附加技能数,0为所有 BYTE
# 称号表
class IPY_Dienstgrad():
class IPY_Title():
    
    def __init__(self):
        self.attrTuple = None
        return
        
    def GetID(self): return self.attrTuple[0] # 头衔id DWORD
    def GetType(self): return self.attrTuple[1] # 头衔类型 WORD
    def GetExpireTime(self): return self.attrTuple[2] # 有效时间 DWORD
    def GetLightType(self): return self.attrTuple[3] # 点亮属性类型 list
    def GetLightAttribute(self): return self.attrTuple[4] # 点亮属性值 list
    def GetSkills(self): return self.attrTuple[5] # 被动技能 list
    def GetInitFightPower(self): return self.attrTuple[6] # 初始战力 DWORD
    def GetTitleID(self): return self.attrTuple[0] # 称号ID DWORD
    def GetExpireMinutes(self): return self.attrTuple[1] # 时效分钟,0永久 DWORD
    def GetUnlockWay(self): return self.attrTuple[2] # 解锁方式 BYTE
    def GetUnlockValue(self): return self.attrTuple[3] # 解锁方式值 DWORD
    def GetUnlockNeedCnt(self): return self.attrTuple[4] # 解锁所需个数 BYTE
    def GetUpNeedCnt(self): return self.attrTuple[5] # 升级所需个数 BYTE
    def GetStarMax(self): return self.attrTuple[6] # 最高星级 BYTE
    def GetAttrIDList(self): return self.attrTuple[7] # 属性ID列表 list
    def GetInitAttrValueList(self): return self.attrTuple[8] # 初始属性值列表 list
    def GetAttrPerStarAddList(self): return self.attrTuple[9] # 每星加成值列表 list
# 称号升星表
class IPY_TitleStarUp():
# 形象表
class IPY_Model():
    
    def __init__(self):
        self.attrTuple = None
        return
        
    def GetTitleID(self): return self.attrTuple[0] # 称号NPCID DWORD
    def GetTitleStar(self): return self.attrTuple[1] # 称号星级 BYTE
    def GetStarUpNeedItemList(self): return self.attrTuple[2] # 升下一星所需道具 [[物品ID,个数], ...] list
    def GetStarAttrType(self): return self.attrTuple[3] # 累计总属性类型 list
    def GetStarAttrValue(self): return self.attrTuple[4] # 累计总属性值 list
    def GetModelID(self): return self.attrTuple[0] # 形象ID DWORD
    def GetExpireMinutes(self): return self.attrTuple[1] # 时效分钟,0永久 DWORD
    def GetUnlockWay(self): return self.attrTuple[2] # 解锁方式 BYTE
    def GetUnlockValue(self): return self.attrTuple[3] # 解锁方式值 DWORD
    def GetUnlockNeedCnt(self): return self.attrTuple[4] # 解锁所需个数 BYTE
    def GetUpNeedCnt(self): return self.attrTuple[5] # 升级所需个数 BYTE
    def GetStarMax(self): return self.attrTuple[6] # 最高星级 BYTE
    def GetAttrIDList(self): return self.attrTuple[7] # 属性ID列表 list
    def GetInitAttrValueList(self): return self.attrTuple[8] # 初始属性值列表 list
    def GetAttrPerStarAddList(self): return self.attrTuple[9] # 每星加成值列表 list
# 头像表
class IPY_PlayerFace():
@@ -2958,25 +2959,15 @@
        return
        
    def GetFaceID(self): return self.attrTuple[0] # 头像ID DWORD
    def GetUnlockDefault(self): return self.attrTuple[1] # 是否默认激活 BYTE
    def GetExpireMinutes(self): return self.attrTuple[2] # 时效分钟,0永久 DWORD
    def GetCustomPlayerID(self): return self.attrTuple[3] # 定制玩家ID DWORD
    def GetLightAttrType(self): return self.attrTuple[4] # 点亮属性类型 list
    def GetLightAttrValue(self): return self.attrTuple[5] # 点亮属性值 list
    def GetLightFightPower(self): return self.attrTuple[6] # 点亮附加战力 DWORD
# 头像升星表
class IPY_PlayerFaceStar():
    def __init__(self):
        self.attrTuple = None
        return
    def GetFaceID(self): return self.attrTuple[0] # 头像ID DWORD
    def GetFaceStar(self): return self.attrTuple[1] # 头像星级 BYTE
    def GetStarUpNeedItemList(self): return self.attrTuple[2] # 升该星所需物品 [[物品ID,个数], ...] list
    def GetStarAttrType(self): return self.attrTuple[3] # 累计总属性类型 list
    def GetStarAttrValue(self): return self.attrTuple[4] # 累计总属性值 list
    def GetExpireMinutes(self): return self.attrTuple[1] # 时效分钟,0永久 DWORD
    def GetUnlockWay(self): return self.attrTuple[2] # 解锁方式 BYTE
    def GetUnlockValue(self): return self.attrTuple[3] # 解锁方式值 DWORD
    def GetUnlockNeedCnt(self): return self.attrTuple[4] # 解锁所需个数 BYTE
    def GetUpNeedCnt(self): return self.attrTuple[5] # 升级所需个数 BYTE
    def GetStarMax(self): return self.attrTuple[6] # 最高星级 BYTE
    def GetAttrIDList(self): return self.attrTuple[7] # 属性ID列表 list
    def GetInitAttrValueList(self): return self.attrTuple[8] # 初始属性值列表 list
    def GetAttrPerStarAddList(self): return self.attrTuple[9] # 每星加成值列表 list
# 头像框表
class IPY_PlayerFacePic():
@@ -2986,24 +2977,33 @@
        return
        
    def GetFacePicID(self): return self.attrTuple[0] # 头像框ID DWORD
    def GetUnlockDefault(self): return self.attrTuple[1] # 是否默认激活 BYTE
    def GetExpireMinutes(self): return self.attrTuple[2] # 时效分钟,0永久 DWORD
    def GetLightAttrType(self): return self.attrTuple[3] # 点亮属性类型 list
    def GetLightAttrValue(self): return self.attrTuple[4] # 点亮属性值 list
    def GetLightFightPower(self): return self.attrTuple[5] # 点亮附加战力 DWORD
    def GetExpireMinutes(self): return self.attrTuple[1] # 时效分钟,0永久 DWORD
    def GetUnlockWay(self): return self.attrTuple[2] # 解锁方式 BYTE
    def GetUnlockValue(self): return self.attrTuple[3] # 解锁方式值 DWORD
    def GetUnlockNeedCnt(self): return self.attrTuple[4] # 解锁所需个数 BYTE
    def GetUpNeedCnt(self): return self.attrTuple[5] # 升级所需个数 BYTE
    def GetStarMax(self): return self.attrTuple[6] # 最高星级 BYTE
    def GetAttrIDList(self): return self.attrTuple[7] # 属性ID列表 list
    def GetInitAttrValueList(self): return self.attrTuple[8] # 初始属性值列表 list
    def GetAttrPerStarAddList(self): return self.attrTuple[9] # 每星加成值列表 list
# 头像框升星表
class IPY_PlayerFacePicStar():
# 气泡表
class IPY_ChatBox():
    
    def __init__(self):
        self.attrTuple = None
        return
        
    def GetFacePicID(self): return self.attrTuple[0] # 头像框ID DWORD
    def GetFacePicStar(self): return self.attrTuple[1] # 头像框星级 BYTE
    def GetStarUpNeedItemList(self): return self.attrTuple[2] # 升该星所需物品 [[物品ID,个数], ...] list
    def GetStarAttrType(self): return self.attrTuple[3] # 累计总属性类型 list
    def GetStarAttrValue(self): return self.attrTuple[4] # 累计总属性值 list
    def GetBoxID(self): return self.attrTuple[0] # 气泡框ID BYTE
    def GetExpireMinutes(self): return self.attrTuple[1] # 时效分钟,0永久 DWORD
    def GetUnlockWay(self): return self.attrTuple[2] # 解锁方式 BYTE
    def GetUnlockValue(self): return self.attrTuple[3] # 解锁方式值 DWORD
    def GetUnlockNeedCnt(self): return self.attrTuple[4] # 解锁所需个数 BYTE
    def GetUpNeedCnt(self): return self.attrTuple[5] # 升级所需个数 BYTE
    def GetStarMax(self): return self.attrTuple[6] # 最高星级 BYTE
    def GetAttrIDList(self): return self.attrTuple[7] # 属性ID列表 list
    def GetInitAttrValueList(self): return self.attrTuple[8] # 初始属性值列表 list
    def GetAttrPerStarAddList(self): return self.attrTuple[9] # 每星加成值列表 list
# 技能搭配表
class IPY_SkillMatch():
@@ -5104,35 +5104,6 @@
    def GetFuncID(self): return self.attrTuple[0] # 功能ID DWORD
    def GetAward(self): return self.attrTuple[1] # 属性类型 dict
# 聊天气泡表
class IPY_ChatBubbleBox():
    def __init__(self):
        self.attrTuple = None
        return
    def GetBoxID(self): return self.attrTuple[0] # 气泡框ID BYTE
    def GetNeedLV(self): return self.attrTuple[1] # 所需等级 WORD
    def GetNeedVIPLVGift(self): return self.attrTuple[2] # 所需购买VIP等级礼包 BYTE
    def GetUnlockDefault(self): return self.attrTuple[3] # 是否默认激活 BYTE
    def GetExpireMinutes(self): return self.attrTuple[4] # 时效分钟,0永久 DWORD
    def GetLightAttrType(self): return self.attrTuple[5] # 点亮属性类型 list
    def GetLightAttrValue(self): return self.attrTuple[6] # 点亮属性值 list
    def GetLightFightPower(self): return self.attrTuple[7] # 点亮附加战力 DWORD
# 聊天气泡升星表
class IPY_ChatBubbleBoxStar():
    def __init__(self):
        self.attrTuple = None
        return
    def GetBoxID(self): return self.attrTuple[0] # 气泡框ID BYTE
    def GetBoxStar(self): return self.attrTuple[1] # 气泡框星级 BYTE
    def GetStarUpNeedItemList(self): return self.attrTuple[2] # 升该星所需物品 [[物品ID,个数], ...] list
    def GetStarAttrType(self): return self.attrTuple[3] # 累计总属性类型 list
    def GetStarAttrValue(self): return self.attrTuple[4] # 累计总属性值 list
# 表情包表
class IPY_EmojiPack():
    
@@ -6338,12 +6309,11 @@
        self.__LoadFileData("MainChapter", onlyCheck)
        self.__LoadFileData("MainLevel", onlyCheck)
        self.__LoadFileData("NPCLineup", onlyCheck)
        self.__LoadFileData("Dienstgrad", onlyCheck)
        self.__LoadFileData("TitleStarUp", onlyCheck)
        self.__LoadFileData("Title", onlyCheck)
        self.__LoadFileData("Model", onlyCheck)
        self.__LoadFileData("PlayerFace", onlyCheck)
        self.__LoadFileData("PlayerFaceStar", onlyCheck)
        self.__LoadFileData("PlayerFacePic", onlyCheck)
        self.__LoadFileData("PlayerFacePicStar", onlyCheck)
        self.__LoadFileData("ChatBox", onlyCheck)
        self.__LoadFileData("SkillMatch", onlyCheck)
        self.__LoadFileData("RolePoint", onlyCheck)
        self.__LoadFileData("LingQiAttr", onlyCheck)
@@ -6483,8 +6453,6 @@
        self.__LoadFileData("ActWishingWell", onlyCheck)
        self.__LoadFileData("WishingWell", onlyCheck)
        self.__LoadFileData("FunctionForecast", onlyCheck)
        self.__LoadFileData("ChatBubbleBox", onlyCheck)
        self.__LoadFileData("ChatBubbleBoxStar", onlyCheck)
        self.__LoadFileData("EmojiPack", onlyCheck)
        self.__LoadFileData("ActRechargePrize", onlyCheck)
        self.__LoadFileData("RechargePrizeTemplate", onlyCheck)
@@ -6942,19 +6910,19 @@
        self.CheckLoadData("NPCLineup")
        return self.ipyNPCLineupCache[index]
    def GetDienstgradCount(self):
        self.CheckLoadData("Dienstgrad")
        return self.ipyDienstgradLen
    def GetDienstgradByIndex(self, index):
        self.CheckLoadData("Dienstgrad")
        return self.ipyDienstgradCache[index]
    def GetTitleCount(self):
        self.CheckLoadData("Title")
        return self.ipyTitleLen
    def GetTitleByIndex(self, index):
        self.CheckLoadData("Title")
        return self.ipyTitleCache[index]
    def GetTitleStarUpCount(self):
        self.CheckLoadData("TitleStarUp")
        return self.ipyTitleStarUpLen
    def GetTitleStarUpByIndex(self, index):
        self.CheckLoadData("TitleStarUp")
        return self.ipyTitleStarUpCache[index]
    def GetModelCount(self):
        self.CheckLoadData("Model")
        return self.ipyModelLen
    def GetModelByIndex(self, index):
        self.CheckLoadData("Model")
        return self.ipyModelCache[index]
    def GetPlayerFaceCount(self):
        self.CheckLoadData("PlayerFace")
@@ -6963,13 +6931,6 @@
        self.CheckLoadData("PlayerFace")
        return self.ipyPlayerFaceCache[index]
    def GetPlayerFaceStarCount(self):
        self.CheckLoadData("PlayerFaceStar")
        return self.ipyPlayerFaceStarLen
    def GetPlayerFaceStarByIndex(self, index):
        self.CheckLoadData("PlayerFaceStar")
        return self.ipyPlayerFaceStarCache[index]
    def GetPlayerFacePicCount(self):
        self.CheckLoadData("PlayerFacePic")
        return self.ipyPlayerFacePicLen
@@ -6977,12 +6938,12 @@
        self.CheckLoadData("PlayerFacePic")
        return self.ipyPlayerFacePicCache[index]
    def GetPlayerFacePicStarCount(self):
        self.CheckLoadData("PlayerFacePicStar")
        return self.ipyPlayerFacePicStarLen
    def GetPlayerFacePicStarByIndex(self, index):
        self.CheckLoadData("PlayerFacePicStar")
        return self.ipyPlayerFacePicStarCache[index]
    def GetChatBoxCount(self):
        self.CheckLoadData("ChatBox")
        return self.ipyChatBoxLen
    def GetChatBoxByIndex(self, index):
        self.CheckLoadData("ChatBox")
        return self.ipyChatBoxCache[index]
    def GetSkillMatchCount(self):
        self.CheckLoadData("SkillMatch")
@@ -7956,20 +7917,6 @@
    def GetFunctionForecastByIndex(self, index):
        self.CheckLoadData("FunctionForecast")
        return self.ipyFunctionForecastCache[index]
    def GetChatBubbleBoxCount(self):
        self.CheckLoadData("ChatBubbleBox")
        return self.ipyChatBubbleBoxLen
    def GetChatBubbleBoxByIndex(self, index):
        self.CheckLoadData("ChatBubbleBox")
        return self.ipyChatBubbleBoxCache[index]
    def GetChatBubbleBoxStarCount(self):
        self.CheckLoadData("ChatBubbleBoxStar")
        return self.ipyChatBubbleBoxStarLen
    def GetChatBubbleBoxStarByIndex(self, index):
        self.CheckLoadData("ChatBubbleBoxStar")
        return self.ipyChatBubbleBoxStarCache[index]
    def GetEmojiPackCount(self):
        self.CheckLoadData("EmojiPack")
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
@@ -596,9 +596,6 @@
    #根据物品效果使用{物品效果ID:call的py名}
    itemEffIdCallFuncDic = {
                            ChConfig.Def_Effect_UseItemGiveZhenQi:"Item_UseItemGiveZhenQi", # 使用道具给予真气
                            ChConfig.Def_Effect_AddDienstgrad:"Item_AddDienstgrad", #道具获得称号
                            ChConfig.Def_Effect_Face:"Item_Face",
                            ChConfig.Def_Effect_FacePic:"Item_Face",
                            ChConfig.Def_Effect_ItemAddLV:"Item_AddLV", #升级道具
                            ChConfig.Def_Effect_GuajiAward:"Item_GuajiAward", #直接给挂机收益
                            ChConfig.Def_Effect_CleanGuilt:"Item_CleanGuilt", # 洗红名
@@ -611,7 +608,6 @@
                            ChConfig.Def_Effect_AddFBCnt:"Item_AddFBCnt", # 增加副本可进入次数
                            ChConfig.Def_Effect_AddKillBossCnt:"Item_AddKillBossCnt", # 增加BOSS可击杀次数
                            ChConfig.Def_Effect_AddMagicWeaponUpExp:"Item_AddMagicWeaponUpExp", # 增加法宝升星经验
                            ChConfig.Def_Effect_ChatBubbleBox:"Item_ChatBubbleBox", # 激活聊天气泡框
                            ChConfig.Def_Effect_EmojiPack:"Item_EmojiPack",
                            ChConfig.Def_Effect_FamilyEmblem:"Item_FamilyEmblem",
                            ChConfig.Def_Effect_ItemGiveWeekPartyPoint:"Item_WeekPartyPoint", # 增加活动巡礼积分
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_AddDienstgrad.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_ChatBubbleBox.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_Face.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -49,7 +49,6 @@
import FBCommon
import PlayerWishingWell
import PlayerSuccess
import PlayerDienstgrad
import PlayerFreeGoods
import PlayerCrossRealmPK
import PlayerCrossChampionship
@@ -117,8 +116,6 @@
import PlayerLove
import GameObj
import PlayerChangeJob
import PlayerFace
import PlayerChatBox
import PlayerXiangong
import PlayerGoldRush
import PlayerActLoginNew
@@ -138,6 +135,7 @@
import PlayerHero
import PlayerOnline
import TurnAttack
import PlayerHJG
import ObjPool
import datetime
@@ -577,10 +575,6 @@
#    Sync_AutoFightSetting(curPlayer)
    
    PlayerFamily.OnPlayerLogin(curPlayer, tick)
    #改到 GameServerRefresh GameSever_PlayerInitOK后处理才能保证玩家已经在Gameserver注册
    #PlayerDienstgrad.RefreshBillBoardDienstgrad(curPlayer)
    # 称号
    PlayerDienstgrad.Sync_AllDienstgradOnLogin(curPlayer)
    
    # ʱװ
    PlayerCoat.OnLogin_Coat(curPlayer)
@@ -746,8 +740,7 @@
        PyMongoMain.GetUserCtrlDB().OnPlayerLogin(curPlayer)
        PlayerHero.OnPlayerLogin(curPlayer)
        PlayerMail.OnPlayerLogin(curPlayer)
        PlayerChatBox.OnPlayerLogin(curPlayer)
        PlayerFace.OnPlayerLogin(curPlayer)
        PlayerHJG.OnPlayerLogin(curPlayer)
        PlayerXiangong.OnPlayerLogin(curPlayer)
        PlayerGubao.OnPlayerLogin(curPlayer)
        PlayerShentong.OnPlayerLogin(curPlayer)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py
@@ -21,7 +21,6 @@
import base64
import ChConfig
import PyGameData
import PlayerDienstgrad
import IpyGameDataPY
import PlayerHorse
import PlayerPet
@@ -225,7 +224,6 @@
    PyGameData.g_crossRegPlayerAttrDict.pop(playerID, None)
    PyGameData.g_crossSyncTickDict.pop(playerID, None)
    PyGameData.g_crossPlayerDictChangeInfo.pop(playerID, None)
    PyGameData.g_crossPlayerDienstgradChangeInfo.pop(playerID, None)
    PyGameData.g_crossPlayerItemsChangeInfo.pop(playerID, None)
    PyGameData.g_crossPlayerSkillsChangeInfo.pop(playerID, None)
    GameWorld.DebugLog("清除同步跨服数据的临时缓存", playerID)
@@ -296,16 +294,6 @@
#    curItem2 = curPack.GetAt(2)
#    curItem2.AssignItem(curSingleItem)
#===============================================================================
def OnDienstgradChange(curPlayer, dienstgradID, state):
    ## 称号变更
    if not IsNeedProcessCrossPlayer(curPlayer):
        return
    playerID = curPlayer.GetPlayerID()
    dienstgradStateDict = PyGameData.g_crossPlayerDienstgradChangeInfo.get(playerID, {})
    dienstgradStateDict[dienstgradID] = state
    PyGameData.g_crossPlayerDienstgradChangeInfo[playerID] = dienstgradStateDict
    return
def OnPlayerFightPowerChange(curPlayer):
    ## 玩家战力变更时
@@ -347,7 +335,6 @@
        data = CommFunc.WriteBYTE(data, MergeData_Player)
        data = __WriteSyncPlayerAttrData(curPlayer, data) # 玩家属性
        data = __WriteSyncPlayerDictData(curPlayer, data) # 字典
        data = __WriteSyncPlayerDienstgradData(curPlayer, data) # 称号
        data = __WriteSyncPlayerItems(curPlayer, data)# 物品
        data = __WriteSyncPlayerSkills(curPlayer, data)# 技能
        
@@ -371,7 +358,6 @@
    
    pos = __ReadSyncPlayerAttrData(curPlayer, pdata, pos) # 玩家属性
    pos = __ReadSyncPlayerDictData(curPlayer, pdata, pos) # 字典
    pos = __ReadSyncPlayerDienstgradData(curPlayer, pdata, pos) # 称号
    pos = __ReadSyncPlayerItems(curPlayer, pdata, pos)  # 物品
    pos = __ReadSyncPlayerSkills(curPlayer, pdata, pos)# 技能
    
@@ -461,39 +447,6 @@
        PlayerControl.NomalDictSetProperty(curPlayer, key, value, dType)
        GameWorld.DebugLog("    key=%s, value=%s, dType=%s" % (key, value, dType))
        
    return pos
def __WriteSyncPlayerDienstgradData(curPlayer, data):
    ## 写入需要同步的玩家称号
    playerID = curPlayer.GetPlayerID()
    if playerID not in PyGameData.g_crossPlayerDienstgradChangeInfo:
        return CommFunc.WriteBYTE(data, 0)
    changeDienstgradDict = PyGameData.g_crossPlayerDienstgradChangeInfo.pop(playerID)
    count = len(changeDienstgradDict)
    GameWorld.DebugLog("变更的玩家称号个数: %s" % count)
    data = CommFunc.WriteBYTE(data, count)
    for dienstgradID, state in changeDienstgradDict.items():
        data = CommFunc.WriteDWORD(data, dienstgradID)
        data = CommFunc.WriteBYTE(data, state)
        GameWorld.DebugLog("    dienstgradID=%s, state=%s" % (dienstgradID, state))
    return data
def __ReadSyncPlayerDienstgradData(curPlayer, pdata, pos):
    ## 读取同步的玩家称号
    pdata = base64.b64decode(pdata)
    count, pos = CommFunc.ReadBYTE(pdata, pos)
    GameWorld.DebugLog("变更的玩家称号个数: %s" % count)
    for _ in xrange(count):
        dienstgradID, pos = CommFunc.ReadDWORD(pdata, pos)
        state, pos = CommFunc.ReadBYTE(pdata, pos)
        GameWorld.DebugLog("    dienstgradID=%s, state=%s" % (dienstgradID, state))
        if state:
            PlayerDienstgrad.PlayerAddDienstgrad(curPlayer, dienstgradID, isRefreshAttr=False)
        else:
            PlayerDienstgrad.PlayerDelDienstgrad(curPlayer, dienstgradID, False)
    return pos
def __WriteSyncPlayerItems(curPlayer, data):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameServerRefresh.py
@@ -110,9 +110,6 @@
        PlayerEventCounter.PlayerOnYear(curPlayer)
        Set_PlayerGameServerInitOK_OnYear(curPlayer, 0)
        
    #刷新排行榜称号
    #PlayerDienstgrad.RefreshBillBoardDienstgrad(curPlayer)
    GameWorld.Log('GameSever_PlayerInitOK' , curPlayer.GetID())
    ChPlayer.DoPlayerRealLoginOK(curPlayer, tick)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerChatBox.py
@@ -16,7 +16,7 @@
#-------------------------------------------------------------------------------
import GameWorld
import ShareDefine
import PlayerHJG
import PlayerControl
import IPY_GameWorld
import ChPyNetSendPack
@@ -24,25 +24,23 @@
import NetPackCommon
import ItemCommon
import ChConfig
import ObjPool
import time
def OnPlayerLogin(curPlayer):
    SyncChatBoxInfo(curPlayer)
    SyncEmojiPackInfo(curPlayer)
    #SyncEmojiPackInfo(curPlayer)
    return
def OnMinute(curPlayer):
    curTime = int(time.time())
    delBoxList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetChatBubbleBoxCount()):
        ipyData = ipyDataMgr.GetChatBubbleBoxByIndex(index)
    for index in range(ipyDataMgr.GetChatBoxCount()):
        ipyData = ipyDataMgr.GetChatBoxByIndex(index)
        boxID = ipyData.GetBoxID()
        if ipyData.GetUnlockDefault():
            # 默认激活的不处理
            continue
        if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBubbleBoxState, boxID):
        if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBoxState, boxID):
            # 未激活的不处理
            continue
        endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ChatBoxEndTime % boxID)
@@ -55,38 +53,51 @@
    if delBoxList:
        RefreshBoxAttr(curPlayer)
        
    # 表情包
    for index in range(ipyDataMgr.GetEmojiPackCount()):
        ipyData = ipyDataMgr.GetEmojiPackByIndex(index)
        packID = ipyData.GetEmojiPackID()
        if ipyData.GetUnlockDefault():
            # 默认激活的不处理
            continue
        if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_EmojiPackState, packID):
            # 未激活的不处理
            continue
        endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EmojiPackEndTime % packID)
        if not endTime or endTime > curTime:
            # 永久或未过期
            continue
        DelEmojiPack(curPlayer, packID, "EmojiPackTimeout")
#    # 表情包
#    for index in range(ipyDataMgr.GetEmojiPackCount()):
#        ipyData = ipyDataMgr.GetEmojiPackByIndex(index)
#        packID = ipyData.GetEmojiPackID()
#        if ipyData.GetUnlockDefault():
#            # 默认激活的不处理
#            continue
#        if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_EmojiPackState, packID):
#            # 未激活的不处理
#            continue
#        endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EmojiPackEndTime % packID)
#        if not endTime or endTime > curTime:
#            # 永久或未过期
#            continue
#        DelEmojiPack(curPlayer, packID, "EmojiPackTimeout")
        
    return
def AddChatBox(curPlayer, boxID, setExpireTimes=None):
def AddChatBox(curPlayer, boxID, setExpireTimes=None, isFree=False):
    if boxID <= 0:
        return
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("ChatBubbleBox", boxID)
    ipyData = IpyGameDataPY.GetIpyGameData("ChatBox", boxID)
    if not ipyData:
        return
    if ipyData.GetUnlockDefault():
        GameWorld.DebugLog("气泡框默认解锁的不用添加: boxID=%s" % (boxID), playerID)
    if ipyData.GetUnlockWay() != 2:
        GameWorld.DebugLog("非道具激活的不用添加: boxID=%s" % (boxID), playerID)
        return
    if not isFree:
        itemID = ipyData.GetUnlockValue()
        itemCount = ipyData.GetUnlockNeedCnt()
        if not itemID or not itemCount:
            return
        needItemList = [[itemID, itemCount]]
        itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
        lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
        if lackItemDict:
            GameWorld.DebugLog("激活所需物品不足! boxID=%s,lackItemDict=%s" % (boxID, lackItemDict), playerID)
            return
        ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "AddChatBox")
    ipyExpireSeconds = ipyData.GetExpireMinutes() * 60
    
    curTime = int(time.time())
    state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBubbleBoxState, boxID)
    state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBoxState, boxID)
    endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ChatBoxEndTime % boxID)
    GameWorld.Log("添加气泡框: boxID=%s,setExpireTimes=%s,state=%s,endTime=%s,ipyExpireSeconds=%s,curTime=%s" 
                  % (boxID, setExpireTimes, state, endTime, ipyExpireSeconds, curTime), playerID)
@@ -95,23 +106,23 @@
    # 指定时长的,如GM指定
    if setExpireTimes >= 0:
        updEndTime = curTime + setExpireTimes
        GameWorld.Log("    指定气泡框时长: boxID=%s,updEndTime=%s" % (boxID, updEndTime), playerID)
        GameWorld.Log("    指定时长: boxID=%s,updEndTime=%s" % (boxID, updEndTime), playerID)
        
    # 永久
    elif ipyExpireSeconds == 0:
        updEndTime = 0
        GameWorld.Log("    添加永久气泡框: boxID=%s,updEndTime=%s" % (boxID, updEndTime), playerID)
        GameWorld.Log("    永久时长: boxID=%s,updEndTime=%s" % (boxID, updEndTime), playerID)
        
    else:
        # 未过期
        if endTime > curTime:
            updEndTime = endTime + ipyExpireSeconds
            GameWorld.Log("    累加气泡框时长: boxID=%s,updEndTime=%s" % (boxID, updEndTime), playerID)
            GameWorld.Log("    累加时长: boxID=%s,updEndTime=%s" % (boxID, updEndTime), playerID)
        else:
            updEndTime = curTime + ipyExpireSeconds
            GameWorld.Log("    重新激活气泡框: boxID=%s,updEndTime=%s" % (boxID, updEndTime), playerID)
            GameWorld.Log("    重新激活: boxID=%s,updEndTime=%s" % (boxID, updEndTime), playerID)
            
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBubbleBoxState, boxID, 1)
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBoxState, boxID, 1)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChatBoxEndTime % boxID, updEndTime)
    RefreshBoxAttr(curPlayer)
    SyncChatBoxInfo(curPlayer, [boxID])
@@ -119,19 +130,19 @@
def DelChatBox(curPlayer, boxID, isRefreshAttr=True, notifyMail=""):
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("ChatBubbleBox", boxID)
    ipyData = IpyGameDataPY.GetIpyGameData("ChatBox", boxID)
    if not ipyData:
        return
    if ipyData.GetUnlockDefault():
    if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBoxState, boxID):
        return
    GameWorld.Log("删除玩家聊天气泡框: boxID=%s,notifyMail=%s" % (boxID, notifyMail), playerID)
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBubbleBoxState, boxID, 0)
    GameWorld.Log("删除气泡框: boxID=%s,notifyMail=%s" % (boxID, notifyMail), playerID)
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBoxState, boxID, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChatBoxEndTime % boxID, 0)
    # 星级不重置,重新激活后再次生效
    
    if PlayerControl.GetChatBubbleBox(curPlayer) == boxID:
    if PlayerControl.GetChatBox(curPlayer) == boxID:
        canUseID = GetCanUseBoxID(curPlayer)
        PlayerControl.SetChatBubbleBox(curPlayer, canUseID)
        PlayerControl.SetChatBox(curPlayer, canUseID)
        GameWorld.DebugLog("玩家聊天气泡框被删除,重新设置可用ID=%s" % canUseID, playerID)
        
    if isRefreshAttr:
@@ -144,8 +155,8 @@
def GetCanUseBoxID(curPlayer):
    ## 获取一个可用的气泡框
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetChatBubbleBoxCount())[::-1]:
        ipyData = ipyDataMgr.GetChatBubbleBoxByIndex(index)
    for index in range(ipyDataMgr.GetChatBoxCount())[::-1]:
        ipyData = ipyDataMgr.GetChatBoxByIndex(index)
        boxID = ipyData.GetBoxID()
        if IsBoxCanUse(curPlayer, boxID, ipyData):
            return boxID
@@ -153,141 +164,92 @@
def IsBoxCanUse(curPlayer, boxID, ipyData=None):
    ## 气泡框是否可用
    state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBubbleBoxState, boxID)
    state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBoxState, boxID)
    if state:
        return True
    
    if not ipyData:
        ipyData = IpyGameDataPY.GetIpyGameData("ChatBubbleBox", boxID)
        ipyData = IpyGameDataPY.GetIpyGameData("ChatBox", boxID)
    if ipyData:
        if ipyData.GetUnlockDefault():
            return True
        needLV = ipyData.GetNeedLV()
        if needLV and curPlayer.GetLV() < needLV:
            #GameWorld.DebugLog("    等级不足,无法使用该气泡框!needLV=%s" % needLV, curPlayer.GetPlayerID())
            return False
        if needLV:
        unlockWay = ipyData.GetUnlockWay()
        if unlockWay == 1: # 默认激活的
            return True
        
    return False
def RefreshBoxAttr(curPlayer):
    CalcBoxAttr(curPlayer)
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
    PlayerHJG.RefreshHJGAttr(curPlayer)
    return
def CalcBoxAttr(curPlayer):
    fightPowerEx = 0
    allAttrList = [{} for i in range(4)]
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetChatBubbleBoxCount()):
        ipyData = ipyDataMgr.GetChatBubbleBoxByIndex(index)
        boxID = ipyData.GetBoxID()
        if not IsBoxCanUse(curPlayer, boxID, ipyData):
            continue
        fightPowerEx += ipyData.GetLightFightPower()
        # 激活属性
        lightAttrType = ipyData.GetLightAttrType()
        lightAttrValue = ipyData.GetLightAttrValue()
        for i, attrID in enumerate(lightAttrType):
            attrValue = lightAttrValue[i]
            PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
        # 星级属性
        boxStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ChatBoxStar % boxID)
        starIpyData = IpyGameDataPY.GetIpyGameDataNotLog("ChatBubbleBoxStar", boxID, boxStar)
        if starIpyData:
            starAttrType = starIpyData.GetStarAttrType()
            starAttrValue = starIpyData.GetStarAttrValue()
            for i, attrID in enumerate(starAttrType):
                attrValue = starAttrValue[i]
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
    # 保存计算值
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_ChatBox, allAttrList)
    PlayerControl.SetMFPExFightPower(curPlayer, ShareDefine.Def_MFPType_ChatBox, fightPowerEx)
    return
#// A2 30 设置聊天气泡框 #tagCMSetChatBubbleBox
#
#struct    tagCMSetChatBubbleBox
#{
#    tagHead         Head;
#    BYTE        BubbleBoxType;    //气泡框类型
#};
def OnSetChatBubbleBox(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    useBoxID = clientData.BubbleBoxType
def OnUseChatBox(curPlayer, useBoxID):
    playerID = curPlayer.GetPlayerID()
    if not IsBoxCanUse(curPlayer, useBoxID):
        GameWorld.DebugLog("聊天气泡框不可用,无法设置! useBoxID=%s" % useBoxID, playerID)    
        return
    GameWorld.DebugLog("设置使用的聊天气泡框ID: useBoxID=%s" % useBoxID, playerID)    
    PlayerControl.SetChatBubbleBox(curPlayer, useBoxID)
    PlayerControl.SetChatBox(curPlayer, useBoxID)
    return
#// A2 36 聊天气泡框升星 #tagCMChatBubbleBoxStarUP
#
#struct    tagCMChatBubbleBoxStarUP
#{
#    tagHead         Head;
#    WORD        BoxID;    //气泡ID
#};
def OnChatBubbleBoxStarUP(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
def OnChatBoxStarUP(curPlayer, boxID):
    playerID = curPlayer.GetPlayerID()
    boxID = clientData.BoxID
    if not IsBoxCanUse(curPlayer, boxID):
        GameWorld.DebugLog("聊天气泡框不可用! boxID=%s" % (boxID), playerID)
        return
    curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ChatBoxStar % boxID)
    nextStar = curStar + 1
    nextIpyData = IpyGameDataPY.GetIpyGameData("ChatBubbleBoxStar", boxID, nextStar)
    if not nextIpyData:
        GameWorld.DebugLog("不存在该气泡框星级! boxID=%s,nextStar=%s" % (boxID, nextStar), playerID)
    ipyData = IpyGameDataPY.GetIpyGameData("ChatBox", boxID)
    if not ipyData:
        return
    needItemList = nextIpyData.GetStarUpNeedItemList()
    if not needItemList:
    starMax = ipyData.GetStarMax()
    curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ChatBoxStar % boxID)
    if curStar >= starMax:
        GameWorld.DebugLog("星级已满! boxID=%s,curStar=%s >= %s" % (boxID, curStar, starMax), playerID)
        return
    if ipyData.GetUnlockWay() != 2:
        return
    itemID = ipyData.GetUnlockValue()
    itemCount = ipyData.GetUnlockNeedCnt()
    if not itemID or not itemCount:
        return
    needItemList = [[itemID, itemCount]]
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
    if lackItemDict:
        GameWorld.DebugLog("气泡框升星所需物品不足! boxID=%s,nextStar=%s,needItemList=%s,lackItemDict=%s"
                           % (boxID, nextStar, needItemList, lackItemDict), playerID)
        GameWorld.DebugLog("升星所需物品不足! boxID=%s,lackItemDict=%s" % (boxID, lackItemDict), playerID)
        return
    ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "ChatBoxStarUP")
    
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChatBoxStar % boxID, nextStar)
    GameWorld.DebugLog("气泡框升星! boxID=%s,curStar=%s,nextStar=%s" % (boxID, curStar, nextStar), playerID)
    nextStar = curStar + 1
    GameWorld.DebugLog("升星! boxID=%s,nextStar=%s" % (boxID, nextStar), playerID)
    SetChatBoxStar(curPlayer, boxID, nextStar)
    return
def SetChatBoxStar(curPlayer, boxID, setStar):
    if not IsBoxCanUse(curPlayer, boxID):
        return
    ipyData = IpyGameDataPY.GetIpyGameData("ChatBox", boxID)
    if not ipyData:
        return
    setStar = min(setStar, ipyData.GetStarMax())
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChatBoxStar % boxID, setStar)
    RefreshBoxAttr(curPlayer)
    SyncChatBoxInfo(curPlayer, [boxID])
    return
    return True
def SyncChatBoxInfo(curPlayer, boxIDList=None):
    if boxIDList == None:
        syncIDList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetChatBubbleBoxCount()):
            ipyData = ipyDataMgr.GetChatBubbleBoxByIndex(index)
        for index in range(ipyDataMgr.GetChatBoxCount()):
            ipyData = ipyDataMgr.GetChatBoxByIndex(index)
            syncIDList.append(ipyData.GetBoxID())
    else:
        syncIDList = boxIDList
        
    boxList = []
    for boxID in syncIDList:
        state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBubbleBoxState, boxID)
        state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ChatBoxState, boxID)
        if not state and boxIDList == None:
            continue
        box = ChPyNetSendPack.tagMCChatBubbleBox()
        box = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCChatBox)
        box.BoxID = boxID
        box.State = state
        box.EndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ChatBoxEndTime % boxID)
@@ -297,7 +259,7 @@
    if not boxList:
        return
    
    clientPack = ChPyNetSendPack.tagMCChatBubbleBoxState()
    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCChatBoxInfo)
    clientPack.BoxList = boxList
    clientPack.Count = len(clientPack.BoxList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -4406,6 +4406,10 @@
    wave = value % 100
    return chapterID, levelNum, wave
## 获取佩戴的称号ID
def GetTitleID(curPlayer): return curPlayer.GetExAttr3()
def SetTitleID(curPlayer, titleID): curPlayer.SetExAttr3(titleID, False, False)
## 协助目标玩家ID
def GetAssistTagPlayerID(curPlayer): return 0
@@ -4414,12 +4418,9 @@
def SetTeamCheckState(curPlayer, checkState): return
## 副本功能线路ID, 这里做db存储,防止在合并地图副本中掉线重上时前端无法加载正确的场景资源,登录加载场景时机为0102包
def SetFBFuncLineID(curPlayer, mapID, funcLineID):
    value = mapID * 1000 + funcLineID
    if value != curPlayer.GetExAttr3():
        curPlayer.SetExAttr3(value, False, True)
    return
def GetFBFuncMapID(curPlayer): return curPlayer.GetExAttr3() / 1000
def GetFBFuncLineID(curPlayer): return curPlayer.GetExAttr3() % 1000
def GetFBFuncMapID(curPlayer): return 0
def GetFBFuncLineID(curPlayer): return 0
## 跨服状态所在地图ID: 0-非跨服状态,非0-跨服状态对应的地图ID
def GetCrossMapID(curPlayer): return curPlayer.GetExAttr5()
@@ -4449,8 +4450,8 @@
def SetVIPLVUpTime(curPlayer, lvUpTime): return
##聊天气泡框
def GetChatBubbleBox(curPlayer): return curPlayer.GetExAttr10()
def SetChatBubbleBox(curPlayer, value): return curPlayer.SetExAttr10(value, False, True)
def GetChatBox(curPlayer): return curPlayer.GetExAttr10()
def SetChatBox(curPlayer, value): return curPlayer.SetExAttr10(value, False, True)
##游戏充值支付代币
def GetPayCoinTotal(curPlayer): return GetPayCoin(curPlayer) + GetPlayerCurrency(curPlayer, ShareDefine.TYPE_Price_PayCoinDay)
@@ -4462,11 +4463,6 @@
    if payCoinDay > 0:
        PayMoney(curPlayer, ShareDefine.TYPE_Price_PayCoin, payCoinDay, "PayCoinOnDay")
    return
## 获取佩戴的称号ID
def GetTitleID(curPlayer):
    curDienstgradMgr = curPlayer.GetDienstgradManager()
    return curDienstgradMgr.GetCurGradID()
##伴侣
def GetCoupleID(curPlayer):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerDienstgrad.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFace.py
@@ -16,14 +16,16 @@
#-------------------------------------------------------------------------------
import GameWorld
import ShareDefine
import PlayerControl
import IPY_GameWorld
import ChPyNetSendPack
import IpyGameDataPY
import NetPackCommon
import ItemCommon
import PlayerHero
import PlayerHJG
import ChConfig
import ObjPool
import random
import time
@@ -41,12 +43,6 @@
    for index in range(ipyDataMgr.GetPlayerFaceCount()):
        ipyData = ipyDataMgr.GetPlayerFaceByIndex(index)
        faceID = ipyData.GetFaceID()
        if ipyData.GetUnlockDefault():
            # 默认激活的不处理
            continue
        if ipyData.GetCustomPlayerID():
            # 玩家定制的不处理
            continue
        if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FaceState, faceID):
            # 未激活的不处理
            continue
@@ -64,9 +60,6 @@
    for index in range(ipyDataMgr.GetPlayerFacePicCount()):
        ipyData = ipyDataMgr.GetPlayerFacePicByIndex(index)
        facePicID = ipyData.GetFacePicID()
        if ipyData.GetUnlockDefault():
            # 默认激活的不处理
            continue
        if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FacePicState, facePicID):
            # 未激活的不处理
            continue
@@ -81,19 +74,29 @@
        RefreshFacePicAttr(curPlayer)
    return
def AddFace(curPlayer, faceID, setExpireTimes=None):
def AddFace(curPlayer, faceID, setExpireTimes=None, isFree=False):
    if faceID <= 0:
        return
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("PlayerFace", faceID)
    if not ipyData:
        return
    if ipyData.GetUnlockDefault():
        GameWorld.DebugLog("默认解锁的头像不用添加: faceID=%s" % (faceID), playerID)
    if ipyData.GetUnlockWay() != 2:
        GameWorld.DebugLog("非道具激活的不用添加: faceID=%s" % (faceID), playerID)
        return
    if ipyData.GetCustomPlayerID():
        GameWorld.DebugLog("玩家定制的头像不用添加: faceID=%s" % (faceID), playerID)
        return
    if not isFree:
        itemID = ipyData.GetUnlockValue()
        itemCount = ipyData.GetUnlockNeedCnt()
        if not itemID or not itemCount:
            return
        needItemList = [[itemID, itemCount]]
        itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
        lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
        if lackItemDict:
            GameWorld.DebugLog("激活所需物品不足! faceID=%s,lackItemDict=%s" % (faceID, lackItemDict), playerID)
            return
        ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "AddFace")
    ipyExpireSeconds = ipyData.GetExpireMinutes() * 60
    
    curTime = int(time.time())
@@ -133,9 +136,7 @@
    ipyData = IpyGameDataPY.GetIpyGameData("PlayerFace", faceID)
    if not ipyData:
        return
    if ipyData.GetUnlockDefault():
        return
    if ipyData.GetCustomPlayerID():
    if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FaceState, faceID):
        return
    GameWorld.Log("删除头像: faceID=%s,notifyMail=%s" % (faceID, notifyMail), playerID)
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_FaceState, faceID, 0)
@@ -162,32 +163,143 @@
    for index in range(ipyDataMgr.GetPlayerFaceCount()):
        ipyData = ipyDataMgr.GetPlayerFaceByIndex(index)
        faceID = ipyData.GetFaceID()
        if not ipyData.GetUnlockDefault():
        if ipyData.GetUnlockWay() != 1:
            continue
        defaultFaceIDList.append(faceID)
    return defaultFaceIDList
def GetDefaultFacePicIDList():
    defaultFacePicIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetPlayerFacePicCount()):
        ipyData = ipyDataMgr.GetPlayerFacePicByIndex(index)
        facePicID = ipyData.GetFacePicID()
        if not ipyData.GetUnlockDefault():
            continue
        defaultFacePicIDList.append(facePicID)
    return defaultFacePicIDList
def IsFaceCanUse(curPlayer, faceID, ipyData=None):
    ## 头像是否可用
    state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FaceState, faceID)
    if state:
        return True
    if not ipyData:
        ipyData = IpyGameDataPY.GetIpyGameData("PlayerFace", faceID)
    if ipyData:
        unlockWay = ipyData.GetUnlockWay()
        unlockValue = ipyData.GetUnlockValue()
        if unlockWay == 1: # 默认激活的
            return True
        if unlockWay == 3: # 关联武将
            heroID = unlockValue
            return True if PlayerHero.GetHeroActivite(curPlayer, heroID) else False
    return False
def AddFacePic(curPlayer, facePicID, setExpireTimes=None):
def RefreshFaceAttr(curPlayer):
    PlayerHJG.RefreshHJGAttr(curPlayer)
    return
def OnUseFace(curPlayer, faceID):
    playerID = curPlayer.GetPlayerID()
    if not IsFaceCanUse(curPlayer, faceID):
        GameWorld.DebugLog("该头像不可用! faceID=%s" % (faceID), playerID)
        return
    GameWorld.DebugLog("头像幻化! faceID=%s" % (faceID), playerID)
    curPlayer.SetFace(faceID)
    return
def OnFaceStarUP(curPlayer, faceID):
    playerID = curPlayer.GetPlayerID()
    if not IsFaceCanUse(curPlayer, faceID):
        GameWorld.DebugLog("该头像不可用! faceID=%s" % (faceID), playerID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("PlayerFace", faceID)
    if not ipyData:
        return
    starMax = ipyData.GetStarMax()
    curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceStar % faceID)
    if curStar >= starMax:
        GameWorld.DebugLog("头像星级已满! faceID=%s,curStar=%s >= %s" % (faceID, curStar, starMax), playerID)
        return
    if ipyData.GetUnlockWay() != 2:
        return
    itemID = ipyData.GetUnlockValue()
    itemCount = ipyData.GetUnlockNeedCnt()
    if not itemID or not itemCount:
        return
    needItemList = [[itemID, itemCount]]
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
    if lackItemDict:
        GameWorld.DebugLog("头像升星所需物品不足! faceID=%s,lackItemDict=%s" % (faceID, lackItemDict), playerID)
        return
    ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "FaceStarUP")
    nextStar = curStar + 1
    GameWorld.DebugLog("头像升星! faceID=%s,nextStar=%s" % (faceID, nextStar), playerID)
    SetFaceStar(curPlayer, faceID, nextStar)
    return
def SetFaceStar(curPlayer, faceID, setStar):
    if not IsFaceCanUse(curPlayer, faceID):
        return
    ipyData = IpyGameDataPY.GetIpyGameData("PlayerFace", faceID)
    if not ipyData:
        return
    setStar = min(setStar, ipyData.GetStarMax())
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FaceStar % faceID, setStar)
    RefreshFaceAttr(curPlayer)
    SyncFaceInfo(curPlayer, [faceID])
    return True
def SyncFaceInfo(curPlayer, faceIDList=None):
    if faceIDList == None:
        syncIDList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetPlayerFaceCount()):
            ipyData = ipyDataMgr.GetPlayerFaceByIndex(index)
            syncIDList.append(ipyData.GetFaceID())
    else:
        syncIDList = faceIDList
    faceList = []
    for faceID in syncIDList:
        state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FaceState, faceID)
        if not state and faceIDList == None:
            continue
        face = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCFace)
        face.FaceID = faceID
        face.State = state
        face.EndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceEndTime % faceID)
        face.Star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceStar % faceID)
        faceList.append(face)
    if not faceList:
        return
    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCFaceInfo)
    clientPack.FaceList = faceList
    clientPack.Count = len(clientPack.FaceList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
## ------------------------------------------------------------------------------------------------
def AddFacePic(curPlayer, facePicID, setExpireTimes=None, isFree=False):
    if facePicID <= 0:
        return
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("PlayerFacePic", facePicID)
    if not ipyData:
        return
    if ipyData.GetUnlockDefault():
        GameWorld.DebugLog("默认解锁的头像框不用添加: facePicID=%s" % (facePicID), playerID)
    if ipyData.GetUnlockWay() != 2:
        GameWorld.DebugLog("非道具激活的不用添加: facePicID=%s" % (facePicID), playerID)
        return
    if not isFree:
        itemID = ipyData.GetUnlockValue()
        itemCount = ipyData.GetUnlockNeedCnt()
        if not itemID or not itemCount:
            return
        needItemList = [[itemID, itemCount]]
        itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
        lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
        if lackItemDict:
            GameWorld.DebugLog("激活所需物品不足! facePicID=%s,lackItemDict=%s" % (facePicID, lackItemDict), playerID)
            return
        ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "AddFacePic")
    ipyExpireSeconds = ipyData.GetExpireMinutes() * 60
    
    curTime = int(time.time())
@@ -227,7 +339,7 @@
    ipyData = IpyGameDataPY.GetIpyGameData("PlayerFacePic", facePicID)
    if not ipyData:
        return
    if ipyData.GetUnlockDefault():
    if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FacePicState, facePicID):
        return
    GameWorld.Log("删除头像框: facePicID=%s,notifyMail=%s" % (facePicID, notifyMail), playerID)
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_FacePicState, facePicID, 0)
@@ -247,21 +359,16 @@
        PlayerControl.SendMailByKey(notifyMail, [playerID], [], [facePicID])
    return True
def IsFaceCanUse(curPlayer, faceID, ipyData=None):
    ## 头像是否可用
    state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FaceState, faceID)
    if state:
        return True
    if not ipyData:
        ipyData = IpyGameDataPY.GetIpyGameData("PlayerFace", faceID)
    if ipyData:
        if ipyData.GetUnlockDefault():
            return True
        if ipyData.GetCustomPlayerID() and ipyData.GetCustomPlayerID() == curPlayer.GetPlayerID():
            return True
    return False
def GetDefaultFacePicIDList():
    defaultFacePicIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetPlayerFacePicCount()):
        ipyData = ipyDataMgr.GetPlayerFacePicByIndex(index)
        facePicID = ipyData.GetFacePicID()
        if ipyData.GetUnlockWay() != 1:
            continue
        defaultFacePicIDList.append(facePicID)
    return defaultFacePicIDList
def IsFacePicCanUse(curPlayer, facePicID, ipyData=None):
    ## 头像框是否可用
@@ -272,188 +379,18 @@
    if not ipyData:
        ipyData = IpyGameDataPY.GetIpyGameData("PlayerFacePic", facePicID)
    if ipyData:
        if ipyData.GetUnlockDefault():
        unlockWay = ipyData.GetUnlockWay()
        if unlockWay == 1: # 默认激活的
            return True
        
    return False
def RefreshFaceAttr(curPlayer):
    CalcFaceAttr(curPlayer)
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
    return
def RefreshFacePicAttr(curPlayer):
    CalcFacePicAttr(curPlayer)
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
    PlayerHJG.RefreshHJGAttr(curPlayer)
    return
def CalcFaceAttr(curPlayer):
    ## 计算头像属性
    fightPowerEx = 0
    allAttrList = [{} for i in range(4)]
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetPlayerFaceCount()):
        ipyData = ipyDataMgr.GetPlayerFaceByIndex(index)
        faceID = ipyData.GetFaceID()
        if not IsFaceCanUse(curPlayer, faceID, ipyData):
            continue
        fightPowerEx += ipyData.GetLightFightPower()
        # 激活属性
        lightAttrType = ipyData.GetLightAttrType()
        lightAttrValue = ipyData.GetLightAttrValue()
        for i, attrID in enumerate(lightAttrType):
            attrValue = lightAttrValue[i]
            PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
        # 星级属性
        faceStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceStar % faceID)
        starIpyData = IpyGameDataPY.GetIpyGameDataNotLog("PlayerFaceStar", faceID, faceStar)
        if starIpyData:
            starAttrType = starIpyData.GetStarAttrType()
            starAttrValue = starIpyData.GetStarAttrValue()
            for i, attrID in enumerate(starAttrType):
                attrValue = starAttrValue[i]
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
    # 保存计算值
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Face, allAttrList)
    PlayerControl.SetMFPExFightPower(curPlayer, ShareDefine.Def_MFPType_Face, fightPowerEx)
    return
def CalcFacePicAttr(curPlayer):
    ## 计算头像框属性
    fightPowerEx = 0
    allAttrList = [{} for _ in range(4)]
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetPlayerFacePicCount()):
        ipyData = ipyDataMgr.GetPlayerFacePicByIndex(index)
        facePicID = ipyData.GetFacePicID()
        if not IsFacePicCanUse(curPlayer, facePicID, ipyData):
            continue
        fightPowerEx += ipyData.GetLightFightPower()
        # 激活属性
        lightAttrType = ipyData.GetLightAttrType()
        lightAttrValue = ipyData.GetLightAttrValue()
        for i, attrID in enumerate(lightAttrType):
            attrValue = lightAttrValue[i]
            PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
        # 星级属性
        facePicStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FacePicStar % facePicID)
        starIpyData = IpyGameDataPY.GetIpyGameDataNotLog("PlayerFacePicStar", facePicID, facePicStar)
        if starIpyData:
            starAttrType = starIpyData.GetStarAttrType()
            starAttrValue = starIpyData.GetStarAttrValue()
            for i, attrID in enumerate(starAttrType):
                attrValue = starAttrValue[i]
                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
    # 保存计算值
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_FacePic, allAttrList)
    PlayerControl.SetMFPExFightPower(curPlayer, ShareDefine.Def_MFPType_FacePic, fightPowerEx)
    return
#// B2 26 头像幻化 #tagCMFaceChange
#
#struct    tagCMFaceChange
#{
#    tagHead        Head;
#    DWORD        FaceID;    // 幻化的ID
#};
def OnFaceChange(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
def OnUseFacePic(curPlayer, facePicID):
    playerID = curPlayer.GetPlayerID()
    faceID = clientData.FaceID
    if not IsFaceCanUse(curPlayer, faceID):
        GameWorld.DebugLog("该头像不可用! faceID=%s" % (faceID), playerID)
        return
    GameWorld.DebugLog("头像幻化! faceID=%s" % (faceID), playerID)
    curPlayer.SetFace(faceID)
    return
#// B2 27 头像升星 #tagCMFaceStarUP
#
#struct    tagCMFaceStarUP
#{
#    tagHead        Head;
#    DWORD        FaceID;
#};
def OnFaceStarUP(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    faceID = clientData.FaceID
    if not IsFaceCanUse(curPlayer, faceID):
        GameWorld.DebugLog("该头像不可用! faceID=%s" % (faceID), playerID)
        return
    curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceStar % faceID)
    nextStar = curStar + 1
    nextIpyData = IpyGameDataPY.GetIpyGameData("PlayerFaceStar", faceID, nextStar)
    if not nextIpyData:
        GameWorld.DebugLog("不存在该头像星级! faceID=%s,nextStar=%s" % (faceID, nextStar), playerID)
        return
    needItemList = nextIpyData.GetStarUpNeedItemList()
    if not needItemList:
        return
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
    if lackItemDict:
        GameWorld.DebugLog("头像升星所需物品不足! faceID=%s,nextStar=%s,needItemList=%s,lackItemDict=%s"
                           % (faceID, nextStar, needItemList, lackItemDict), playerID)
        return
    ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "FaceStarUP")
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FaceStar % faceID, nextStar)
    GameWorld.DebugLog("头像升星! faceID=%s,curStar=%s,nextStar=%s" % (faceID, curStar, nextStar), playerID)
    RefreshFaceAttr(curPlayer)
    SyncFaceInfo(curPlayer, [faceID])
    return
def GMSetFaceStar(curPlayer, faceID, setValue=None):
    ## GM设置星级
    if not IsFaceCanUse(curPlayer, faceID):
        return False, "The player has not activated the faceID(%s)" % faceID
    if setValue == None:
        curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceStar % faceID)
        setStar = curStar + 1 # 没指定星级时默认升星
    else:
        setStar = setValue
    if setStar > 0:
        if not IpyGameDataPY.GetIpyGameData("PlayerFaceStar", faceID, setStar):
            return False, "The faceID(%s) star(%s) is not exist." % (faceID, setStar)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FaceStar % faceID, setStar)
    GameWorld.Log("GM设置头像星级: faceID=%s,setStar=%s" % (faceID, setStar), curPlayer.GetPlayerID())
    RefreshFaceAttr(curPlayer)
    SyncFaceInfo(curPlayer, [faceID])
    return True, ""
#// B2 28 头像框幻化 #tagCMFacePicChange
#
#struct    tagCMFacePicChange
#{
#    tagHead        Head;
#    DWORD        FacePicID;    // 幻化的ID
#};
def OnFacePicChange(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    facePicID = clientData.FacePicID
    if not IsFacePicCanUse(curPlayer, facePicID):
        GameWorld.DebugLog("该头像框不可用! facePicID=%s" % (facePicID), playerID)
        return    
@@ -461,100 +398,49 @@
    curPlayer.SetFacePic(facePicID)
    return
#// B2 29 头像框升星 #tagCMFacePicStarUP
#
#struct    tagCMFacePicStarUP
#{
#    tagHead        Head;
#    DWORD        FacePicID;
#};
def OnFacePicStarUP(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
def OnFacePicStarUP(curPlayer, facePicID):
    playerID = curPlayer.GetPlayerID()
    facePicID = clientData.FacePicID
    if not IsFacePicCanUse(curPlayer, facePicID):
        GameWorld.DebugLog("该头像框不可用! facePicID=%s" % (facePicID), playerID)
        return
    curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FacePicStar % facePicID)
    nextStar = curStar + 1
    nextIpyData = IpyGameDataPY.GetIpyGameData("PlayerFacePicStar", facePicID, nextStar)
    if not nextIpyData:
        GameWorld.DebugLog("不存在该头像框星级! facePicID=%s,nextStar=%s" % (facePicID, nextStar), playerID)
    ipyData = IpyGameDataPY.GetIpyGameData("PlayerFacePic", facePicID)
    if not ipyData:
        return
    needItemList = nextIpyData.GetStarUpNeedItemList()
    if not needItemList:
    starMax = ipyData.GetStarMax()
    curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FacePicStar % facePicID)
    if curStar >= starMax:
        GameWorld.DebugLog("头像框星级已满! facePicID=%s,curStar=%s >= %s" % (facePicID, curStar, starMax), playerID)
        return
    if ipyData.GetUnlockWay() != 2:
        return
    itemID = ipyData.GetUnlockValue()
    itemCount = ipyData.GetUnlockNeedCnt()
    if not itemID or not itemCount:
        return
    needItemList = [[itemID, itemCount]]
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
    if lackItemDict:
        GameWorld.DebugLog("头像框升星所需物品不足! facePicID=%s,nextStar=%s,needItemList=%s,lackItemDict=%s"
                           % (facePicID, nextStar, needItemList, lackItemDict), playerID)
        GameWorld.DebugLog("头像框升星所需物品不足! facePicID=%s,lackItemDict=%s" % (facePicID, lackItemDict), playerID)
        return
    ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "FacePicStarUP")
    
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FacePicStar % facePicID, nextStar)
    GameWorld.DebugLog("头像框升星! facePicID=%s,curStar=%s,nextStar=%s" % (facePicID, curStar, nextStar), playerID)
    RefreshFacePicAttr(curPlayer)
    SyncFacePicInfo(curPlayer, [facePicID])
    nextStar = curStar + 1
    GameWorld.DebugLog("头像框升星! facePicID=%s,nextStar=%s" % (facePicID, nextStar), playerID)
    SetFacePicStar(curPlayer, facePicID, nextStar)
    return
def GMSetFacePicStar(curPlayer, facePicID, setValue=None):
    ## GM设置星级
def SetFacePicStar(curPlayer, facePicID, setStar):
    if not IsFacePicCanUse(curPlayer, facePicID):
        return False, "The player has not activated the facePicID(%s)" % facePicID
    if setValue == None:
        curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FacePicStar % facePicID)
        setStar = curStar + 1 # 没指定星级时默认升星
    else:
        setStar = setValue
    if setStar > 0:
        if not IpyGameDataPY.GetIpyGameData("PlayerFacePicStar", facePicID, setStar):
            return False, "The setStar(%s) star(%s) is not exist." % (setStar, setStar)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("PlayerFacePic", facePicID)
    if not ipyData:
        return
    setStar = min(setStar, ipyData.GetStarMax())
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FacePicStar % facePicID, setStar)
    GameWorld.Log("GM设置头像框星级: facePicID=%s,setStar=%s" % (facePicID, setStar), curPlayer.GetPlayerID())
    RefreshFacePicAttr(curPlayer)
    SyncFacePicInfo(curPlayer, [facePicID])
    return True, ""
def SyncFaceInfo(curPlayer, faceIDList=None):
    if faceIDList == None:
        syncIDList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetPlayerFaceCount()):
            ipyData = ipyDataMgr.GetPlayerFaceByIndex(index)
            syncIDList.append(ipyData.GetFaceID())
    else:
        syncIDList = faceIDList
    faceList = []
    for faceID in syncIDList:
        state = 1 if IsFaceCanUse(curPlayer, faceID) else 0
        if not state and faceIDList == None:
            continue
        face = ChPyNetSendPack.tagMCFace()
        face.FaceID = faceID
        face.State = state
        face.EndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceEndTime % faceID)
        face.Star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceStar % faceID)
        faceList.append(face)
    if not faceList:
        return
    clientPack = ChPyNetSendPack.tagMCFaceInfo()
    clientPack.FaceList = faceList
    clientPack.Count = len(clientPack.FaceList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
    return True
def SyncFacePicInfo(curPlayer, facePicIDList=None):
    if facePicIDList == None:
@@ -571,7 +457,7 @@
        state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FacePicState, facePicID)
        if not state and facePicIDList == None:
            continue
        facePic = ChPyNetSendPack.tagMCFacePic()
        facePic = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCFacePic)
        facePic.FacePicID = facePicID
        facePic.State = state
        facePic.EndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FacePicEndTime % facePicID)
@@ -581,7 +467,7 @@
    if not facePicList:
        return
    
    clientPack = ChPyNetSendPack.tagMCFacePicInfo()
    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCFacePicInfo)
    clientPack.FacePicList = facePicList
    clientPack.Count = len(clientPack.FacePicList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHJG.py
New file
@@ -0,0 +1,684 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.PlayerHJG
#
# @todo:幻境阁
# @author hxp
# @date 2025-10-15
# @version 1.0
#
# 详细描述: 幻境阁(管理 形象、头像、头像框、气泡、称号)
#
#-------------------------------------------------------------------------------
#"""Version = 2025-10-15 09:30"""
#-------------------------------------------------------------------------------
import GameWorld
import ItemCommon
import PlayerOnline
import PlayerChatBox
import PlayerControl
import IpyGameDataPY
import ChPyNetSendPack
import IPY_GameWorld
import NetPackCommon
import PlayerFace
import PlayerHero
import ChConfig
import ObjPool
import random
import time
HJGType_Model = 1
HJGType_Face = 2
HJGType_FacePic = 3
HJGType_ChatBox = 4
HJGType_Title = 5
def OnPlayerLogin(curPlayer):
    SyncTitleInfo(curPlayer)
    SyncModelInfo(curPlayer)
    PlayerFace.OnPlayerLogin(curPlayer)
    PlayerChatBox.OnPlayerLogin(curPlayer)
    return
def OnMinute(curPlayer):
    OnMinuteTitle(curPlayer)
    OnMinuteModel(curPlayer)
    PlayerFace.OnMinute(curPlayer)
    PlayerChatBox.OnMinute(curPlayer)
    return
#// B2 25 幻境阁操作 #tagCSHJGOP
#
#struct    tagCSHJGOP
#{
#    tagHead         Head;
#    BYTE        Type;    // 类型 1-形象;2-头像;3-头像框;4-气泡;5-称号
#    BYTE        OPType;    // 操作 1-激活;2-佩戴;3-卸下;4-升星
#    DWORD        OPID;    // 操作对应的ID,如形象ID等
#};
def OnHJGOP(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    hjgType = clientData.Type
    opType = clientData.OPType
    opID = clientData.OPID
    # 激活
    if opType == 1:
        OnHJGActivate(curPlayer, hjgType, opID)
    # 佩戴
    elif opType == 2:
        OnHJGUse(curPlayer, hjgType, opID)
    # 卸下
    elif opType == 3:
        # 暂仅称号支持卸下
        if hjgType == HJGType_Title:
            OnTakeOffTitle(curPlayer, opID)
    # 升级
    elif opType == 4:
        OnHJGStarUP(curPlayer, hjgType, opID)
    return
def OnHJGActivate(curPlayer, hjgType, opID):
    ## 幻境阁激活
    if hjgType == HJGType_Model:
        AddModel(curPlayer, opID)
    elif hjgType == HJGType_Face:
        PlayerFace.AddFace(curPlayer, opID)
    elif hjgType == HJGType_FacePic:
        PlayerFace.AddFacePic(curPlayer, opID)
    elif hjgType == HJGType_ChatBox:
        PlayerChatBox.AddChatBox(curPlayer, opID)
    elif hjgType == HJGType_Title:
        AddTitle(curPlayer, opID)
    return
def OnHJGUse(curPlayer, hjgType, opID):
    ## 幻境阁使用/佩戴
    if hjgType == HJGType_Model:
        OnUseModel(curPlayer, opID)
    elif hjgType == HJGType_Face:
        PlayerFace.OnUseFace(curPlayer, opID)
    elif hjgType == HJGType_FacePic:
        PlayerFace.OnUseFacePic(curPlayer, opID)
    elif hjgType == HJGType_ChatBox:
        PlayerChatBox.OnUseChatBox(curPlayer, opID)
    elif hjgType == HJGType_Title:
        OnUseTitle(curPlayer, opID)
    return
def OnHJGStarUP(curPlayer, hjgType, opID):
    ## 幻境阁升星
    if hjgType == HJGType_Model:
        OnModelStarUP(curPlayer, opID)
    elif hjgType == HJGType_Face:
        PlayerFace.OnFaceStarUP(curPlayer, opID)
    elif hjgType == HJGType_FacePic:
        PlayerFace.OnFacePicStarUP(curPlayer, opID)
    elif hjgType == HJGType_ChatBox:
        PlayerChatBox.OnChatBoxStarUP(curPlayer, opID)
    elif hjgType == HJGType_Title:
        OnTitleStarUP(curPlayer, opID)
    return
def RefreshHJGAttr(curPlayer):
    CalcHJGAttr(curPlayer)
    PlayerOnline.GetOnlinePlayer(curPlayer).RefreshRoleAttr()
    return
def CalcHJGAttr(curPlayer):
    playerID = curPlayer.GetPlayerID()
    attrDict = {}
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    # 称号
    for index in range(ipyDataMgr.GetTitleCount()):
        ipyData = ipyDataMgr.GetTitleByIndex(index)
        titleID = ipyData.GetTitleID()
        if not IsTitleCanUse(curPlayer, titleID, ipyData):
            continue
        attrIDList = ipyData.GetAttrIDList()
        if not attrIDList:
            continue
        initAttrValueList = ipyData.GetInitAttrValueList()
        perStarAddList = ipyData.GetAttrPerStarAddList()
        star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TitleStar % titleID)
        for aIndex, attrID in enumerate(attrIDList):
            initValue = initAttrValueList[aIndex] if len(initAttrValueList) > aIndex else 0
            perStarAdd = perStarAddList[aIndex] if len(perStarAddList) > aIndex else 0
            attrValue = initValue + perStarAdd * star
            attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
    #GameWorld.DebugLog("幻境阁累加称号,总属性: %s" % attrDict)
    # 形象
    for index in range(ipyDataMgr.GetModelCount()):
        ipyData = ipyDataMgr.GetModelByIndex(index)
        modelID = ipyData.GetModelID()
        if not IsModelCanUse(curPlayer, modelID, ipyData):
            continue
        attrIDList = ipyData.GetAttrIDList()
        if not attrIDList:
            continue
        initAttrValueList = ipyData.GetInitAttrValueList()
        perStarAddList = ipyData.GetAttrPerStarAddList()
        star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ModelStar % modelID)
        for aIndex, attrID in enumerate(attrIDList):
            initValue = initAttrValueList[aIndex] if len(initAttrValueList) > aIndex else 0
            perStarAdd = perStarAddList[aIndex] if len(perStarAddList) > aIndex else 0
            attrValue = initValue + perStarAdd * star
            attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
    #GameWorld.DebugLog("幻境阁累加形象,总属性: %s" % attrDict)
    # 头像
    for index in range(ipyDataMgr.GetPlayerFaceCount()):
        ipyData = ipyDataMgr.GetPlayerFaceByIndex(index)
        faceID = ipyData.GetFaceID()
        if not PlayerFace.IsFaceCanUse(curPlayer, faceID, ipyData):
            continue
        attrIDList = ipyData.GetAttrIDList()
        if not attrIDList:
            continue
        initAttrValueList = ipyData.GetInitAttrValueList()
        perStarAddList = ipyData.GetAttrPerStarAddList()
        star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceStar % faceID)
        for aIndex, attrID in enumerate(attrIDList):
            initValue = initAttrValueList[aIndex] if len(initAttrValueList) > aIndex else 0
            perStarAdd = perStarAddList[aIndex] if len(perStarAddList) > aIndex else 0
            attrValue = initValue + perStarAdd * star
            attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
    #GameWorld.DebugLog("幻境阁累加头像,总属性: %s" % attrDict)
    # 头像框
    for index in range(ipyDataMgr.GetPlayerFacePicCount()):
        ipyData = ipyDataMgr.GetPlayerFacePicByIndex(index)
        facePicID = ipyData.GetFacePicID()
        if not PlayerFace.IsFacePicCanUse(curPlayer, facePicID, ipyData):
            continue
        attrIDList = ipyData.GetAttrIDList()
        if not attrIDList:
            continue
        initAttrValueList = ipyData.GetInitAttrValueList()
        perStarAddList = ipyData.GetAttrPerStarAddList()
        star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FacePicStar % facePicID)
        for aIndex, attrID in enumerate(attrIDList):
            initValue = initAttrValueList[aIndex] if len(initAttrValueList) > aIndex else 0
            perStarAdd = perStarAddList[aIndex] if len(perStarAddList) > aIndex else 0
            attrValue = initValue + perStarAdd * star
            attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
    #GameWorld.DebugLog("幻境阁累加头框,总属性: %s" % attrDict)
    # 气泡框
    for index in range(ipyDataMgr.GetChatBoxCount()):
        ipyData = ipyDataMgr.GetChatBoxByIndex(index)
        boxID = ipyData.GetBoxID()
        if not PlayerChatBox.IsBoxCanUse(curPlayer, boxID, ipyData):
            continue
        attrIDList = ipyData.GetAttrIDList()
        if not attrIDList:
            continue
        initAttrValueList = ipyData.GetInitAttrValueList()
        perStarAddList = ipyData.GetAttrPerStarAddList()
        star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ChatBoxStar % boxID)
        for aIndex, attrID in enumerate(attrIDList):
            initValue = initAttrValueList[aIndex] if len(initAttrValueList) > aIndex else 0
            perStarAdd = perStarAddList[aIndex] if len(perStarAddList) > aIndex else 0
            attrValue = initValue + perStarAdd * star
            attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
    #GameWorld.DebugLog("幻境阁累加气泡,总属性: %s" % attrDict)
    # 保存计算值
    GameWorld.DebugLog("幻境阁属性: %s" % attrDict, playerID)
    PlayerOnline.GetOnlinePlayer(curPlayer).SetCalcAttr(ChConfig.Def_CalcAttr_HJG, attrDict)
    return
## ----------------------------------------- 称号 --------------------------------------------------
def OnMinuteTitle(curPlayer):
    curTime = int(time.time())
    delIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetTitleCount()):
        ipyData = ipyDataMgr.GetTitleByIndex(index)
        titleID = ipyData.GetTitleID()
        if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, titleID):
            # 未激活的不处理
            continue
        endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TitleEndTime % titleID)
        if not endTime or endTime > curTime:
            # 永久或未过期
            continue
        if DelTitle(curPlayer, titleID, False, "TitleTimeout"):
            delIDList.append(titleID)
    if delIDList:
        RefreshHJGAttr(curPlayer)
    return
def AddTitle(curPlayer, titleID, setExpireTimes=None, isFree=False):
    if titleID <= 0:
        return
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("Title", titleID)
    if not ipyData:
        return
    if ipyData.GetUnlockWay() != 2:
        GameWorld.DebugLog("非道具激活的不用添加: titleID=%s" % (titleID), playerID)
        return
    if not isFree:
        itemID = ipyData.GetUnlockValue()
        itemCount = ipyData.GetUnlockNeedCnt()
        if not itemID or not itemCount:
            return
        needItemList = [[itemID, itemCount]]
        itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
        lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
        if lackItemDict:
            GameWorld.DebugLog("激活所需物品不足! titleID=%s,lackItemDict=%s" % (titleID, lackItemDict), playerID)
            return
        ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "AddTitle")
    ipyExpireSeconds = ipyData.GetExpireMinutes() * 60
    curTime = int(time.time())
    state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, titleID)
    endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TitleEndTime % titleID)
    GameWorld.Log("添加称号: titleID=%s,setExpireTimes=%s,state=%s,endTime=%s,ipyExpireSeconds=%s,curTime=%s"
                  % (titleID, setExpireTimes, state, endTime, ipyExpireSeconds, curTime), playerID)
    updEndTime = endTime
    # 指定时长的,如GM指定
    if setExpireTimes > 0:
        updEndTime = curTime + setExpireTimes
        GameWorld.Log("    指定时长: titleID=%s,updEndTime=%s" % (titleID, updEndTime), playerID)
    # 永久
    elif ipyExpireSeconds == 0 or setExpireTimes == 0:
        updEndTime = 0
        GameWorld.Log("    永久时长: titleID=%s,updEndTime=%s" % (titleID, updEndTime), playerID)
    else:
        # 未过期
        if endTime > curTime:
            updEndTime = endTime + ipyExpireSeconds
            GameWorld.Log("    累加时长: titleID=%s,updEndTime=%s" % (titleID, updEndTime), playerID)
        else:
            updEndTime = curTime + ipyExpireSeconds
            GameWorld.Log("    重新激活: titleID=%s,updEndTime=%s" % (titleID, updEndTime), playerID)
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, titleID, 1)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TitleEndTime % titleID, updEndTime)
    RefreshHJGAttr(curPlayer)
    SyncTitleInfo(curPlayer, [titleID])
    return True
def DelTitle(curPlayer, titleID, isRefreshAttr=True, notifyMail=""):
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("Title", titleID)
    if not ipyData:
        return
    if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, titleID):
        return
    GameWorld.Log("删除称号: titleID=%s,notifyMail=%s" % (titleID, notifyMail), playerID)
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, titleID, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TitleEndTime % titleID, 0)
    # 星级不重置,重新激活后再次生效
    if PlayerControl.GetTitleID(curPlayer) == titleID:
        defaultIDList = GetDefaultTitleIDList()
        randID = random.choice(defaultIDList) if defaultIDList else 0
        PlayerControl.SetTitleID(curPlayer, randID)
        GameWorld.DebugLog("玩家佩戴的称号被删除,随机重置默认! randID=%s" % randID, playerID)
    if isRefreshAttr:
        RefreshHJGAttr(curPlayer)
    SyncTitleInfo(curPlayer, [titleID])
    if notifyMail:
        PlayerControl.SendMailByKey(notifyMail, [playerID], [], [titleID])
    return True
def GetDefaultTitleIDList():
    defaultIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetTitleCount()):
        ipyData = ipyDataMgr.GetTitleByIndex(index)
        titleID = ipyData.GetTitleID()
        if ipyData.GetUnlockWay() != 1:
            continue
        defaultIDList.append(titleID)
    return defaultIDList
def IsTitleCanUse(curPlayer, titleID, ipyData=None):
    ## 称号是否可用
    state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, titleID)
    if state:
        return True
    if not ipyData:
        ipyData = IpyGameDataPY.GetIpyGameData("Title", titleID)
    if ipyData:
        unlockWay = ipyData.GetUnlockWay()
        if unlockWay == 1: # 默认激活的
            return True
    return False
def OnUseTitle(curPlayer, titleID):
    playerID = curPlayer.GetPlayerID()
    if not IsTitleCanUse(curPlayer, titleID):
        GameWorld.DebugLog("该称号不可用! titleID=%s" % (titleID), playerID)
        return
    GameWorld.DebugLog("使用称号! titleID=%s" % (titleID), playerID)
    PlayerControl.SetTitleID(curPlayer, titleID)
    return
def OnTakeOffTitle(curPlayer, titleID):
    if PlayerControl.GetTitleID(curPlayer) != titleID:
        return
    PlayerControl.SetTitleID(curPlayer, 0)
    return
def OnTitleStarUP(curPlayer, titleID):
    playerID = curPlayer.GetPlayerID()
    if not IsTitleCanUse(curPlayer, titleID):
        GameWorld.DebugLog("该称号不可用! titleID=%s" % (titleID), playerID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("Title", titleID)
    if not ipyData:
        return
    starMax = ipyData.GetStarMax()
    curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TitleStar % titleID)
    if curStar >= starMax:
        GameWorld.DebugLog("星级已满! titleID=%s,curStar=%s >= %s" % (titleID, curStar, starMax), playerID)
        return
    if ipyData.GetUnlockWay() != 2:
        return
    itemID = ipyData.GetUnlockValue()
    itemCount = ipyData.GetUnlockNeedCnt()
    if not itemID or not itemCount:
        return
    needItemList = [[itemID, itemCount]]
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
    if lackItemDict:
        GameWorld.DebugLog("升星所需物品不足! titleID=%s,lackItemDict=%s" % (titleID, lackItemDict), playerID)
        return
    ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "TitleStarUP")
    nextStar = curStar + 1
    GameWorld.DebugLog("升星! titleID=%s,nextStar=%s" % (titleID, nextStar), playerID)
    SetTitleStar(curPlayer, titleID, nextStar)
    return
def SetTitleStar(curPlayer, titleID, setStar):
    if not IsTitleCanUse(curPlayer, titleID):
        return
    ipyData = IpyGameDataPY.GetIpyGameData("Title", titleID)
    if not ipyData:
        return
    setStar = min(setStar, ipyData.GetStarMax())
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TitleStar % titleID, setStar)
    RefreshHJGAttr(curPlayer)
    SyncTitleInfo(curPlayer, [titleID])
    return True
def SyncTitleInfo(curPlayer, titleIDList=None):
    if titleIDList == None:
        syncIDList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetTitleCount()):
            ipyData = ipyDataMgr.GetTitleByIndex(index)
            syncIDList.append(ipyData.GetTitleID())
    else:
        syncIDList = titleIDList
    titleList = []
    for titleID in syncIDList:
        state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, titleID)
        if not state and titleIDList == None:
            continue
        title = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCTitle)
        title.TitleID = titleID
        title.State = state
        title.EndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TitleEndTime % titleID)
        title.Star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TitleStar % titleID)
        titleList.append(title)
    if not titleList:
        return
    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCTitleInfo)
    clientPack.TitleList = titleList
    clientPack.Count = len(clientPack.TitleList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
## -------------------------------------------------------------------------------------------------
## ----------------------------------------- 形象 --------------------------------------------------
def OnMinuteModel(curPlayer):
    curTime = int(time.time())
    delIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetModelCount()):
        ipyData = ipyDataMgr.GetModelByIndex(index)
        modelID = ipyData.GetModelID()
        if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ModelState, modelID):
            # 未激活的不处理
            continue
        endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ModelEndTime % modelID)
        if not endTime or endTime > curTime:
            # 永久或未过期
            continue
        if DelModel(curPlayer, modelID, False, "ModelTimeout"):
            delIDList.append(modelID)
    if delIDList:
        RefreshHJGAttr(curPlayer)
    return
def AddModel(curPlayer, modelID, setExpireTimes=None, isFree=False):
    if modelID <= 0:
        return
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("Model", modelID)
    if not ipyData:
        return
    if ipyData.GetUnlockWay() != 2:
        GameWorld.DebugLog("非道具激活的不用添加: modelID=%s" % (modelID), playerID)
        return
    if not isFree:
        itemID = ipyData.GetUnlockValue()
        itemCount = ipyData.GetUnlockNeedCnt()
        if not itemID or not itemCount:
            return
        needItemList = [[itemID, itemCount]]
        itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
        lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
        if lackItemDict:
            GameWorld.DebugLog("激活所需物品不足! modelID=%s,lackItemDict=%s" % (modelID, lackItemDict), playerID)
            return
        ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "AddModel")
    ipyExpireSeconds = ipyData.GetExpireMinutes() * 60
    curTime = int(time.time())
    state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ModelState, modelID)
    endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ModelEndTime % modelID)
    GameWorld.Log("添加形象: modelID=%s,setExpireTimes=%s,state=%s,endTime=%s,ipyExpireSeconds=%s,curTime=%s"
                  % (modelID, setExpireTimes, state, endTime, ipyExpireSeconds, curTime), playerID)
    updEndTime = endTime
    # 指定时长的,如GM指定
    if setExpireTimes > 0:
        updEndTime = curTime + setExpireTimes
        GameWorld.Log("    指定时长: modelID=%s,updEndTime=%s" % (modelID, updEndTime), playerID)
    # 永久
    elif ipyExpireSeconds == 0 or setExpireTimes == 0:
        updEndTime = 0
        GameWorld.Log("    永久时长: modelID=%s,updEndTime=%s" % (modelID, updEndTime), playerID)
    else:
        # 未过期
        if endTime > curTime:
            updEndTime = endTime + ipyExpireSeconds
            GameWorld.Log("    累加时长: modelID=%s,updEndTime=%s" % (modelID, updEndTime), playerID)
        else:
            updEndTime = curTime + ipyExpireSeconds
            GameWorld.Log("    重新激活: modelID=%s,updEndTime=%s" % (modelID, updEndTime), playerID)
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ModelState, modelID, 1)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ModelEndTime % modelID, updEndTime)
    RefreshHJGAttr(curPlayer)
    SyncModelInfo(curPlayer, [modelID])
    return True
def DelModel(curPlayer, modelID, isRefreshAttr=True, notifyMail=""):
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("Model", modelID)
    if not ipyData:
        return
    if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ModelState, modelID):
        return
    GameWorld.Log("删除形象: modelID=%s,notifyMail=%s" % (modelID, notifyMail), playerID)
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ModelState, modelID, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ModelEndTime % modelID, 0)
    # 星级不重置,重新激活后再次生效
    if curPlayer.GetModelMark() == modelID:
        defaultIDList = GetDefaultModelIDList()
        randID = random.choice(defaultIDList) if defaultIDList else 0
        curPlayer.SetModelMark(randID)
        GameWorld.DebugLog("玩家使用的形象被删除,随机重置默认! randID=%s" % randID, playerID)
    if isRefreshAttr:
        RefreshHJGAttr(curPlayer)
    SyncModelInfo(curPlayer, [modelID])
    if notifyMail:
        PlayerControl.SendMailByKey(notifyMail, [playerID], [], [modelID])
    return True
def GetDefaultModelIDList():
    defaultIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetModelCount()):
        ipyData = ipyDataMgr.GetModelByIndex(index)
        modelID = ipyData.GetModelID()
        if ipyData.GetUnlockWay() != 1:
            continue
        defaultIDList.append(modelID)
    return defaultIDList
def IsModelCanUse(curPlayer, modelID, ipyData=None):
    ## 形象是否可用
    state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ModelState, modelID)
    if state:
        return True
    if not ipyData:
        ipyData = IpyGameDataPY.GetIpyGameData("Model", modelID)
    if ipyData:
        unlockWay = ipyData.GetUnlockWay()
        unlockValue = ipyData.GetUnlockValue()
        if unlockWay == 1: # 默认激活的
            return True
        if unlockWay == 3: # 关联武将
            heroID = unlockValue
            return True if PlayerHero.GetHeroActivite(curPlayer, heroID) else False
    return False
def OnUseModel(curPlayer, modelID):
    playerID = curPlayer.GetPlayerID()
    if not IsModelCanUse(curPlayer, modelID):
        GameWorld.DebugLog("该形象不可用! modelID=%s" % (modelID), playerID)
        return
    GameWorld.DebugLog("使用形象! modelID=%s" % (modelID), playerID)
    curPlayer.SetModelMark(modelID)
    return
def OnModelStarUP(curPlayer, modelID):
    playerID = curPlayer.GetPlayerID()
    if not IsModelCanUse(curPlayer, modelID):
        GameWorld.DebugLog("该形象不可用! modelID=%s" % (modelID), playerID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("Model", modelID)
    if not ipyData:
        return
    starMax = ipyData.GetStarMax()
    curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ModelStar % modelID)
    if curStar >= starMax:
        GameWorld.DebugLog("星级已满! modelID=%s,curStar=%s >= %s" % (modelID, curStar, starMax), playerID)
        return
    if ipyData.GetUnlockWay() != 2:
        return
    itemID = ipyData.GetUnlockValue()
    itemCount = ipyData.GetUnlockNeedCnt()
    if not itemID or not itemCount:
        return
    needItemList = [[itemID, itemCount]]
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
    if lackItemDict:
        GameWorld.DebugLog("升星所需物品不足! modelID=%s,lackItemDict=%s" % (modelID, lackItemDict), playerID)
        return
    ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "ModelStarUP")
    nextStar = curStar + 1
    GameWorld.DebugLog("升星! modelID=%s,nextStar=%s" % (modelID, nextStar), playerID)
    SetModelStar(curPlayer, modelID, nextStar)
    return
def SetModelStar(curPlayer, modelID, setStar):
    if not IsModelCanUse(curPlayer, modelID):
        return
    ipyData = IpyGameDataPY.GetIpyGameData("Model", modelID)
    if not ipyData:
        return
    setStar = min(setStar, ipyData.GetStarMax())
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ModelStar % modelID, setStar)
    RefreshHJGAttr(curPlayer)
    SyncModelInfo(curPlayer, [modelID])
    return True
def SyncModelInfo(curPlayer, modelIDList=None):
    if modelIDList == None:
        syncIDList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetModelCount()):
            ipyData = ipyDataMgr.GetModelByIndex(index)
            syncIDList.append(ipyData.GetModelID())
    else:
        syncIDList = modelIDList
    modelList = []
    for modelID in syncIDList:
        state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ModelState, modelID)
        if not state and modelIDList == None:
            continue
        model = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCModel)
        model.ModelID = modelID
        model.State = state
        model.EndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ModelEndTime % modelID)
        model.Star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ModelStar % modelID)
        modelList.append(model)
    if not modelList:
        return
    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCModelInfo)
    clientPack.ModelList = modelList
    clientPack.Count = len(clientPack.ModelList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
## -------------------------------------------------------------------------------------------------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
@@ -26,6 +26,7 @@
import PlayerPrestigeSys
import PlayerGubao
import PlayerHero
import PlayerHJG
import GameWorld
import ChConfig
import ChEquip
@@ -414,6 +415,7 @@
    PlayerHero.CalcHeroAddAttr(curPlayer)
    PlayerPrestigeSys.CalcOfficialRankAttr(curPlayer)
    PlayerGubao.CalcGubaoAttr(curPlayer)
    PlayerHJG.CalcHJGAttr(curPlayer)
    return
def doRefreshLineupAttr(curPlayer, olPlayer, lineup):
@@ -637,6 +639,7 @@
    bookAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_HeroBook)
    realmAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_Realm)
    gubaoAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_Gubao)
    hjgAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_HJG)
    
    GameWorld.DebugLog("    国家武将统计=%s" % countryHeroInfo, playerID)
    GameWorld.DebugLog("    羁绊武将统计=%s" % fetterHeroInfo, playerID)
@@ -653,6 +656,7 @@
    GameWorld.DebugLog("    主公图鉴属性=%s" % bookAttrDict, playerID)
    GameWorld.DebugLog("    主公官职属性=%s" % realmAttrDict, playerID)
    GameWorld.DebugLog("    主公古宝属性=%s" % gubaoAttrDict, playerID)
    GameWorld.DebugLog("    主幻境阁属性=%s" % hjgAttrDict, playerID)
    
    PlayerLV = curPlayer.GetLV()
    OfficialLV = curPlayer.GetOfficialRank()
@@ -690,6 +694,9 @@
            gubaoValue = gubaoAttrDict.get(attrID, 0)
            gubaoPer = gubaoAttrDict.get(attrPerID, 0) / 10000.0 if attrPerID else 0
            
            hjgValue = hjgAttrDict.get(attrID, 0)
            hjgPer = hjgAttrDict.get(attrPerID, 0) / 10000.0 if attrPerID else 0
            lineupInitAddPer, lineupLVAddPer, lineupBreakLVAddPer, lineupStarAddPer = 0, 0, 0, 0
            if attrID in ChConfig.BaseAttrIDList:
                lineupInitAddPer, lineupLVAddPer, lineupBreakLVAddPer, lineupStarAddPer = InitAddPer, LVAddPer, BreakLVAddPer, StarAddPer
@@ -716,7 +723,7 @@
                
            # 计算
            attrParamDict = {"lvValue":lvValue, "equipValue":equipValue, "bookValue":bookValue, "bookPer":bookPer, "realmValue":realmValue, "realmPer":realmPer, 
                             "gubaoValue":gubaoValue, "gubaoPer":gubaoPer,
                             "gubaoValue":gubaoValue, "gubaoPer":gubaoPer, "hjgValue":hjgValue, "hjgPer":hjgPer,
                             "lineupInitAddPer":lineupInitAddPer, "lineupLVAddPer":lineupLVAddPer, "lineupBreakLVAddPer":lineupBreakLVAddPer, "lineupStarAddPer":lineupStarAddPer,
                             "heroSelfValue":heroSelfValue, "heroSelfPer":heroSelfPer, "inheritPer":inheritPer,
                             "lineupHaloValue":lineupHaloValue, "lineupHaloPer":lineupHaloPer, "fetterValue":fetterValue, "fetterPer":fetterPer,
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -25,7 +25,6 @@
import OperControlManager
import ShareDefine
import ReadChConfig
import PlayerDienstgrad
import IpyGameDataPY
import GameObj
import GameMap
@@ -36,13 +35,11 @@
import PlayerSuccess
import PassiveBuffEffMng
import FunctionNPCCommon
import FormulaControl
import PlayerFlashSale
import PlayerChatBox
import PlayerFace
import PlayerBackup
import PlayerOnline
import PlayerGoldRush
import PlayerHJG
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -1069,12 +1066,7 @@
        return
    curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_Minute, tick)
    
    # 时效称号
    PlayerDienstgrad.CheckDienstgradTimeout(curPlayer)
    # 时效头像
    PlayerFace.OnMinute(curPlayer)
    # 聊天气泡
    PlayerChatBox.OnMinute(curPlayer)
    PlayerHJG.OnMinute(curPlayer)
    return
# 一定时间自动释放的被动技能
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTalk.py
@@ -78,7 +78,7 @@
        #发送到跨服,待扩展
        return
    
    bubbleBox = PlayerControl.GetChatBubbleBox(curPlayer) # 气泡框
    bubbleBox = PlayerControl.GetChatBox(curPlayer) # 气泡框
    
    clientPack = ChPyNetSendPack.tagMCTalk()
    clientPack.ChannelType = channelType
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_AddDienstgrad.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTAddTitle.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTFace.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -109,7 +109,6 @@
g_crossRegPlayerAttrDict = {} #跨服注册时登记的会影响战力的属性值 {playerID:[value, ...], ...}
g_crossSyncTickDict = {} #需要同步跨服数据的玩家同步tick字典 {playerID:tick, ...}
g_crossPlayerDictChangeInfo = {} #跨服玩家字典变化信息 {playerID:{(key, dType):value, ...}, ...}
g_crossPlayerDienstgradChangeInfo = {} #跨服玩家称号变化信息 {playerID:{id:isAdd, ...}, ...}
g_crossPlayerItemsChangeInfo = {} #跨服玩家物品变化信息 {playerID:{"背包类型-物品位":itemMD5, ...}, ...}
g_crossPlayerSkillsChangeInfo = {} #跨服玩家技能变化信息 {playerID:[技能ID], ...}
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_Face.py
New file
@@ -0,0 +1,104 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package PyMongoDB.GMToolLogicProcess.Commands.GMT_Face
#
# @todo:GM工具命令 - 幻境阁
# @author hxp
# @date 2025-10-15
# @version 1.0
#
# 详细描述: GM工具命令 - 幻境阁
#
#-------------------------------------------------------------------------------
#"""Version = 2025-10-15 09:30"""
#-------------------------------------------------------------------------------
import GMCommon
import GameWorld
import PlayerFace
import PlayerHJG
import ChConfig
## 收到gm命令执行
# @param gmCmdDict:gm命令字典
# @return None
def OnExec(gmCmdDict):
    #命令测试没通过,后续再调试
    GameWorld.Log("GMT_Face: %s" % gmCmdDict)
    errorMsg = ""
    from GMToolLogicProcess import  ProjSpecialProcess
    Result, curPlayer = ProjSpecialProcess.GMCmdPlayerValidation(gmCmdDict, False)
    if Result != GMCommon.Def_Success:
        return Result, errorMsg
    faceType = gmCmdDict.get('faceType', '')
    opType = gmCmdDict.get('opType', '')
    opID = GameWorld.ToIntDef(gmCmdDict.get('opID', '0'))
    expireTime = GameWorld.ToIntDef(gmCmdDict.get('expireTime', '0'))
    setValue = GameWorld.ToIntDef(gmCmdDict.get('setValue', '0'))
    state, endTime, star = 0, 0, 0
    isOK = False
    errorMsg = ""
    if faceType == "face":
        if opType == "add":
            isOK = PlayerFace.AddFace(curPlayer, opID, expireTime, isFree=True)
        elif opType == "del":
            isOK = PlayerFace.DelFace(curPlayer, opID)
        elif opType == "starUp":
            setValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceStar % opID) + 1
            isOK = PlayerFace.SetFaceStar(curPlayer, opID, setValue)
        elif opType == "setStar":
            isOK = PlayerFace.SetFaceStar(curPlayer, opID, setValue)
        elif opType == "query":
            isOK = True
        state = PlayerFace.IsFaceCanUse(curPlayer, opID)
        endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceEndTime % opID)
        star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FaceStar % opID)
    elif faceType == "facePic":
        if opType == "add":
            isOK = PlayerFace.AddFacePic(curPlayer, opID, expireTime, isFree=True)
        elif opType == "del":
            isOK = PlayerFace.DelFacePic(curPlayer, opID)
        elif opType == "starUp":
            setValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FacePicStar % opID) + 1
            isOK = PlayerFace.SetFacePicStar(curPlayer, opID, setValue)
        elif opType == "setStar":
            isOK = PlayerFace.SetFacePicStar(curPlayer, opID, setValue)
        elif opType == "query":
            isOK = True
        state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_FacePicState, opID)
        endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FacePicEndTime % opID)
        star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FacePicStar % opID)
    elif faceType == "title":
        if opType == "add":
            isOK = PlayerHJG.AddTitle(curPlayer, opID, expireTime, isFree=True)
        elif opType == "del":
            isOK = PlayerHJG.DelTitle(curPlayer, opID)
        elif opType == "starUp":
            setValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TitleStar % opID) + 1
            isOK = PlayerHJG.SetTitleStar(curPlayer, opID, setValue)
        elif opType == "setStar":
            isOK = PlayerHJG.SetTitleStar(curPlayer, opID, setValue)
        elif opType == "query":
            isOK = True
        state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_TitleState, opID)
        endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TitleEndTime % opID)
        star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TitleStar % opID)
    if not isOK:
        if errorMsg:
            errorMsg = "%s %s fail! %s" % (opType, faceType, errorMsg)
        else:
            errorMsg = "%s %s fail! Please check that the ID(%s) is correct." % (opType, faceType, opID)
        return GMCommon.Def_ParamErr, errorMsg
    endTimeStr = "未激活"
    if state:
        endTimeStr = "永久" if not endTime else GameWorld.ChangeTimeNumToStr(endTime)
    resultDict = {"opID":opID, "expireTime":expireTime, "opType":opType,
                  "faceType":faceType, "state":state, "endTimeStr":endTimeStr, "star":star}
    GameWorld.Log("GMT_Face: resultDict=%s" % resultDict, curPlayer.GetPlayerID())
    return Result, resultDict