From caba629e01f8f603b8e05f588688c40e82eb6c88 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 21 十一月 2025 16:44:33 +0800
Subject: [PATCH] 358 【内政】红颜系统-服务端

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerChatBox.py                         |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py                           |   10 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py                                  |  172 ++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py                              |  317 +++++++---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/FBPass.py                           |   40 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBeauty.py                          |  626 ++++++++++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                                   |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py                           |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Arena.py     |   16 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py                           |    1 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Beauty.py                           |  110 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Zhanchui.py  |   29 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py                          |   10 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                                          |   20 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py |   11 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py                                |  146 ++++-
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGoldRush.py                        |   20 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py                              |    5 
 PySysDB/PySysDBPY.h                                                                                                 |   59 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFace.py                            |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Arena.py                            |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                     |   12 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHJG.py                             |    4 
 23 files changed, 1,441 insertions(+), 184 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index a62f192..f95361c 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -955,6 +955,52 @@
 	list		LVUPNeedItemInfo;	//升级所需物品 [[物品ID,个数], ...]
 };
 
+//红颜表
+
+struct Beauty
+{
+	WORD		_BeautyID;	//红颜ID
+	BYTE		BeautyQuality;	//品质
+	BYTE		UnlockWay;	//解锁方式
+    DWORD		UnlockValue;	//解锁方式值
+	BYTE		UnlockNeedCnt;	//解锁所需个数
+	list		TalentAttrIDList;	//天赋属性ID列表
+	list		TalentAttrValueList;	//天赋属性初始值
+	list		TalentPerLVAddList;	//天赋属性每级成长
+	BYTE		EffType;	//天赋效果类型
+	BYTE		EffTypeValue;	//效果类型值
+	BYTE		EffValue;	//效果初始值
+	DWORD		EffPerLVAdd;	//天赋效果每级成长
+};
+
+//红颜品质升级表
+
+struct BeautyQualityLV
+{
+	BYTE		_BeautyQuality;
+	WORD		_BeautyLV;
+	WORD		LVNeedExp;	//升到本级所需经验
+	list		AttrIDList;	//本级属性ID列表
+	list		AttrValueList;	//本级属性值列表
+    list		AwardItemList;	//本级奖励
+};
+
+//红颜时装表
+
+struct	BeautySkin
+{
+    WORD		SkinID;	//时装ID
+	WORD		_BeautyID;
+	BYTE		UnlockWay;	//解锁方式
+    DWORD		UnlockValue;	//解锁方式值
+	BYTE		UnlockNeedCnt;	//解锁所需个数
+	BYTE		UpNeedCnt;	//升级所需个数
+	BYTE		StarMax;	//最高星级
+	list		AttrIDList;	//属性ID列表
+	list		InitAttrValueList;	//初始属性值列表
+    list		AttrPerStarAddList;	//每星加成值列表
+};
+
 //玩家等级表
 
 struct PlayerLV
@@ -1460,19 +1506,6 @@
 	dict		Reward;	//奖励 {"职业":[[物品ID,个数],...], ...}
 	BYTE		VIPLimit;	//需要VIP几
 	list		VIPAward;	//vip奖励[[物品ID,个数],...]
-};
-
-//仙宝寻主表
-
-struct tagXBXZ
-{
-	DWORD		_ID;	//ID
-	BYTE		Type;	//类型
-	DWORD		NeedCnt;	//需要数量
-	list		Condition;	//条件
-	WORD		MWID;	//法宝ID
-	list		AwardItem;	//奖励物品列表
-	list		Money;	//金钱
 };
 
 //寻宝设定表
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index a461166..0b0154c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -1132,6 +1132,26 @@
 PacketSubCMD_3=0x18
 PacketCallFunc_3=OnGubaoLVUp
 
+;红颜
+[PlayerBeauty]
+ScriptName = Player\PlayerBeauty.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 3
+
+PacketCMD_1=0xB2
+PacketSubCMD_1=0x19
+PacketCallFunc_1=OnBeautyActivate
+
+PacketCMD_2=0xB2
+PacketSubCMD_2=0x20
+PacketCallFunc_2=OnBeautyLVUP
+
+PacketCMD_3=0xB2
+PacketSubCMD_3=0x21
+PacketCallFunc_3=OnBeautySkinOP
+
 ;主线战斗
 [GameLogic_MainLevel]
 ScriptName = GameWorldLogic\FBProcess\GameLogic_MainLevel.py
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 0bf8cb5..63faebc 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -219,7 +219,8 @@
 Def_CalcAttr_Gubao, # 古宝 4
 Def_CalcAttr_HJG, # 幻境阁 5
 Def_CalcAttr_Horse, # 坐骑 6
-) = range(7)
+Def_CalcAttr_Beauty, # 红颜 7
+) = range(8)
 
 CalcAttrName = {
                 Def_CalcAttr_LV:"主公等级",
@@ -229,6 +230,7 @@
                 Def_CalcAttr_Gubao:"古宝",
                 Def_CalcAttr_HJG:"幻境阁",
                 Def_CalcAttr_Horse:"坐骑",
+                Def_CalcAttr_Beauty:"红颜",
                 }
 
 ##-----------------------------------------------------------------------------------------------
@@ -3511,6 +3513,11 @@
 Def_PDict_EmojiPackState = "EmojiPackState_%s"  # 表情包状态,参数(key编号)
 Def_PDict_EmojiPackEndTime = "EmojiPackEndTime_%s"  # 到期时间戳,0为永久,参数(表情包ID)
 
+#红颜
+Def_PDict_BeautyLVInfo = "BeautyLVInfo_%s"  # 红颜等级信息,参数(红颜ID) 经验*10000+等级*10+是否已激活
+Def_PDict_BeautyAwardLV = "BeautyAwardLV_%s"  # 红颜已领取到的奖励等级,参数(红颜ID)
+Def_PDict_BeautySkinInfo = "BeautySkinInfo_%s"  # 红颜时装信息,参数(时装ID) 星级*100+是否使用+是否已激活
+
 #周狂欢
 Def_PDict_WeekPartyActID = "WeekPartyActID"  # 玩家身上的活动ID,唯一标识,取活动开始日期time值
 Def_PDict_WeekPartyID = "WeekPartyID"  # 玩家身上的活动ID,配置ID,用于补发上次活动用
@@ -3763,6 +3770,7 @@
 
 #竞技场
 Def_PDict_ArenaScore = "ArenaScore" # 当前积分
+Def_PDict_ArenaWinCnt = "ArenaWinCnt" # 累计胜利次数
 
 #功能系统特权
 Def_PDict_FuncSysPrivilegeActTime = "FuncSysPrivilegeActTime_%s" # 系统功能特权激活时间戳,参数(系统功能ID)
@@ -4767,7 +4775,7 @@
 Def_RewardType_FamilyTaofaBox,  # 公会讨伐领取宝箱奖励 3
 Def_RewardType_LineupRecommend,  # 阵容推荐奖励 4
 Def_RewardType_LVAward,  # 玩家等级奖励5
-Def_RewardType_XBXZ, # 仙宝寻主奖励6
+Def_RewardType_BeautyLVAward, # 红颜等级奖励 6
 Def_RewardType_DayRealmPoint, # 每日任务修行点奖励7
 Def_RewardType_FirstCharge, # 首充礼包奖励8
 Def_RewardType_MWSoulAward, # 法宝之魂奖励9 -废弃
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index c67123e..1f80fad 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -11575,6 +11575,178 @@
 
 
 #------------------------------------------------------
+# B2 19 红颜激活 #tagCSBeautyActivate
+
+class  tagCSBeautyActivate(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("BeautyID", c_ushort),    #红颜ID
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB2
+        self.SubCmd = 0x19
+        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 = 0x19
+        self.BeautyID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCSBeautyActivate)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B2 19 红颜激活 //tagCSBeautyActivate:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                BeautyID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.BeautyID
+                                )
+        return DumpString
+
+
+m_NAtagCSBeautyActivate=tagCSBeautyActivate()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSBeautyActivate.Cmd,m_NAtagCSBeautyActivate.SubCmd))] = m_NAtagCSBeautyActivate
+
+
+#------------------------------------------------------
+# B2 20 红颜好感度升级 #tagCSBeautyLVUP
+
+class  tagCSBeautyLVUP(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("BeautyID", c_ushort),    #红颜ID
+                  ("ItemID", c_int),    #使用物品ID
+                  ("IsQuick", c_ubyte),    # 是否快速升级,0-只消耗1个道具;1-消耗升1级的道具
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB2
+        self.SubCmd = 0x20
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB2
+        self.SubCmd = 0x20
+        self.BeautyID = 0
+        self.ItemID = 0
+        self.IsQuick = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCSBeautyLVUP)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B2 20 红颜好感度升级 //tagCSBeautyLVUP:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                BeautyID:%d,
+                                ItemID:%d,
+                                IsQuick:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.BeautyID,
+                                self.ItemID,
+                                self.IsQuick
+                                )
+        return DumpString
+
+
+m_NAtagCSBeautyLVUP=tagCSBeautyLVUP()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSBeautyLVUP.Cmd,m_NAtagCSBeautyLVUP.SubCmd))] = m_NAtagCSBeautyLVUP
+
+
+#------------------------------------------------------
+# B2 21 红颜时装操作 #tagCSBeautySkinOP
+
+class  tagCSBeautySkinOP(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("BeautyID", c_ushort),    #红颜ID
+                  ("SkinID", c_ushort),    #时装ID
+                  ("OPType", c_ubyte),    #操作 1-激活;2-佩戴;3-升星
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB2
+        self.SubCmd = 0x21
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB2
+        self.SubCmd = 0x21
+        self.BeautyID = 0
+        self.SkinID = 0
+        self.OPType = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCSBeautySkinOP)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B2 21 红颜时装操作 //tagCSBeautySkinOP:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                BeautyID:%d,
+                                SkinID:%d,
+                                OPType:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.BeautyID,
+                                self.SkinID,
+                                self.OPType
+                                )
+        return DumpString
+
+
+m_NAtagCSBeautySkinOP=tagCSBeautySkinOP()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSBeautySkinOP.Cmd,m_NAtagCSBeautySkinOP.SubCmd))] = m_NAtagCSBeautySkinOP
+
+
+#------------------------------------------------------
 # B2 12 领取功能系统特权奖励 #tagCMGetFuncSysPrivilegeAward
 
 class  tagCMGetFuncSysPrivilegeAward(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 8adb7ac..ad5e796 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -8964,114 +8964,6 @@
 
 
 #------------------------------------------------------
-# A3 48 仙宝寻主领奖记录 #tagMCXBXZAwardRecordList
-
-class  tagMCXBXZAwardRecord(Structure):
-    _pack_ = 1
-    _fields_ = [
-                  ("RecordIndex", c_ushort),    #第几个记录值 每个key存31个id   0-30为0, 31-61为1..
-                  ("Record", c_int),    #对应是否领取值
-                  ]
-
-    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.RecordIndex = 0
-        self.Record = 0
-        return
-
-    def GetLength(self):
-        return sizeof(tagMCXBXZAwardRecord)
-
-    def GetBuffer(self):
-        return string_at(addressof(self), self.GetLength())
-
-    def OutputString(self):
-        DumpString = '''// A3 48 仙宝寻主领奖记录 //tagMCXBXZAwardRecordList:
-                                RecordIndex:%d,
-                                Record:%d
-                                '''\
-                                %(
-                                self.RecordIndex,
-                                self.Record
-                                )
-        return DumpString
-
-
-class  tagMCXBXZAwardRecordList(Structure):
-    Head = tagHead()
-    RecordCnt = 0    #(WORD RecordCnt)//记录个数
-    RecordList = list()    #(vector<tagMCXBXZAwardRecord> RecordList)//记录列表
-    data = None
-
-    def __init__(self):
-        self.Clear()
-        self.Head.Cmd = 0xA3
-        self.Head.SubCmd = 0x48
-        return
-
-    def ReadData(self, _lpData, _pos=0, _Len=0):
-        self.Clear()
-        _pos = self.Head.ReadData(_lpData, _pos)
-        self.RecordCnt,_pos = CommFunc.ReadWORD(_lpData, _pos)
-        for i in range(self.RecordCnt):
-            temRecordList = tagMCXBXZAwardRecord()
-            _pos = temRecordList.ReadData(_lpData, _pos)
-            self.RecordList.append(temRecordList)
-        return _pos
-
-    def Clear(self):
-        self.Head = tagHead()
-        self.Head.Clear()
-        self.Head.Cmd = 0xA3
-        self.Head.SubCmd = 0x48
-        self.RecordCnt = 0
-        self.RecordList = list()
-        return
-
-    def GetLength(self):
-        length = 0
-        length += self.Head.GetLength()
-        length += 2
-        for i in range(self.RecordCnt):
-            length += self.RecordList[i].GetLength()
-
-        return length
-
-    def GetBuffer(self):
-        data = ''
-        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
-        data = CommFunc.WriteWORD(data, self.RecordCnt)
-        for i in range(self.RecordCnt):
-            data = CommFunc.WriteString(data, self.RecordList[i].GetLength(), self.RecordList[i].GetBuffer())
-        return data
-
-    def OutputString(self):
-        DumpString = '''
-                                Head:%s,
-                                RecordCnt:%d,
-                                RecordList:%s
-                                '''\
-                                %(
-                                self.Head.OutputString(),
-                                self.RecordCnt,
-                                "..."
-                                )
-        return DumpString
-
-
-m_NAtagMCXBXZAwardRecordList=tagMCXBXZAwardRecordList()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCXBXZAwardRecordList.Head.Cmd,m_NAtagMCXBXZAwardRecordList.Head.SubCmd))] = m_NAtagMCXBXZAwardRecordList
-
-
-#------------------------------------------------------
 # A4 11 传功邀请信息 #tagGCChuangongInviteInfo
 
 class  tagGCChuangongInviteInfo(Structure):
@@ -15003,6 +14895,7 @@
                   ("Cmd", c_ubyte),
                   ("SubCmd", c_ubyte),
                   ("Score", c_int),    #当前积分
+                  ("WinCnt", c_int),    #累计胜利次数
                   ]
 
     def __init__(self):
@@ -15020,6 +14913,7 @@
         self.Cmd = 0xA9
         self.SubCmd = 0x23
         self.Score = 0
+        self.WinCnt = 0
         return
 
     def GetLength(self):
@@ -15032,12 +14926,14 @@
         DumpString = '''// A9 23 演武场玩家信息 //tagSCArenaPlayerInfo:
                                 Cmd:%s,
                                 SubCmd:%s,
-                                Score:%d
+                                Score:%d,
+                                WinCnt:%d
                                 '''\
                                 %(
                                 self.Cmd,
                                 self.SubCmd,
-                                self.Score
+                                self.Score,
+                                self.WinCnt
                                 )
         return DumpString
 
@@ -32317,6 +32213,207 @@
 
 
 #------------------------------------------------------
+# B1 30 红颜信息 #tagSCBeautyInfo
+
+class  tagSCBeautySkin(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("SkinID", c_ushort),    #时装ID
+                  ("State", c_ubyte),    #是否已激活
+                  ("Used", c_ubyte),    #是否已穿戴该时装,某个红颜的所有时装穿戴可能都为0,则前端取默认时装进行展示,如果有同步已穿戴的则以后端为准
+                  ("Star", c_ubyte),    #时装星级,激活时为0星
+                  ]
+
+    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.SkinID = 0
+        self.State = 0
+        self.Used = 0
+        self.Star = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagSCBeautySkin)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B1 30 红颜信息 //tagSCBeautyInfo:
+                                SkinID:%d,
+                                State:%d,
+                                Used:%d,
+                                Star:%d
+                                '''\
+                                %(
+                                self.SkinID,
+                                self.State,
+                                self.Used,
+                                self.Star
+                                )
+        return DumpString
+
+
+class  tagSCBeauty(Structure):
+    BeautyID = 0    #(WORD BeautyID)//红颜ID
+    State = 0    #(BYTE State)//是否已激活
+    LV = 0    #(WORD LV)//红颜好感等级,激活时为0级
+    Exp = 0    #(WORD Exp)//当前等级经验
+    AwardLV = 0    #(WORD AwardLV)//已经领取到的奖励等级记录
+    SkinCnt = 0    #(BYTE SkinCnt)
+    SkinList = list()    #(vector<tagSCBeautySkin> SkinList)//时装皮肤列表,默认解锁的不通知,有变化的才会同步
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.BeautyID,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.State,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.Exp,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.AwardLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.SkinCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.SkinCnt):
+            temSkinList = tagSCBeautySkin()
+            _pos = temSkinList.ReadData(_lpData, _pos)
+            self.SkinList.append(temSkinList)
+        return _pos
+
+    def Clear(self):
+        self.BeautyID = 0
+        self.State = 0
+        self.LV = 0
+        self.Exp = 0
+        self.AwardLV = 0
+        self.SkinCnt = 0
+        self.SkinList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 2
+        length += 1
+        length += 2
+        length += 2
+        length += 2
+        length += 1
+        for i in range(self.SkinCnt):
+            length += self.SkinList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteWORD(data, self.BeautyID)
+        data = CommFunc.WriteBYTE(data, self.State)
+        data = CommFunc.WriteWORD(data, self.LV)
+        data = CommFunc.WriteWORD(data, self.Exp)
+        data = CommFunc.WriteWORD(data, self.AwardLV)
+        data = CommFunc.WriteBYTE(data, self.SkinCnt)
+        for i in range(self.SkinCnt):
+            data = CommFunc.WriteString(data, self.SkinList[i].GetLength(), self.SkinList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                BeautyID:%d,
+                                State:%d,
+                                LV:%d,
+                                Exp:%d,
+                                AwardLV:%d,
+                                SkinCnt:%d,
+                                SkinList:%s
+                                '''\
+                                %(
+                                self.BeautyID,
+                                self.State,
+                                self.LV,
+                                self.Exp,
+                                self.AwardLV,
+                                self.SkinCnt,
+                                "..."
+                                )
+        return DumpString
+
+
+class  tagSCBeautyInfo(Structure):
+    Head = tagHead()
+    Count = 0    #(BYTE Count)
+    BeautyList = list()    #(vector<tagSCBeauty> BeautyList)
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB1
+        self.Head.SubCmd = 0x30
+        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):
+            temBeautyList = tagSCBeauty()
+            _pos = temBeautyList.ReadData(_lpData, _pos)
+            self.BeautyList.append(temBeautyList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB1
+        self.Head.SubCmd = 0x30
+        self.Count = 0
+        self.BeautyList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        for i in range(self.Count):
+            length += self.BeautyList[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.BeautyList[i].GetLength(), self.BeautyList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                Count:%d,
+                                BeautyList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.Count,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagSCBeautyInfo=tagSCBeautyInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCBeautyInfo.Head.Cmd,m_NAtagSCBeautyInfo.Head.SubCmd))] = m_NAtagSCBeautyInfo
+
+
+#------------------------------------------------------
 # B1 27 聊天气泡框信息 #tagSCChatBoxInfo
 
 class  tagSCChatBox(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Arena.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Arena.py
index b6586ff..415b8bf 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Arena.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Arena.py
@@ -32,6 +32,7 @@
         GameWorld.DebugAnswer(curPlayer, "重置玩家竞技场: Arena 0")
         GameWorld.DebugAnswer(curPlayer, "设置玩家榜积分: Arena 积分")
         GameWorld.DebugAnswer(curPlayer, "直接匹配到目标: Arena m 对手ID 对手ID ...")
+        GameWorld.DebugAnswer(curPlayer, "设置累计胜利数: Arena w 胜利数")
         GameWorld.DebugAnswer(curPlayer, "重置赛季直接用 test_OnWeek")
         return
     
@@ -54,5 +55,11 @@
         gmMatchIDList = msgList[1:]
         PlayerArena.GMArenaMatch(curPlayer, gmMatchIDList)
         
+    elif value1 == "w":
+        winCnt = msgList[1] if len(msgList) > 1 else 0
+        GameWorld.DebugAnswer(curPlayer, "设置竞技场胜利数: %s" % winCnt)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaWinCnt, winCnt)
+        PlayerArena.Sync_ArenaInfo(curPlayer)
+        
     return
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Beauty.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Beauty.py
new file mode 100644
index 0000000..250a2ad
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Beauty.py
@@ -0,0 +1,110 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.Beauty
+#
+# @todo:红颜
+# @author hxp
+# @date 2025-11-21
+# @version 1.0
+#
+# 详细描述: 红颜
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-11-21 17:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import IpyGameDataPY
+import PlayerControl
+import PlayerBeauty
+import ChConfig
+
+def OnExec(curPlayer, msgList):
+    
+    if not msgList:
+        GameWorld.DebugAnswer(curPlayer, "重置红颜: Beauty 0 [红颜ID]")
+        GameWorld.DebugAnswer(curPlayer, "设置红颜: Beauty 红颜ID [等级 经验 领奖等级]")
+        GameWorld.DebugAnswer(curPlayer, "红颜时装: Beauty s 时装ID [星级]")
+        GameWorld.DebugAnswer(curPlayer, "演武场胜利数: Arena w 胜利数")
+        GameWorld.DebugAnswer(curPlayer, "副本过关进度: FBPass")
+        return
+    
+    beautyIDList, skinIDList = [], []
+    
+    value1 = msgList[0]
+    if value1 == 0:
+        setBeautyID = msgList[1] if len(msgList) > 1 else 0
+        ipyDataMgr = IpyGameDataPY.IPY_Data()
+        for index in range(ipyDataMgr.GetBeautyCount()):
+            ipyData = ipyDataMgr.GetBeautyByIndex(index)
+            beautyID = ipyData.GetBeautyID()
+            if setBeautyID and setBeautyID != beautyID:
+                continue
+            if not PlayerBeauty.GetBeautyState(curPlayer, beautyID):
+                continue
+            beautyIDList.append(beautyID)
+            
+            ipyDataList = IpyGameDataPY.GetIpyGameDataList("BeautySkin", beautyID)
+            if ipyDataList:
+                for skinIpyData in ipyDataList:
+                    skinID = skinIpyData.GetSkinID()
+                    if not PlayerBeauty.GetBeautySkinState(curPlayer, skinID):
+                        continue
+                    skinIDList.append(skinID)
+                    
+                    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BeautySkinInfo % skinID, 0)
+                    
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BeautyLVInfo % beautyID, 0)
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BeautyAwardLV % beautyID, 0)
+            
+        GameWorld.DebugAnswer(curPlayer, "重置红颜OK")
+        
+    elif value1 == "s":
+        skinID = msgList[1] if len(msgList) > 1 else 0
+        star = msgList[2] if len(msgList) > 2 else 0
+        ipyData = IpyGameDataPY.GetIpyGameDataByCondition("BeautySkin", {"SkinID":skinID}, False)
+        if not ipyData:
+            GameWorld.DebugAnswer(curPlayer, "不存在红颜时装skinID:%s" % skinID)
+            return
+        beautyID = ipyData.GetBeautyID()
+        star = min(star, ipyData.GetStarMax())
+        PlayerBeauty.DoBeautyActivate(curPlayer, beautyID)
+        PlayerBeauty.SetBeautySkinState(curPlayer, skinID, 1)
+        PlayerBeauty.SetBeautySkinStar(curPlayer, skinID, star)
+        beautyIDList, skinIDList = [beautyID], [skinID]
+        GameWorld.DebugAnswer(curPlayer, "红颜ID:%s,时装ID:%s,星:%s" % (beautyID, skinID, star))
+        
+    elif value1 > 0:
+        beautyID = value1
+        lv = msgList[1] if len(msgList) > 1 else None
+        exp = msgList[2] if len(msgList) > 2 else 0
+        awardLV = msgList[3] if len(msgList) > 3 else None
+        ipyData = IpyGameDataPY.GetIpyGameData("Beauty", beautyID)
+        if not ipyData:
+            GameWorld.DebugAnswer(curPlayer, "不存在红颜! %s" % beautyID)
+            return
+        quality = ipyData.GetBeautyQuality()
+        
+        PlayerBeauty.DoBeautyActivate(curPlayer, beautyID)
+        if lv == None:
+            lv, exp, awardLV = 0, 0, 0
+            
+        if not IpyGameDataPY.GetIpyGameData("BeautyQualityLV", quality, lv):
+            GameWorld.DebugAnswer(curPlayer, "不存在红颜等级! ID:%s,品质:%s,LV:%s" % (beautyID, quality, lv))
+            return
+        PlayerBeauty.SetBeautyLVInfo(curPlayer, beautyID, lv, exp)
+        lv, exp = PlayerBeauty.GetBeautyLVInfo(curPlayer, beautyID)
+        
+        if awardLV != None:
+            awardLV = min(lv, awardLV)
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BeautyAwardLV % beautyID, awardLV)
+        awardLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautyAwardLV % beautyID)
+        
+        GameWorld.DebugAnswer(curPlayer, "红颜ID:%s, 品质:%s, LV:%s-%s, 奖励LV:%s" % (beautyID, quality, lv, exp, awardLV))
+        beautyIDList = [beautyID]
+        
+    PlayerBeauty.RefreshBeautyAttr(curPlayer)
+    PlayerBeauty.SyncBeautyInfo(curPlayer, beautyIDList, skinIDList)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/FBPass.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/FBPass.py
new file mode 100644
index 0000000..08d0329
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/FBPass.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.FBPass
+#
+# @todo:设置副本过关进度
+# @author hxp
+# @date 2025-11-21
+# @version 1.0
+#
+# 详细描述: 设置副本过关进度
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-11-21 17:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import IpyGameDataPY
+import PlayerControl
+import FBCommon
+import ChConfig
+
+def OnExec(curPlayer, paramList):
+    
+    if not paramList:
+        GameWorld.DebugAnswer(curPlayer, "副本过关进度: FBPass mapID lineID")
+        return
+    mapID = paramList[0]
+    funcLineID = paramList[1] if len(paramList) > 1 else 0
+    
+    if not IpyGameDataPY.GetIpyGameData("FBLine", mapID, funcLineID):
+        GameWorld.DebugAnswer(curPlayer, "不存在该副本线路:%s-%s" % (mapID, funcLineID))
+        return
+    
+    GameWorld.DebugAnswer(curPlayer, "副本过关进度:%s-%s" % (mapID, funcLineID))
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FBPassLineID % mapID, funcLineID)
+    FBCommon.Sync_FBPlayerFBInfoData(curPlayer, mapID)
+    return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Arena.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Arena.py
index fb0c287..f9d3308 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Arena.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Arena.py
@@ -25,6 +25,7 @@
 import PlayerBillboard
 import PlayerZhanling
 import ItemControler
+import PlayerBeauty
 import PlayerArena
 import PlayerGubao
 import PyGameData
@@ -125,7 +126,13 @@
         GameWorld.DebugLog("scoreIndex=%s,winScoreInfo=%s" % (scoreIndex, winScoreInfo), playerID)
         
     # 无论胜负,只要挑战都给固定奖励
-    awardItemList = IpyGameDataPY.GetFuncEvalCfg("ArenaSet", 4)
+    awardItemList = []
+    awardItemList += IpyGameDataPY.GetFuncEvalCfg("ArenaSet", 4)
+    exItemRate, exItemID = PlayerBeauty.GetBeautyEffInfo(curPlayer, PlayerBeauty.EffType_ArenaItemEx) # 概率额外获得1个物品
+    if exItemRate and exItemID:
+        if GameWorld.CanHappen(exItemRate):
+            awardItemList.append([exItemID, 1])
+            GameWorld.DebugLog("红颜概率额外获得1个物品: exItemRate=%s, exItemID=%s, awardItemList=%s" % (exItemRate, exItemID, awardItemList))
     overMsg.update({"tagPlayerID":tagPlayerID, "atkAddScore":atkAddScore, "defDecScore":defDecScore,
                     FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(awardItemList)})
     
@@ -142,6 +149,11 @@
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, updScore)
     GameWorld.DebugLog("score=%s,atkAddScore=%s,updScore=%s" % (score, atkAddScore, updScore), playerID)
     
+    if isWin:
+        winCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaWinCnt)
+        updWinCnt = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaWinCnt, winCnt + 1)
+        GameWorld.DebugLog("updWinCnt=%s" % (updWinCnt), playerID)
+        
     tagViewCache = turnFight.tagViewCache
     gameRecMgr = DBDataMgr.GetGameRecMgr()
     atkRecMgr = gameRecMgr.GetRecTypeIDMgr(ShareDefine.Def_GameRecType_ArenaRecord, playerID)
@@ -208,7 +220,7 @@
         return
     
     tagPlayerID, isWin, atkAddScore, defDecScore, awardItemList = awardData
-    
+    GameWorld.DebugLog("竞技场结算奖励: tagPlayerID=%s,isWin=%s,atkAddScore=%s,defDecScore=%s,awardItemList=%s" % (tagPlayerID, isWin, atkAddScore, defDecScore, awardItemList))
     if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_ArenaTicket, 1):
         return
     
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
index 3829f22..c640cc3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
@@ -26,6 +26,7 @@
 import ItemControler
 import IPY_GameWorld
 import NetPackCommon
+import PlayerBeauty
 import PlayerArena
 import PlayerLLMJ
 import ItemCommon
@@ -121,12 +122,18 @@
     # 其他战利品掉落
     bootyDropNeedDict = IpyGameDataPY.GetFuncEvalCfg("MainBootyDrop", 1, {})
     bootyDropCntDict = IpyGameDataPY.GetFuncEvalCfg("MainBootyDrop", 2, {})
-    for itemID, dropUpper in DailyBootyUpperList:
+    for itemID, baseUpper in DailyBootyUpperList:
         if spaceCount <= 0:
             GameWorld.DebugLog("掉落背包已满!", playerID)
             break
-        if dropUpper <= 0:
+        if baseUpper <= 0:
             continue
+        dropUpper = baseUpper
+        addPer = 0
+        addPer += PlayerBeauty.GetBeautyEffInfo(curPlayer, PlayerBeauty.EffType_BootyPer)[0] # 战利品上限提高百分比
+        if addPer:
+            dropUpper = int(baseUpper * (100 + addPer) / 100.0)
+            GameWorld.DebugLog("红颜提高战利品掉落上限: itemID=%s,baseUpper=%s,addPer=%s,dropUpper=%s" % (itemID, baseUpper, addPer, dropUpper))
         todyDropCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID)
         if todyDropCnt >= dropUpper:
             GameWorld.DebugLog("战利品已达今日掉落上限! itemID=%s,todyDropCnt=%s >= %s" % (itemID, todyDropCnt, dropUpper), playerID)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Zhanchui.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Zhanchui.py
index 542529b..4aa788e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Zhanchui.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Zhanchui.py
@@ -17,6 +17,7 @@
 
 import GameWorld
 import ItemControler
+import PlayerBeauty
 import FBCommon
 
 def OnTurnFightRequest(curPlayer, mapID, funcLineID, tagType, tagID, valueList):
@@ -74,13 +75,35 @@
 def OnPlayerFBSweepResult(curPlayer, mapID, lineID, sweepCnt, dataEx, askRet):
     ## 扫荡结果,次数消耗已在外层处理扣除
     
-    itemList = FBCommon.GetSweepAwardList(mapID, lineID, sweepCnt)
-    GameWorld.DebugLog("白骨盈野扫荡: mapID=%s,lineID=%s,sweepCnt=%s" % (mapID, lineID, sweepCnt))
+    itemList = []
+    itemList += FBCommon.GetSweepAwardList(mapID, lineID, sweepCnt)
+    GameWorld.DebugLog("白骨盈野扫荡: mapID=%s,lineID=%s,sweepCnt=%s,itemList=%s" % (mapID, lineID, sweepCnt, itemList))
     
+    addPer = PlayerBeauty.GetBeautyEffInfo(curPlayer, PlayerBeauty.EffType_FBZhanchuiAwardPer)[0] # 扫荡奖励百分比
+    if addPer:
+        GameWorld.DebugLog("红颜额外增加扫荡奖励百分比: %s, itemList=%s" % (addPer, itemList))
+        itemListEx = []
+        for itemInfo in itemList:
+            itemID = itemInfo[0]
+            itemCount = itemInfo[1]
+            addCount = int(itemCount * addPer / 100.0)
+            if addCount > 0:
+                itemListEx.append([itemID, addCount, 1]) # 标记是红颜效果额外获得的
+        itemList += itemListEx
+        GameWorld.DebugLog("itemListEx=%s,itemList=%s" % (itemListEx, itemList))
+        
     ItemControler.GivePlayerItemOrMail(curPlayer, itemList, event=["Zhanchui", False, {}], isNotifyAward=False)
     
     isPass = 1
-    overDict = {FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(itemList), FBCommon.Over_isSweep:1}
+    jsonItemList = []
+    for itemInfo in itemList:
+        itemID = itemInfo[0]
+        itemCount = itemInfo[1]
+        itemDict = {"ItemID":itemInfo[0], "Count":itemInfo[1]}
+        if len(itemInfo) > 2:
+            itemDict['BeautyEx'] = itemInfo[2]
+        jsonItemList.append(itemDict)
+    overDict = {FBCommon.Over_itemInfo:jsonItemList, FBCommon.Over_isSweep:1}
     FBCommon.NotifyFBOver(curPlayer, mapID, lineID, isPass, overDict)
     
     return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index c16c9d1..25013fb 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -795,6 +795,43 @@
                         ("list", "LVUPNeedItemInfo", 0),
                         ),
 
+                "Beauty":(
+                        ("WORD", "BeautyID", 1),
+                        ("BYTE", "BeautyQuality", 0),
+                        ("BYTE", "UnlockWay", 0),
+                        ("DWORD", "UnlockValue", 0),
+                        ("BYTE", "UnlockNeedCnt", 0),
+                        ("list", "TalentAttrIDList", 0),
+                        ("list", "TalentAttrValueList", 0),
+                        ("list", "TalentPerLVAddList", 0),
+                        ("BYTE", "EffType", 0),
+                        ("BYTE", "EffTypeValue", 0),
+                        ("BYTE", "EffValue", 0),
+                        ("DWORD", "EffPerLVAdd", 0),
+                        ),
+
+                "BeautyQualityLV":(
+                        ("BYTE", "BeautyQuality", 1),
+                        ("WORD", "BeautyLV", 1),
+                        ("WORD", "LVNeedExp", 0),
+                        ("list", "AttrIDList", 0),
+                        ("list", "AttrValueList", 0),
+                        ("list", "AwardItemList", 0),
+                        ),
+
+                "BeautySkin":(
+                        ("WORD", "SkinID", 0),
+                        ("WORD", "BeautyID", 1),
+                        ("BYTE", "UnlockWay", 0),
+                        ("DWORD", "UnlockValue", 0),
+                        ("BYTE", "UnlockNeedCnt", 0),
+                        ("BYTE", "UpNeedCnt", 0),
+                        ("BYTE", "StarMax", 0),
+                        ("list", "AttrIDList", 0),
+                        ("list", "InitAttrValueList", 0),
+                        ("list", "AttrPerStarAddList", 0),
+                        ),
+
                 "PlayerLV":(
                         ("WORD", "LV", 1),
                         ("DWORD", "Exp", 0),
@@ -1185,16 +1222,6 @@
                         ("dict", "Reward", 0),
                         ("BYTE", "VIPLimit", 0),
                         ("list", "VIPAward", 0),
-                        ),
-
-                "XBXZ":(
-                        ("DWORD", "ID", 1),
-                        ("BYTE", "Type", 0),
-                        ("DWORD", "NeedCnt", 0),
-                        ("list", "Condition", 0),
-                        ("WORD", "MWID", 0),
-                        ("list", "AwardItem", 0),
-                        ("list", "Money", 0),
                         ),
 
                 "TreasureSet":(
@@ -3319,6 +3346,58 @@
     def GetLessEqualLV(self): return self.attrTuple[1] # 小于等于等级 BYTE
     def GetLVUPNeedItemInfo(self): return self.attrTuple[2] # 升级所需物品 [[物品ID,个数], ...] list
 
+# 红颜表
+class IPY_Beauty():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetBeautyID(self): return self.attrTuple[0] # 红颜ID WORD
+    def GetBeautyQuality(self): return self.attrTuple[1] # 品质 BYTE
+    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 GetTalentAttrIDList(self): return self.attrTuple[5] # 天赋属性ID列表 list
+    def GetTalentAttrValueList(self): return self.attrTuple[6] # 天赋属性初始值 list
+    def GetTalentPerLVAddList(self): return self.attrTuple[7] # 天赋属性每级成长 list
+    def GetEffType(self): return self.attrTuple[8] # 天赋效果类型 BYTE
+    def GetEffTypeValue(self): return self.attrTuple[9] # 效果类型值 BYTE
+    def GetEffValue(self): return self.attrTuple[10] # 效果初始值 BYTE
+    def GetEffPerLVAdd(self): return self.attrTuple[11] # 天赋效果每级成长 DWORD
+
+# 红颜品质升级表
+class IPY_BeautyQualityLV():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetBeautyQuality(self): return self.attrTuple[0] # BYTE
+    def GetBeautyLV(self): return self.attrTuple[1] # WORD
+    def GetLVNeedExp(self): return self.attrTuple[2] # 升到本级所需经验 WORD
+    def GetAttrIDList(self): return self.attrTuple[3] # 本级属性ID列表 list
+    def GetAttrValueList(self): return self.attrTuple[4] # 本级属性值列表 list
+    def GetAwardItemList(self): return self.attrTuple[5] # 本级奖励 list
+
+# 红颜时装表
+class IPY_BeautySkin():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetSkinID(self): return self.attrTuple[0] # 时装ID WORD
+    def GetBeautyID(self): return self.attrTuple[1] # WORD
+    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_PlayerLV():
     
@@ -3900,21 +3979,6 @@
     def GetReward(self): return self.attrTuple[3] # 奖励 {"职业":[[物品ID,个数],...], ...} dict
     def GetVIPLimit(self): return self.attrTuple[4] # 需要VIP几 BYTE
     def GetVIPAward(self): return self.attrTuple[5] # vip奖励[[物品ID,个数],...] list
-
-# 仙宝寻主表
-class IPY_XBXZ():
-    
-    def __init__(self):
-        self.attrTuple = None
-        return
-        
-    def GetID(self): return self.attrTuple[0] # ID DWORD
-    def GetType(self): return self.attrTuple[1] # 类型 BYTE
-    def GetNeedCnt(self): return self.attrTuple[2] # 需要数量 DWORD
-    def GetCondition(self): return self.attrTuple[3] # 条件 list
-    def GetMWID(self): return self.attrTuple[4] # 法宝ID WORD
-    def GetAwardItem(self): return self.attrTuple[5] # 奖励物品列表 list
-    def GetMoney(self): return self.attrTuple[6] # 金钱 list
 
 # 寻宝设定表
 class IPY_TreasureSet():
@@ -5631,6 +5695,9 @@
         self.__LoadFileData("GubaoResonance", onlyCheck)
         self.__LoadFileData("GubaoStar", onlyCheck)
         self.__LoadFileData("GubaoLV", onlyCheck)
+        self.__LoadFileData("Beauty", onlyCheck)
+        self.__LoadFileData("BeautyQualityLV", onlyCheck)
+        self.__LoadFileData("BeautySkin", onlyCheck)
         self.__LoadFileData("PlayerLV", onlyCheck)
         self.__LoadFileData("SpecMapPlayerAttrFormat", onlyCheck)
         self.__LoadFileData("GMAttr", onlyCheck)
@@ -5669,7 +5736,6 @@
         self.__LoadFileData("CTGSelectItem", onlyCheck)
         self.__LoadFileData("FirstCharge", onlyCheck)
         self.__LoadFileData("LVAward", onlyCheck)
-        self.__LoadFileData("XBXZ", onlyCheck)
         self.__LoadFileData("TreasureSet", onlyCheck)
         self.__LoadFileData("TreasureHouse", onlyCheck)
         self.__LoadFileData("TreasureItemLib", onlyCheck)
@@ -6494,6 +6560,27 @@
         self.CheckLoadData("GubaoLV")
         return self.ipyGubaoLVCache[index]
 
+    def GetBeautyCount(self):
+        self.CheckLoadData("Beauty")
+        return self.ipyBeautyLen
+    def GetBeautyByIndex(self, index):
+        self.CheckLoadData("Beauty")
+        return self.ipyBeautyCache[index]
+
+    def GetBeautyQualityLVCount(self):
+        self.CheckLoadData("BeautyQualityLV")
+        return self.ipyBeautyQualityLVLen
+    def GetBeautyQualityLVByIndex(self, index):
+        self.CheckLoadData("BeautyQualityLV")
+        return self.ipyBeautyQualityLVCache[index]
+
+    def GetBeautySkinCount(self):
+        self.CheckLoadData("BeautySkin")
+        return self.ipyBeautySkinLen
+    def GetBeautySkinByIndex(self, index):
+        self.CheckLoadData("BeautySkin")
+        return self.ipyBeautySkinCache[index]
+
     def GetPlayerLVCount(self):
         self.CheckLoadData("PlayerLV")
         return self.ipyPlayerLVLen
@@ -6759,13 +6846,6 @@
     def GetLVAwardByIndex(self, index):
         self.CheckLoadData("LVAward")
         return self.ipyLVAwardCache[index]
-
-    def GetXBXZCount(self):
-        self.CheckLoadData("XBXZ")
-        return self.ipyXBXZLen
-    def GetXBXZByIndex(self, index):
-        self.CheckLoadData("XBXZ")
-        return self.ipyXBXZCache[index]
 
     def GetTreasureSetCount(self):
         self.CheckLoadData("TreasureSet")
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
index 79539df..74383d5 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
@@ -2005,11 +2005,11 @@
         return False
     
     if isAuctionItem:
-        ipyData = None #IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
-        if not ipyData:
-            GameWorld.ErrLog("非拍卖物品,默认转为非拍品! itemID=%s,itemCount=%s,isAuctionItem=%s" 
-                             % (itemID, itemCount, isAuctionItem), curPlayer.GetPlayerID())
-            isAuctionItem = 0
+        #ipyData = None #IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
+        #if not ipyData:
+        #    GameWorld.ErrLog("非拍卖物品,默认转为非拍品! itemID=%s,itemCount=%s,isAuctionItem=%s" 
+        #                     % (itemID, itemCount, isAuctionItem), curPlayer.GetPlayerID())
+        isAuctionItem = 0
     
     defaultPack = IPY_GameWorld.rptItem if not packIndexList else packIndexList[0]
     packIndex = ChConfig.GetItemPackType(curItemData, defaultPack)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index cff0141..c8654ae 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -131,6 +131,7 @@
 import PlayerTalk
 import PlayerHero
 import PlayerOnline
+import PlayerBeauty
 import TurnAttack
 import PlayerHJG
 import ObjPool
@@ -732,6 +733,7 @@
         UpdatePlayerName.OnPlayerLogin(curPlayer)
         PlayerActivity.OnPlayerLogin(curPlayer)
         PlayerLLMJ.OnPlayerLogin(curPlayer)
+        PlayerBeauty.OnPlayerLogin(curPlayer)
         
         # 上线查询一次充值订单
         curPlayer.SendDBQueryRecharge()
@@ -3233,6 +3235,9 @@
     # 功能开启奖励
     elif rewardType == ChConfig.Def_RewardType_OpenFunc:
         GameFuncComm.GetFuncOpenAward(curPlayer, dataEx)
+    # 红颜等级奖励
+    elif rewardType == ChConfig.Def_RewardType_BeautyLVAward:
+        PlayerBeauty.GetBeautyLVAward(curPlayer, dataEx)
         
         
     # 每日免费直购礼包
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
index 76ecda7..92bd1af 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
@@ -373,5 +373,6 @@
 def Sync_ArenaInfo(curPlayer):
     clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCArenaPlayerInfo)
     clientPack.Score = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
+    clientPack.WinCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaWinCnt)
     NetPackCommon.SendFakePack(curPlayer, clientPack)
     return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBeauty.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBeauty.py
new file mode 100644
index 0000000..413f347
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBeauty.py
@@ -0,0 +1,626 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerBeauty
+#
+# @todo:红颜
+# @author hxp
+# @date 2025-11-21
+# @version 1.0
+#
+# 详细描述: 红颜
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-11-21 17:00"""
+#-------------------------------------------------------------------------------
+
+import ChConfig
+import GameWorld
+import ItemCommon
+import PlayerOnline
+import PlayerControl
+import IpyGameDataPY
+import ChPyNetSendPack
+import PlayerGoldRush
+import NetPackCommon
+import ItemControler
+import PlayerTask
+import FBCommon
+import ObjPool
+import PyGameData
+
+# 红颜解锁方式
+(
+UnlockWay_Item, # 物品解锁 1
+UnlockWay_TaskID, # 完成主线任务ID 2
+UnlockWay_ArenaWinCnt, # 演武场胜利次数 3
+UnlockWay_GoldRushWorker, # 拥有监工数量 4
+UnlockWay_FBZhanchui, # 白骨盈野过关 5
+UnlockWay_OfficialRank, # 官职达到 6
+UnlockWay_TravelCnt, # 游历次数 7
+) = range(1, 1 + 7)
+
+# 皮肤解锁方式
+UnlockWaySkin_Default = 1 # 默认解锁 1
+UnlockWaySkin_Item = 2 # 物品解锁 2
+
+# 红颜效果类型
+(
+EffType_BootyPer, # 1. 主线战利品上限提高百分比(对所有主线战利品生效)  Value:百分比
+EffType_ArenaItemEx, # 2. 演武场挑战胜利,概率额外获得1个物品的概率    TypeValue:物品ID  Value:概率
+EffType_TravelEnergy, # 3.游历体力上限增加     Value:增加上限
+EffType_FBZhanchuiAwardPer, # 4.白骨盈野扫荡奖励增加百分比     Value:百分比
+) = range(1, 1 + 4)
+
+def OnPlayerLogin(curPlayer):
+    SyncBeautyInfo(curPlayer)
+    return
+
+## Def_PDict_BeautyLVInfo 经验*10000+等级*10+是否已激活
+def GetBeautyState(curPlayer, beautyID):
+    ## 红颜激活状态
+    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautyLVInfo % beautyID) % 10
+def SetBeautyState(curPlayer, beautyID, state):
+    ## 设置红颜激活状态
+    lvInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautyLVInfo % beautyID)
+    lvInfo = lvInfo / 10 * 10 + min(1, state)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BeautyLVInfo % beautyID, lvInfo)
+    return lvInfo
+def GetBeautyLVInfo(curPlayer, beautyID):
+    ## 获取红颜等级经验
+    lvInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautyLVInfo % beautyID)
+    exp = lvInfo / 10000
+    lv = lvInfo % 10000 / 10
+    return lv, exp
+def SetBeautyLVInfo(curPlayer, beautyID, lv, exp):
+    lvInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautyLVInfo % beautyID)
+    lvInfo = min(exp, 200000) * 10000 + min(lv, 999) * 10 + lvInfo % 10
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BeautyLVInfo % beautyID, lvInfo)
+    return lvInfo
+
+## Def_PDict_BeautySkinInfo 星级*100+是否使用+是否已激活
+def GetBeautySkinState(curPlayer, skinID):
+    ## 红颜时装激活状态
+    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautySkinInfo % skinID) % 10
+def SetBeautySkinState(curPlayer, skinID, state):
+    info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautySkinInfo % skinID)
+    info = info / 10 * 10 + min(1, state)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BeautySkinInfo % skinID, info)
+    return info
+def GetBeautySkinUsed(curPlayer, skinID):
+    ## 是否使用中
+    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautySkinInfo % skinID) % 100 / 10
+def SetBeautySkinUsed(curPlayer, skinID, isUsed):
+    info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautySkinInfo % skinID)
+    info = info / 100 * 100 + min(1, isUsed) * 10 + info % 10
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BeautySkinInfo % skinID, info)
+    return info
+def GetBeautySkinStar(curPlayer, skinID):
+    ## 红颜时装星级
+    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautySkinInfo % skinID) / 100
+def SetBeautySkinStar(curPlayer, skinID, star):
+    info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautySkinInfo % skinID)
+    info = star * 100 + info % 100
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BeautySkinInfo % skinID, info)
+    return info
+
+def IsBeautySkinCanUse(curPlayer, beautyID, skinID, ipyData=None):
+    ## 红颜时装是否可用
+    if GetBeautySkinState(curPlayer, skinID):
+        return True
+    
+    if not ipyData:
+        ipyData = GetBeautySkinIpyData(curPlayer, beautyID, skinID)
+    if ipyData:
+        unlockWay = ipyData.GetUnlockWay()
+        if unlockWay == UnlockWaySkin_Default: # 默认激活的
+            return True
+        
+    return False
+
+#// B2 19 红颜激活 #tagCSBeautyActivate
+#
+#struct    tagCSBeautyActivate
+#{
+#    tagHead         Head;
+#    WORD        BeautyID;    //红颜ID
+#};
+def OnBeautyActivate(index, curPackData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    beautyID = curPackData.BeautyID
+    
+    if GetBeautyState(curPlayer, beautyID):
+        GameWorld.DebugLog("红颜已经激活过! beautyID=%s" % beautyID, playerID)
+        return
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("Beauty", beautyID)
+    if not ipyData:
+        return
+    
+    unlockWay = ipyData.GetUnlockWay()
+    unlockValue = ipyData.GetUnlockValue()
+    unlockNeedCnt = ipyData.GetUnlockNeedCnt()
+    
+    if unlockWay == UnlockWay_Item:
+        needItemID = unlockValue
+        needItemCnt = unlockNeedCnt
+        itemCount = ItemControler.GetItemCountByID(curPlayer, needItemID)
+        if itemCount < needItemCnt:
+            GameWorld.DebugLog("激活红颜物品不足! beautyID=%s,needItemID=%s,itemCount=%s < %s" % (beautyID, needItemID, itemCount, needItemCnt), playerID)
+            return
+        ItemControler.DelItemCountByID(curPlayer, needItemID, needItemCnt)
+        
+    elif unlockWay == UnlockWay_TaskID:
+        taskID = unlockValue
+        if not PlayerTask.IsTaskFinish(curPlayer, taskID):
+            GameWorld.DebugLog("激活红颜所需任务未完成! beautyID=%s,taskID=%s" % (beautyID, taskID), playerID)
+            return
+        
+    elif unlockWay == UnlockWay_ArenaWinCnt:
+        needWinCnt = unlockNeedCnt
+        winCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaWinCnt)
+        if winCnt < needWinCnt:
+            GameWorld.DebugLog("激活红颜所需演武场胜利次数不足! beautyID=%s,winCnt=%s < %s" % (beautyID, winCnt, needWinCnt), playerID)
+            return
+        
+    elif unlockWay == UnlockWay_GoldRushWorker:
+        needWorkerCnt = unlockNeedCnt
+        workerTotal = PlayerGoldRush.GetWorkerTotal(curPlayer)
+        if workerTotal < needWorkerCnt:
+            GameWorld.DebugLog("激活红颜所需监工不足! beautyID=%s,workerTotal=%s < %s" % (beautyID, workerTotal, needWorkerCnt), playerID)
+            return
+        
+    elif unlockWay == UnlockWay_FBZhanchui:
+        mapID = ChConfig.Def_FBMapID_Zhanchui
+        funcLineID = unlockValue
+        isPass = FBCommon.IsFBPass(curPlayer, mapID, funcLineID)
+        if not isPass:
+            GameWorld.DebugLog("激活红颜所需副本未过关! beautyID=%s,mapID=%s,funcLineID=%s" % (beautyID, mapID, funcLineID), playerID)
+            return
+        
+    elif unlockWay == UnlockWay_OfficialRank:
+        realmLV = curPlayer.GetOfficialRank()
+        needRealmLV = unlockValue
+        if realmLV < needRealmLV:
+            GameWorld.DebugLog("激活红颜所需官职不足! beautyID=%s,realmLV=%s < %s" % (beautyID, realmLV, needRealmLV), playerID)
+            return
+        
+    elif unlockWay == UnlockWay_TravelCnt:
+        travelCnt = 0
+        needTravelCnt = unlockNeedCnt
+        if travelCnt < needTravelCnt:
+            GameWorld.DebugLog("激活红颜所需游历次数不足! beautyID=%s,travelCnt=%s < %s" % (beautyID, travelCnt, needTravelCnt), playerID)
+            return
+        
+    else:
+        GameWorld.DebugLog("该红颜不支持激活! beautyID=%s,unlockWay=%s" % (beautyID, unlockWay), playerID)
+        return
+    
+    DoBeautyActivate(curPlayer, beautyID)
+    return
+
+def DoBeautyActivate(curPlayer, beautyID):
+    ## 执行激活红颜逻辑
+    if GetBeautyState(curPlayer, beautyID):
+        return
+    lv, exp = 0, 0
+    SetBeautyState(curPlayer, beautyID, 1)
+    SetBeautyLVInfo(curPlayer, beautyID, lv, exp)
+    GameWorld.DebugLog("红颜激活成功! beautyID=%s" % beautyID, curPlayer.GetPlayerID())
+    RefreshBeautyAttr(curPlayer)
+    SyncBeautyInfo(curPlayer, [beautyID])
+    return
+
+#// B2 20 红颜好感度升级 #tagCSBeautyLVUP
+#
+#struct    tagCSBeautyLVUP
+#{
+#    tagHead         Head;
+#    WORD        BeautyID;    //红颜ID
+#    DWORD        ItemID;        //使用物品ID
+#    BYTE        IsQuick;        // 是否快速升级,0-只消耗1个道具;1-消耗升1级的道具
+#};
+def OnBeautyLVUP(index, curPackData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    beautyID = curPackData.BeautyID
+    itemID = curPackData.ItemID
+    isQuick = curPackData.IsQuick
+    
+    if not GetBeautyState(curPlayer, beautyID):
+        GameWorld.DebugLog("红颜未激活! beautyID=%s" % beautyID, playerID)
+        return
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("Beauty", beautyID)
+    if not ipyData:
+        return
+    quality = ipyData.GetBeautyQuality()
+    curLV, curExp = GetBeautyLVInfo(curPlayer, beautyID)
+    
+    isCommItem = True # 是否使用的常规通用物品
+    commItemIDList = IpyGameDataPY.GetFuncEvalCfg("BeautyLVUP", 1)
+    commExpList = IpyGameDataPY.GetFuncEvalCfg("BeautyLVUP", 2)
+    if itemID in commItemIDList:
+        index = commItemIDList.index(itemID)
+        perExp = commExpList[index] if len(commExpList) > index else 0
+    else:
+        isCommItem = False
+        unlockWay = ipyData.GetUnlockWay()
+        unlockValue = ipyData.GetUnlockValue()
+        if unlockWay != UnlockWay_Item:
+            GameWorld.DebugLog("非道具激活的不支持专属信物ID升级! beautyID=%s,unlockWay=%s" % (beautyID, unlockWay), playerID)
+            return
+        if itemID != unlockValue:
+            GameWorld.DebugLog("非该红颜专属信物ID! beautyID=%s,itemID=%s != %s" % (beautyID, itemID, unlockValue), playerID)
+            return
+        perExp = IpyGameDataPY.GetFuncCfg("BeautyLVUP", 3)
+        
+    if perExp <= 0:
+        return
+    
+    nextLV = curLV + 1
+    nextLVIpyData = IpyGameDataPY.GetIpyGameData("BeautyQualityLV", quality, nextLV)
+    if not nextLVIpyData:
+        GameWorld.DebugLog("红颜已满级! beautyID=%s,quality=%s,curLV=%s" % (beautyID, quality, curLV), playerID)
+        return
+    lvNeedExp = nextLVIpyData.GetLVNeedExp()
+    
+    costItemCount = 0
+    needExp = lvNeedExp - curExp # 升级还需经验
+    if needExp > 0:
+        if isQuick:
+            costItemCount = needExp / perExp
+            if needExp % perExp > 0:
+                costItemCount += 1
+        else:
+            costItemCount = 1
+            
+        if costItemCount < 1:
+            return
+        
+        if isCommItem:
+            costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, itemID, costItemCount)
+            lackCnt = costItemCount - bindCnt - unBindCnt
+            if lackCnt > 0:
+                costItemCount -= lackCnt
+                GameWorld.DebugLog("消耗道具不足,有多少消耗多少! itemID=%s,costItemCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s" 
+                                   % (itemID, costItemCount, bindCnt, unBindCnt, lackCnt))
+            # 扣除消耗
+            if costItemCount > 0:
+                ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, costItemCount, "Beauty")
+        else:
+            itemCount = ItemControler.GetItemCountByID(curPlayer, itemID)
+            if itemCount < costItemCount:
+                costItemCount = itemCount
+                
+            if costItemCount > 0:
+                ItemControler.SetItemCountByID(curPlayer, itemID, itemCount - costItemCount)
+                
+    addExp = costItemCount * perExp
+    updExp = curExp + addExp
+    GameWorld.DebugLog("红颜加经验: beautyID=%s,quality=%s,curLV=%s,curExp=%s,addExp=%s,updExp=%s/%s,itemID=%s,costItemCount=%s,perExp=%s" 
+                       % (beautyID, quality, curLV, curExp, addExp, updExp, lvNeedExp, itemID, costItemCount, perExp))
+    
+    updLV = curLV
+    if updExp >= lvNeedExp:
+        updExp -= lvNeedExp
+        updLV += 1
+        GameWorld.DebugLog("    升级: updLV=%s,updExp=%s" % (updLV, updExp))
+        
+    SetBeautyLVInfo(curPlayer, beautyID, updLV, updExp)
+    
+    SyncBeautyInfo(curPlayer, [beautyID])
+    
+    # 有升级额外处理
+    if updLV > updLV:
+        RefreshBeautyAttr(curPlayer)
+        
+    return
+
+def GetBeautyLVAward(curPlayer, beautyID):
+    ## 领取红颜等级奖励
+    if not GetBeautyState(curPlayer, beautyID):
+        GameWorld.DebugLog("红颜未激活! beautyID=%s" % beautyID)
+        return
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("Beauty", beautyID)
+    if not ipyData:
+        return
+    quality = ipyData.GetBeautyQuality()
+    
+    curLV = GetBeautyLVInfo(curPlayer, beautyID)[0]
+    awardLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautyAwardLV % beautyID)
+    if awardLV >= curLV:
+        GameWorld.DebugLog("当前没有红颜等级奖励可领取! beautyID=%s,quality=%s,awardLV=%s >= curLV=%s" % (beautyID, quality, awardLV, curLV))
+        return
+    GameWorld.DebugLog("领取红颜等级奖励: beautyID=%s,quality=%s,curLV=%s,awardLV=%s" % (beautyID, quality, curLV, awardLV))
+    
+    updAwardLV = awardLV
+    itemDict = {}
+    for getLV in range(awardLV + 1, curLV + 1):
+        lvIpyData = IpyGameDataPY.GetIpyGameData("BeautyQualityLV", quality, getLV)
+        if not lvIpyData:
+            break
+        itemList = lvIpyData.GetAwardItemList()
+        for itemInfo in itemList:
+            itemID = itemInfo[0]
+            itemCount = itemInfo[1]
+            itemDict[itemID] = itemDict.get(itemID, 0) + itemCount
+        updAwardLV = getLV
+        
+    if not itemDict:
+        return
+    awardItemList = [[itemID, itemCount] for itemID, itemCount in itemDict.items()]
+    GameWorld.DebugLog("    updAwardLV=%s,awardItemList=%s" % (updAwardLV, awardItemList))
+    
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BeautyAwardLV % beautyID, updAwardLV)
+    SyncBeautyInfo(curPlayer, [beautyID])
+    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["BeautyLVAward", False, {}])
+    return
+
+#// B2 21 红颜时装操作 #tagCSBeautySkinOP
+#
+#struct    tagCSBeautySkinOP
+#{
+#    tagHead         Head;
+#    WORD        BeautyID;    //红颜ID
+#    WORD        SkinID;        //时装ID
+#    BYTE        OPType;        //操作 1-激活;2-佩戴;3-升星
+#};
+def OnBeautySkinOP(index, curPackData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    beautyID = curPackData.BeautyID
+    skinID = curPackData.SkinID
+    opType = curPackData.OPType
+    
+    if not GetBeautyState(curPlayer, beautyID):
+        GameWorld.DebugLog("红颜未激活! beautyID=%s" % beautyID, playerID)
+        return
+    
+    if opType == 1:
+        OnBeautySkinActivate(curPlayer, beautyID, skinID)
+    elif opType == 2:
+        OnUseBeautySkin(curPlayer, beautyID, skinID)
+    elif opType == 3:
+        OnBeautySkinStarUP(curPlayer, beautyID, skinID)
+    return
+
+def GetBeautySkinIpyData(curPlayer, beautyID, skinID):
+    ipyDataList = IpyGameDataPY.GetIpyGameDataList("BeautySkin", beautyID)
+    if not ipyDataList:
+        return
+    for ipyData in ipyDataList:
+        if ipyData.GetSkinID() == skinID:
+            return ipyData
+    return
+
+def OnBeautySkinActivate(curPlayer, beautyID, skinID):
+    ## 红颜时装激活
+    if GetBeautySkinState(curPlayer, skinID):
+        GameWorld.DebugLog("红颜皮肤已激活! beautyID=%s,skinID=%s" % (beautyID, skinID))
+        return
+    
+    ipyData = GetBeautySkinIpyData(curPlayer, beautyID, skinID)
+    if not ipyData:
+        return
+    unlockWay = ipyData.GetUnlockWay()
+    unlockValue = ipyData.GetUnlockValue()
+    unlockNeedCnt = ipyData.GetUnlockNeedCnt()
+    
+    if unlockWay == UnlockWaySkin_Item:
+        needItemID = unlockValue
+        needItemCnt = unlockNeedCnt
+        itemCount = ItemControler.GetItemCountByID(curPlayer, needItemID)
+        if itemCount < needItemCnt:
+            GameWorld.DebugLog("激活红颜时装物品不足! beautyID=%s,needItemID=%s,itemCount=%s < %s" % (beautyID, needItemID, itemCount, needItemCnt))
+            return
+        ItemControler.DelItemCountByID(curPlayer, needItemID, needItemCnt)
+        
+    else:
+        GameWorld.DebugLog("红颜皮肤不需要激活! beautyID=%s,skinID=%s" % (beautyID, skinID))
+        return
+    
+    SetBeautySkinState(curPlayer, skinID, 1)
+    GameWorld.DebugLog("红颜皮肤激活: beautyID=%s,skinID=%s" % (beautyID, skinID))
+    RefreshBeautyAttr(curPlayer)
+    SyncBeautyInfo(curPlayer, [beautyID], [skinID])
+    return
+
+def OnUseBeautySkin(curPlayer, beautyID, skinID):
+    playerID = curPlayer.GetPlayerID()
+    if not IsBeautySkinCanUse(curPlayer, beautyID, skinID):
+        GameWorld.DebugLog("该红颜时装不可用! beautyID=%s,skinID=%s" % (beautyID, skinID), playerID)
+        return
+    GameWorld.DebugLog("穿戴 红颜时装! beautyID=%s,skinID=%s" % (beautyID, skinID), playerID)
+    ipyDataList = IpyGameDataPY.GetIpyGameDataList("BeautySkin", beautyID)
+    if not ipyDataList:
+        return
+    skinIDList = []
+    for ipyData in ipyDataList:
+        ipySkinID = ipyData.GetSkinID()
+        if ipySkinID == skinID:
+            SetBeautySkinUsed(curPlayer, skinID, 1)
+        elif GetBeautySkinUsed(curPlayer, ipySkinID):
+            SetBeautySkinUsed(curPlayer, ipySkinID, 0)
+        else:
+            continue
+        skinIDList.append(ipySkinID)
+    SyncBeautyInfo(curPlayer, [beautyID], skinIDList)
+    return
+
+def OnBeautySkinStarUP(curPlayer, beautyID, skinID):
+    playerID = curPlayer.GetPlayerID()
+    if not IsBeautySkinCanUse(curPlayer, beautyID, skinID):
+        GameWorld.DebugLog("该红颜时装不可用! beautyID=%s,skinID=%s" % (beautyID, skinID), playerID)
+        return
+    ipyData = GetBeautySkinIpyData(curPlayer, beautyID, skinID)
+    if not ipyData:
+        return
+    starMax = ipyData.GetStarMax()
+    curStar = GetBeautySkinStar(curPlayer, skinID)
+    if curStar >= starMax:
+        GameWorld.DebugLog("红颜时装星级已满! skinID=%s,curStar=%s >= %s" % (skinID, curStar, starMax), playerID)
+        return
+    if ipyData.GetUnlockWay() != UnlockWaySkin_Item:
+        return
+    needItemID = ipyData.GetUnlockValue()
+    needItemCnt = ipyData.GetUpNeedCnt()
+    if not needItemID or not needItemCnt:
+        return
+    itemCount = ItemControler.GetItemCountByID(curPlayer, needItemID)
+    if itemCount < needItemCnt:
+        GameWorld.DebugLog("红颜时装升星物品不足! skinID=%s,needItemID=%s,itemCount=%s < %s" % (skinID, needItemID, itemCount, needItemCnt))
+        return
+    ItemControler.DelItemCountByID(curPlayer, needItemID, needItemCnt)
+    
+    nextStar = curStar + 1
+    GameWorld.DebugLog("红颜时装升星! skinID=%s,nextStar=%s" % (skinID, nextStar), playerID)
+    SetBeautySkinStar(curPlayer, skinID, nextStar)
+    RefreshBeautyAttr(curPlayer)
+    SyncBeautyInfo(curPlayer, [beautyID], [skinID])
+    return
+
+def RefreshBeautyAttr(curPlayer):
+    CalcBeautyAttr(curPlayer)
+    PlayerOnline.GetOnlinePlayer(curPlayer).RefreshRoleAttr()
+    return
+
+def CalcBeautyAttr(curPlayer):
+    
+    playerID = curPlayer.GetPlayerID()
+    attrDict = {}
+    effTypeDict = {} # 特殊效果缓存
+    
+    talentLVUPPer = IpyGameDataPY.GetFuncCfg("BeautyLVUP", 4) # 每x级好感度提升一级天赋效果
+    
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for index in range(ipyDataMgr.GetBeautyCount()):
+        ipyData = ipyDataMgr.GetBeautyByIndex(index)
+        beautyID = ipyData.GetBeautyID()
+        if not GetBeautyState(curPlayer, beautyID):
+            continue
+        quality = ipyData.GetBeautyQuality()
+        beautyLV = GetBeautyLVInfo(curPlayer, beautyID)[0]
+        # 等级属性
+        for lv in range(beautyLV + 1):
+            lvIpyData = IpyGameDataPY.GetIpyGameData("BeautyQualityLV", quality, lv)
+            if not lvIpyData:
+                continue
+            lvAttrIDList = lvIpyData.GetAttrIDList()
+            lvAttrValueList = lvIpyData.GetAttrValueList()
+            for lvIndex, attrID in enumerate(lvAttrIDList):
+                attrValue = lvAttrValueList[lvIndex] if len(lvAttrValueList) > lvIndex else 0
+                attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
+        #GameWorld.DebugLog("红颜等级属性: beautyID=%s,quality=%s,beautyLV=%s,%s" % (beautyID, quality, beautyLV, attrDict), playerID)
+        
+        # 天赋属性
+        talentAttrIDList = ipyData.GetTalentAttrIDList()
+        talentAttrValueList = ipyData.GetTalentAttrValueList()
+        talentPerLVAddList = ipyData.GetTalentPerLVAddList()
+        talentLV = beautyLV / talentLVUPPer
+        for tIndex, attrID in enumerate(talentAttrIDList):
+            initValue = talentAttrValueList[tIndex] if len(talentAttrValueList) > tIndex else 0
+            perLVAdd = talentPerLVAddList[tIndex] if len(talentPerLVAddList) > tIndex else 0
+            attrValue = initValue + perLVAdd * talentLV
+            attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
+        #GameWorld.DebugLog("红颜天赋属性: beautyID=%s,talentLV=%s,%s" % (beautyID, talentLV, attrDict), playerID)
+        
+        # 特殊效果
+        effType = ipyData.GetEffType()
+        effTypeValue = ipyData.GetEffTypeValue()
+        effValue = ipyData.GetEffValue()
+        effPerLVAdd = ipyData.GetEffPerLVAdd()
+        if effType:
+            effValue = effValue + effPerLVAdd * talentLV
+            effTypeDict[effType] = [effValue, effTypeValue]
+            #GameWorld.DebugLog("红颜特殊效果: beautyID=%s,effType=%s,talentLV=%s,%s" % (beautyID, effType, talentLV, effTypeDict), playerID)
+            
+        # 时装
+        ipyDataList = IpyGameDataPY.GetIpyGameDataList("BeautySkin", beautyID)
+        if not ipyDataList:
+            continue
+        for skinIpyData in ipyDataList:
+            skinID = skinIpyData.GetSkinID()
+            if not IsBeautySkinCanUse(curPlayer, beautyID, skinID, skinIpyData):
+                continue
+            
+            attrIDList = skinIpyData.GetAttrIDList()
+            initAttrValueList = skinIpyData.GetInitAttrValueList()
+            perStarAddList = skinIpyData.GetAttrPerStarAddList()
+            star = GetBeautySkinStar(curPlayer, skinID)
+            for sIndex, attrID in enumerate(attrIDList):
+                initValue = initAttrValueList[sIndex] if len(initAttrValueList) > sIndex else 0
+                perStarAdd = perStarAddList[sIndex] if len(perStarAddList) > sIndex else 0
+                attrValue = initValue + perStarAdd * star
+                attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
+            #GameWorld.DebugLog("红颜时装属性: beautyID=%s,skinID=%s,star=%s,%s" % (beautyID, skinID, star, attrDict), playerID)
+            
+    # 保存计算值
+    GameWorld.DebugLog("红颜属性: %s" % attrDict, playerID)
+    GameWorld.DebugLog("红颜效果: %s" % effTypeDict, playerID)
+    PyGameData.g_beautyEffTypeDict[playerID] = effTypeDict
+    PlayerOnline.GetOnlinePlayer(curPlayer).SetCalcAttr(ChConfig.Def_CalcAttr_Beauty, attrDict)
+    return
+
+def GetBeautyEffInfo(curPlayer, effType):
+    ## 获取红颜特殊效果信息
+    # @return: effValue, effTypeValue
+    effTypeDict = PyGameData.g_beautyEffTypeDict.get(curPlayer.GetPlayerID(), {})
+    return effTypeDict.get(effType, [0, 0])
+
+def SyncBeautyInfo(curPlayer, beautyIDList=None, skinIDList=None):
+    if beautyIDList == None:
+        syncBeautyIDList = []
+        ipyDataMgr = IpyGameDataPY.IPY_Data()
+        for index in range(ipyDataMgr.GetBeautyCount()):
+            ipyData = ipyDataMgr.GetBeautyByIndex(index)
+            syncBeautyIDList.append(ipyData.GetBeautyID())
+    else:
+        syncBeautyIDList = beautyIDList
+        
+    beautyList = []
+    for beautyID in syncBeautyIDList:
+        state = GetBeautyState(curPlayer, beautyID)
+        if not state and beautyIDList == None:
+            continue
+        lv, exp = GetBeautyLVInfo(curPlayer, beautyID)
+        beauty = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBeauty)
+        beauty.BeautyID = beautyID
+        beauty.State = state
+        beauty.LV = lv
+        beauty.Exp = exp
+        beauty.AwardLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautyAwardLV % beautyID)
+        
+        beauty.SkinList = []
+        ipyDataList = IpyGameDataPY.GetIpyGameDataList("BeautySkin", beautyID)
+        if ipyDataList:
+            for ipyData in ipyDataList:
+                skinID = ipyData.GetSkinID()
+                skinInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BeautySkinInfo % skinID)
+                if skinIDList != None:
+                    if skinID not in skinIDList:
+                        continue
+                else:
+                    if not skinInfo:
+                        continue
+                beautySkin = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBeautySkin)
+                beautySkin.SkinID = skinID
+                beautySkin.State = 1 if IsBeautySkinCanUse(curPlayer, beautyID, skinID, ipyData) else 0
+                beautySkin.Used = GetBeautySkinUsed(curPlayer, skinID)
+                beautySkin.Star = GetBeautySkinStar(curPlayer, skinID)
+                beauty.SkinList.append(beautySkin)
+        beauty.SkinCnt = len(beauty.SkinList)
+        
+        beautyList.append(beauty)
+        
+    if not beautyList:
+        return
+    
+    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBeautyInfo)
+    clientPack.BeautyList = beautyList
+    clientPack.Count = len(clientPack.BeautyList)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerChatBox.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerChatBox.py
index 5142697..92745ec 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerChatBox.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerChatBox.py
@@ -206,7 +206,7 @@
     if ipyData.GetUnlockWay() != 2:
         return
     itemID = ipyData.GetUnlockValue()
-    itemCount = ipyData.GetUnlockNeedCnt()
+    itemCount = ipyData.GetUpNeedCnt()
     if not itemID or not itemCount:
         return
     needItemList = [[itemID, itemCount]]
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFace.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFace.py
index e252abc..96b370e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFace.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFace.py
@@ -219,7 +219,7 @@
     if ipyData.GetUnlockWay() != 2:
         return
     itemID = ipyData.GetUnlockValue()
-    itemCount = ipyData.GetUnlockNeedCnt()
+    itemCount = ipyData.GetUpNeedCnt()
     if not itemID or not itemCount:
         return
     needItemList = [[itemID, itemCount]]
@@ -419,7 +419,7 @@
     if ipyData.GetUnlockWay() != 2:
         return
     itemID = ipyData.GetUnlockValue()
-    itemCount = ipyData.GetUnlockNeedCnt()
+    itemCount = ipyData.GetUpNeedCnt()
     if not itemID or not itemCount:
         return
     needItemList = [[itemID, itemCount]]
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGoldRush.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGoldRush.py
index 0966036..1d67bb6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGoldRush.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGoldRush.py
@@ -269,13 +269,7 @@
             if campID != cID:
                 atWorkCnt += wCnt
             
-    workersTotal = 0 # 总工人数
-    workerState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWorkerState)
-    for index in range(ipyDataMgr.GetGoldRushWorkerCount()):
-        ipyData = ipyDataMgr.GetGoldRushWorkerByIndex(index)
-        workerID = ipyData.GetWorkerID()
-        if workerState & pow(2, workerID):
-            workersTotal += 1
+    workersTotal = GetWorkerTotal(curPlayer) # 总工人数
     idleWorkers = workersTotal - atWorkCnt # 空闲工人数
     if idleWorkers <= 0:
         GameWorld.DebugLog("没有空闲工人,无法开始淘金! atWorkCnt=%s >= %s" % (atWorkCnt, workersTotal))
@@ -323,6 +317,18 @@
                        % (updWorkerCnt, realNeedSeconds, GameWorld.ChangeTimeNumToStr(endTime), campInfo))
     return
 
+def GetWorkerTotal(curPlayer):
+    ## 获取监工总数
+    workersTotal = 0 # 总工人数
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    workerState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GoldRushWorkerState)
+    for index in range(ipyDataMgr.GetGoldRushWorkerCount()):
+        ipyData = ipyDataMgr.GetGoldRushWorkerByIndex(index)
+        workerID = ipyData.GetWorkerID()
+        if workerState & pow(2, workerID):
+            workersTotal += 1
+    return workersTotal
+
 def __onGoldRushCancel(curPlayer, campID):
     ## 取消
     refreshCnt, goldID, workerCnt = GetCampInfo(curPlayer, campID)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHJG.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHJG.py
index bdf5c14..2275cca 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHJG.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHJG.py
@@ -401,7 +401,7 @@
     if ipyData.GetUnlockWay() != 2:
         return
     itemID = ipyData.GetUnlockValue()
-    itemCount = ipyData.GetUnlockNeedCnt()
+    itemCount = ipyData.GetUpNeedCnt()
     if not itemID or not itemCount:
         return
     needItemList = [[itemID, itemCount]]
@@ -623,7 +623,7 @@
     if ipyData.GetUnlockWay() != 2:
         return
     itemID = ipyData.GetUnlockValue()
-    itemCount = ipyData.GetUnlockNeedCnt()
+    itemCount = ipyData.GetUpNeedCnt()
     if not itemID or not itemCount:
         return
     needItemList = [[itemID, itemCount]]
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py
index 85b2211..c7316af 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py
@@ -437,7 +437,7 @@
     if ipyData.GetUnlockWay() != 2:
         return
     itemID = ipyData.GetUnlockValue()
-    itemCount = ipyData.GetUnlockNeedCnt()
+    itemCount = ipyData.GetUpNeedCnt()
     if not itemID or not itemCount:
         return
     needItemList = [[itemID, itemCount]]
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
index a2775f6..213bb6a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
@@ -24,6 +24,7 @@
 import IpyGameDataPY
 import FormulaControl
 import PlayerPrestigeSys
+import PlayerBeauty
 import PlayerFamily
 import PlayerHorse
 import PlayerGubao
@@ -422,6 +423,7 @@
     PlayerGubao.CalcGubaoAttr(curPlayer)
     PlayerHJG.CalcHJGAttr(curPlayer)
     PlayerHorse.CalcHorseAttr(curPlayer)
+    PlayerBeauty.CalcBeautyAttr(curPlayer)
     return
 
 def doRefreshLineupAttr(curPlayer, olPlayer, lineup):
@@ -647,6 +649,7 @@
     gubaoAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_Gubao)
     hjgAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_HJG)
     horseAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_Horse)
+    beautyAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_Beauty)
     
     GameWorld.DebugLog("    国家武将统计=%s" % countryHeroInfo, playerID)
     GameWorld.DebugLog("    羁绊武将统计=%s" % fetterHeroInfo, playerID)
@@ -665,6 +668,7 @@
     GameWorld.DebugLog("    主公古宝属性=%s" % gubaoAttrDict, playerID)
     GameWorld.DebugLog("    主幻境阁属性=%s" % hjgAttrDict, playerID)
     GameWorld.DebugLog("    主公坐骑属性=%s" % horseAttrDict, playerID)
+    GameWorld.DebugLog("    主公红颜属性=%s" % beautyAttrDict, playerID)
     
     PlayerLV = curPlayer.GetLV()
     OfficialLV = curPlayer.GetOfficialRank()
@@ -708,6 +712,9 @@
             horseValue = horseAttrDict.get(attrID, 0)
             horsePer = horseAttrDict.get(attrPerID, 0) / 10000.0 if attrPerID else 0
             
+            beautyValue = beautyAttrDict.get(attrID, 0)
+            beautyPer = beautyAttrDict.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
@@ -734,7 +741,8 @@
                 
             # 计算
             attrParamDict = {"lvValue":lvValue, "equipValue":equipValue, "bookValue":bookValue, "bookPer":bookPer, "realmValue":realmValue, "realmPer":realmPer, 
-                             "gubaoValue":gubaoValue, "gubaoPer":gubaoPer, "hjgValue":hjgValue, "hjgPer":hjgPer, "horseValue":horseValue, "horsePer":horsePer,
+                             "gubaoValue":gubaoValue, "gubaoPer":gubaoPer, "hjgValue":hjgValue, "hjgPer":hjgPer, "horseValue":horseValue, "horsePer":horsePer, 
+                             "beautyValue":beautyValue, "beautyPer":beautyPer,
                              "lineupInitAddPer":lineupInitAddPer, "lineupLVAddPer":lineupLVAddPer, "lineupBreakLVAddPer":lineupBreakLVAddPer, "lineupStarAddPer":lineupStarAddPer,
                              "heroSelfValue":heroSelfValue, "heroSelfPer":heroSelfPer, "inheritPer":inheritPer,
                              "lineupHaloValue":lineupHaloValue, "lineupHaloPer":lineupHaloPer, "fetterValue":fetterValue, "fetterPer":fetterPer,
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index 91e18f4..2247e69 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -37,6 +37,8 @@
 
 g_arenaPlayerMatchDict = {} # 本服竞技场玩家匹配记录缓存 {playerID:[tagPlayerID, ...], ...}
 
+g_beautyEffTypeDict = {} # 红颜特殊效果缓存 {playerID:{effType:[effValue, effTypeValue], ...}, ...}
+
 g_mapIDTxtInfo = {} # MapID.txt 加载的信息
 g_realmDiffPlayerDict = {} # 境界难度玩家信息 {realm:[playerID, ...], ...}
 g_realmDiffNPCRefresh = {} # {(lineID, realm):{refreshID:tagNPCRefresh, ...}}

--
Gitblit v1.8.0