From 2a659639d74889599ed54458863a2f7b31ff4eff Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 29 九月 2023 01:54:33 +0800
Subject: [PATCH] 9946 【BT0.1】【主干】仙盟BOSS修改

---
 ServerPython/CoreServerGroup/GameServer/PyNetPack.ini                                                                |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_FamilyBoss.py |  661 ++++++++++-----------
 ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py                                                      |   26 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py                           |   78 --
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                                   |    2 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py                                                    |    4 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py                                                 |   18 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py                                   |  100 ---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py                               |  128 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                                    |    3 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py                                                        |  100 ---
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                                    |  128 ++++
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py                                                |   19 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_FamilyBoss.py        |   50 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                                           |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py                                 |   26 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py                               |    4 
 PySysDB/PySysDBPY.h                                                                                                  |   10 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py                                            |  378 +++++-------
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                                        |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py                     |    7 
 PySysDB/PySysDBG.h                                                                                                   |   10 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                      |   15 
 23 files changed, 889 insertions(+), 892 deletions(-)

diff --git a/PySysDB/PySysDBG.h b/PySysDB/PySysDBG.h
index d61ad48..f129180 100644
--- a/PySysDB/PySysDBG.h
+++ b/PySysDB/PySysDBG.h
@@ -39,6 +39,16 @@
 	BYTE		BossFBCnt;	//BOSS副本次数
 };
 
+//仙盟试炼伤血奖励表
+
+struct tagFamilyBossHurtAward
+{
+	BYTE		_AwardType;	//奖励类型 1-个人;2-仙盟
+	BYTE		_RecordIndex;	//奖励记录索引,同奖励类型时记录索引不可重复
+	DWORD		NeedHurtTotal;	//所需总伤血
+	list		AwardItemList;	//奖励物品列表[[物品ID,个数,是否拍品], ...]
+};
+
 //集市查询表
 
 struct tagMarketQuery
diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index a5ef948..0236cce 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -2555,6 +2555,16 @@
 	dict		Award2;	//饼图奖励{随机次数:[(概率,[物品ID,数量,是否拍品]),..]}
 };
 
+//仙盟试炼伤血奖励表
+
+struct tagFamilyBossHurtAward
+{
+	BYTE		_AwardType;	//奖励类型 1-个人;2-仙盟
+	BYTE		_RecordIndex;	//奖励记录索引,同奖励类型时记录索引不可重复
+	DWORD		NeedHurtTotal;	//所需总伤血
+	list		AwardItemList;	//奖励物品列表[[物品ID,个数,是否拍品], ...]
+};
+
 //装备洗练等级上限
 
 struct tagItemWashMax
diff --git a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
index cfc70b8..5b9405c 100644
--- a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
+++ b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
@@ -53,9 +53,9 @@
 PacketSubCMD_3=0x03
 PacketCallFunc_3=AddFamilyReply
 
-PacketCMD_4=0xA4
-PacketSubCMD_4=0x05
-PacketCallFunc_4=OpenFamilyBossFB
+PacketCMD_4=
+PacketSubCMD_4=
+PacketCallFunc_4=
 
 PacketCMD_5=0xA4
 PacketSubCMD_5=0x06
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index ffcc7ac..04f4a00 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -706,58 +706,6 @@
 
 
 #------------------------------------------------------
-# A4 05 开启家族boss副本 #tagCGOpenFamilyBossFB
-
-class  tagCGOpenFamilyBossFB(Structure):
-    _pack_ = 1
-    _fields_ = [
-                  ("Cmd", c_ubyte),
-                  ("SubCmd", c_ubyte),
-                  ("MapID", c_int),    # 开启的副本地图ID
-                  ]
-
-    def __init__(self):
-        self.Clear()
-        self.Cmd = 0xA4
-        self.SubCmd = 0x05
-        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 = 0xA4
-        self.SubCmd = 0x05
-        self.MapID = 0
-        return
-
-    def GetLength(self):
-        return sizeof(tagCGOpenFamilyBossFB)
-
-    def GetBuffer(self):
-        return string_at(addressof(self), self.GetLength())
-
-    def OutputString(self):
-        DumpString = '''// A4 05 开启家族boss副本 //tagCGOpenFamilyBossFB:
-                                Cmd:%s,
-                                SubCmd:%s,
-                                MapID:%d
-                                '''\
-                                %(
-                                self.Cmd,
-                                self.SubCmd,
-                                self.MapID
-                                )
-        return DumpString
-
-
-m_NAtagCGOpenFamilyBossFB=tagCGOpenFamilyBossFB()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGOpenFamilyBossFB.Cmd,m_NAtagCGOpenFamilyBossFB.SubCmd))] = m_NAtagCGOpenFamilyBossFB
-
-
-#------------------------------------------------------
 # A4 04 创建家族 #tagCGPyCreatFamily
 
 class  tagCGPyCreatFamily(Structure):
@@ -13946,54 +13894,6 @@
 
 m_NAtagCMFamilyActivityExchange=tagCMFamilyActivityExchange()
 ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMFamilyActivityExchange.Head.Cmd,m_NAtagCMFamilyActivityExchange.Head.SubCmd))] = m_NAtagCMFamilyActivityExchange
-
-
-#------------------------------------------------------
-# A6 05  家族捐献兽粮 #tagCMFamilyDonate
-
-class  tagCMFamilyDonate(Structure):
-    _pack_ = 1
-    _fields_ = [
-                  ("Cmd", c_ubyte),
-                  ("SubCmd", c_ubyte),
-                  ]
-
-    def __init__(self):
-        self.Clear()
-        self.Cmd = 0xA6
-        self.SubCmd = 0x05
-        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 = 0xA6
-        self.SubCmd = 0x05
-        return
-
-    def GetLength(self):
-        return sizeof(tagCMFamilyDonate)
-
-    def GetBuffer(self):
-        return string_at(addressof(self), self.GetLength())
-
-    def OutputString(self):
-        DumpString = '''// A6 05  家族捐献兽粮 //tagCMFamilyDonate:
-                                Cmd:%s,
-                                SubCmd:%s
-                                '''\
-                                %(
-                                self.Cmd,
-                                self.SubCmd
-                                )
-        return DumpString
-
-
-m_NAtagCMFamilyDonate=tagCMFamilyDonate()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMFamilyDonate.Cmd,m_NAtagCMFamilyDonate.SubCmd))] = m_NAtagCMFamilyDonate
 
 
 #------------------------------------------------------
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index 7ca9139..9c95ee6 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -1243,6 +1243,66 @@
 
 
 #------------------------------------------------------
+# A4 0E 家族boss副本信息 #tagGCFamilyBosFBInfo
+
+class  tagGCFamilyBosFBInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("HurtTotal", c_int),    # 仙盟累计伤血,亿求余部分
+                  ("HurtTotalPoint", c_int),    # 仙盟累计伤血,亿整除部分
+                  ("FightMemCount", c_ubyte),    # 目前正在仙盟boss副本中的成员数
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA4
+        self.SubCmd = 0x0E
+        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 = 0xA4
+        self.SubCmd = 0x0E
+        self.HurtTotal = 0
+        self.HurtTotalPoint = 0
+        self.FightMemCount = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagGCFamilyBosFBInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A4 0E 家族boss副本信息 //tagGCFamilyBosFBInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                HurtTotal:%d,
+                                HurtTotalPoint:%d,
+                                FightMemCount:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.HurtTotal,
+                                self.HurtTotalPoint,
+                                self.FightMemCount
+                                )
+        return DumpString
+
+
+m_NAtagGCFamilyBosFBInfo=tagGCFamilyBosFBInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCFamilyBosFBInfo.Cmd,m_NAtagGCFamilyBosFBInfo.SubCmd))] = m_NAtagGCFamilyBosFBInfo
+
+
+#------------------------------------------------------
 # A4 02 家族boss副本开启及击杀信息 #tagGCFamilyBossFBInfo
 
 class  tagGCFamilyBossFBInfo(Structure):
@@ -25962,6 +26022,74 @@
 
 
 #------------------------------------------------------
+# A5 07 家族boss副本玩家信息 #tagMCFamilyBosFBPlayerInfo
+
+class  tagMCFamilyBosFBPlayerInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("HurtTotal", c_int),    # 累计伤血,亿求余部分
+                  ("HurtTotalPoint", c_int),    # 累计伤血,亿整除部分
+                  ("FightSeconds", c_int),    # 已累计战斗时长,秒
+                  ("HurtAwardState", c_int),    # 个人总伤血领奖记录,按奖励位二进制位运算表示是否已领取
+                  ("HurtAwardStateFamily", c_int),    # 仙盟总伤血领奖记录,按奖励位二进制位运算表示是否已领取
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0x07
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xA5
+        self.SubCmd = 0x07
+        self.HurtTotal = 0
+        self.HurtTotalPoint = 0
+        self.FightSeconds = 0
+        self.HurtAwardState = 0
+        self.HurtAwardStateFamily = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCFamilyBosFBPlayerInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 07 家族boss副本玩家信息 //tagMCFamilyBosFBPlayerInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                HurtTotal:%d,
+                                HurtTotalPoint:%d,
+                                FightSeconds:%d,
+                                HurtAwardState:%d,
+                                HurtAwardStateFamily:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.HurtTotal,
+                                self.HurtTotalPoint,
+                                self.FightSeconds,
+                                self.HurtAwardState,
+                                self.HurtAwardStateFamily
+                                )
+        return DumpString
+
+
+m_NAtagMCFamilyBosFBPlayerInfo=tagMCFamilyBosFBPlayerInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCFamilyBosFBPlayerInfo.Cmd,m_NAtagMCFamilyBosFBPlayerInfo.SubCmd))] = m_NAtagMCFamilyBosFBPlayerInfo
+
+
+#------------------------------------------------------
 # A5 06 仙盟每日福利领取状态 #tagMCFamilyDayAward
 
 class  tagMCFamilyDayAward(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
index 65f0b57..24001a4 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
@@ -61,6 +61,13 @@
                         ("BYTE", "BossFBCnt", 0),
                         ),
 
+                "FamilyBossHurtAward":(
+                        ("BYTE", "AwardType", 1),
+                        ("BYTE", "RecordIndex", 1),
+                        ("DWORD", "NeedHurtTotal", 0),
+                        ("list", "AwardItemList", 0),
+                        ),
+
                 "MarketQuery":(
                         ("WORD", "QueryType", 1),
                         ("dict", "LimitInfo", 0),
@@ -969,6 +976,21 @@
     def GetNeedMoney(self): return self.NeedMoney # 升级需要资金
     def GetWeekMissionMoneyMax(self): return self.WeekMissionMoneyMax # 每周任务最大可获得仙盟资金
     def GetBossFBCnt(self): return self.BossFBCnt # BOSS副本次数
+
+# 仙盟试炼伤血奖励表
+class IPY_FamilyBossHurtAward():
+    
+    def __init__(self):
+        self.AwardType = 0
+        self.RecordIndex = 0
+        self.NeedHurtTotal = 0
+        self.AwardItemList = []
+        return
+        
+    def GetAwardType(self): return self.AwardType # 奖励类型 1-个人;2-仙盟
+    def GetRecordIndex(self): return self.RecordIndex # 奖励记录索引,同奖励类型时记录索引不可重复
+    def GetNeedHurtTotal(self): return self.NeedHurtTotal # 所需总伤血
+    def GetAwardItemList(self): return self.AwardItemList # 奖励物品列表[[物品ID,个数,是否拍品], ...]
 
 # 集市查询表
 class IPY_MarketQuery():
@@ -2771,6 +2793,8 @@
         self.ipyWorldLVLen = len(self.ipyWorldLVCache)
         self.ipyFamilyCache = self.__LoadFileData("Family", IPY_Family)
         self.ipyFamilyLen = len(self.ipyFamilyCache)
+        self.ipyFamilyBossHurtAwardCache = self.__LoadFileData("FamilyBossHurtAward", IPY_FamilyBossHurtAward)
+        self.ipyFamilyBossHurtAwardLen = len(self.ipyFamilyBossHurtAwardCache)
         self.ipyMarketQueryCache = self.__LoadFileData("MarketQuery", IPY_MarketQuery)
         self.ipyMarketQueryLen = len(self.ipyMarketQueryCache)
         self.ipyAuctionItemCache = self.__LoadFileData("AuctionItem", IPY_AuctionItem)
@@ -3103,6 +3127,8 @@
     def GetWorldLVByIndex(self, index): return self.ipyWorldLVCache[index]
     def GetFamilyCount(self): return self.ipyFamilyLen
     def GetFamilyByIndex(self, index): return self.ipyFamilyCache[index]
+    def GetFamilyBossHurtAwardCount(self): return self.ipyFamilyBossHurtAwardLen
+    def GetFamilyBossHurtAwardByIndex(self, index): return self.ipyFamilyBossHurtAwardCache[index]
     def GetMarketQueryCount(self): return self.ipyMarketQueryLen
     def GetMarketQueryByIndex(self, index): return self.ipyMarketQueryCache[index]
     def GetAuctionItemCount(self): return self.ipyAuctionItemLen
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
index 86ba160..10bcd77 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -773,10 +773,6 @@
         if not GameWorldFamilyWar.CheckPlayerCanEnterFamilyWarFBMap(curPlayer):
             return
         
-    elif tagMapID == ChConfig.Def_FBMapID_FamilyBossMap:
-        if not PlayerFamilyBoss.CheckIsFamilyBossFBOpen(curPlayer.GetFamilyID(), tagMapID):
-            GameWorld.Log("EnterFBLine mapID=%s is familyBossFB, but is not open!" % tagMapID)
-            return
     #守卫人皇 是否已参加
     elif tagMapID == ChConfig.Def_FBMapID_FamilyInvade:
         if curPlayer.GetFamilyID() in PyGameData.g_swrhJoinRecord:
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py
index ad1322e..be10c3e 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py
@@ -416,8 +416,8 @@
     #通知战盟红包信息
     PlayerFamilyRedPacket.NotifyRedPacketInfo(jionPlayer)
     
-    #通知战盟BOSS开启信息
-    PlayerFamilyBoss.NotifyFamilyBossFBInfo(jionPlayer)
+    #通知战盟BOSS
+    PlayerFamilyBoss.OnPlayerJionFamily(curFamily, jionPlayer)
     #通知家族仓库
     PyDataManager.GetFamilyStoreItemManager().SyncFamilyStoreItem(jionPlayer, curFamily.GetID())
     #仙盟拍品
@@ -2668,6 +2668,8 @@
 #            #帮会日常维持消耗{%S1%}银两帮会资金
 #            PlayerControl.FamilyNotify(family.GetID(), 'jiazu_lhs_272921', [useMoney])
         
+        #仙盟boss
+        PlayerFamilyBoss.FamilyBossFBOnDay(family)
         #通知客户端刷新
         family.Broadcast_FamilyChange()
         #通知地图服务器刷新
@@ -2720,7 +2722,7 @@
         DataRecordPack.DR_FamilyActiveValueByOnWeek(familyID, family.GetName(), familyActiveValue)
         
         #清除家族boss副本信息
-        PlayerFamilyBoss.FamilyBossFBOnWeek(familyID)
+        PlayerFamilyBoss.FamilyBossFBOnWeek(family)
         
     return
 
@@ -3332,17 +3334,6 @@
     PlayerFamilyAction.ViewFamilyRequestInfo(curPlayer)
     return
 
-
-## 开启家族boss副本
-#  @param index 玩家索引
-#  @param clientData 封包数据结构体
-#  @param tick 时间戳
-#  @return None
-def OpenFamilyBossFB(index, clientData, tick):
-    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
-    fbMapID = clientData.MapID
-    PlayerFamilyBoss.OpenFamilyBossFB(curPlayer, tick)
-    return
 #===============================================================================
 # //A4 06 变更家族成员加入审核方式#tagCGChangeFamilyAcceptJoinType
 #struct tagCGChangeFamilyAcceptJoinType
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py
index 717d12e..fe5a6e2 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py
@@ -19,7 +19,7 @@
 
 import PlayerFamilyAction
 import GameWorld
-import PlayerFamily
+import PlayerCompensation
 import ChPyNetSendPack
 import NetPackCommon
 import ShareDefine
@@ -29,251 +29,181 @@
 import ChConfig
 import time
 
-
-
-#value1:已开启次数 value2:是否开启中(0未开启,time值-开启中,2-退出计时中)
-def GetFamilyBossOpenCnt(fActionData): return fActionData.GetValue1()
-def SetFamilyBossOpenCnt(fActionData, cnt): return fActionData.SetValue1(cnt)
-def GetFamilyBossIsOpen(fActionData): return fActionData.GetValue2()
-def SetFamilyBossIsOpen(fActionData, isOpen): return fActionData.SetValue2(isOpen)
-
-def GetFamilyBossLimitCnt(family):
-    '''仙盟BOSS每周次数限制'''
-    return PlayerFamily.GetFamilySetting(family, ChConfig.Def_FamilySetting_BossFBCnt)#IpyGameDataPY.GetFuncCfg('FamilyBossOpen', 4)
-
-def GetFamilyBossCostFood():
-    '''仙盟BOSS开启消耗兽粮'''
-    return IpyGameDataPY.GetFuncCfg('FamilyBossOpen', 2)
-
-    
-def ChekcFamilyBossOpenTime():
-    '''是否在可开启活动的时间内'''
-    beginTime, endTime = IpyGameDataPY.GetFuncEvalCfg('FamilyBossOpen', 3)
-    curTime = GameWorld.GetServerTime()
-    isAtCPing = '%02d:00:00' % endTime > str(curTime)[11:19] > '%02d:00:00' % beginTime
-    return isAtCPing
-
-## 检查家族boss副本是否开启
-#  @param familyID 家族id
-#  @param mapID 地图id
-#  @return True-是
-def CheckIsFamilyBossFBOpen(familyID, mapID):
-    if familyID <= 0:
-        return False
-
-    familyBossFBOpenData = __GetFamilyBossFBActionData(familyID)
-    if not familyBossFBOpenData:
-        return False
-    
-    return GetFamilyBossIsOpen(familyBossFBOpenData)
-    
-
-
-## 家族boss副本OnWeek
-#  @param familyID 家族id
-#  @return None
-def FamilyBossFBOnWeek(familyID):
-    PlayerFamilyAction.ClearFamilyAction(familyID, ShareDefine.Def_ActionType_FamilyBossFB)
-    
-    curFamily = GameWorld.GetFamilyManager().FindFamily(familyID)
-    
-    if not curFamily:
-        GameWorld.ErrLog("FamilyBossFBOnWeek can not find family! familyID=%s" % (familyID))
-        return
-    
-    __Notify_FamilyAllMemberBossFBInfo(curFamily)
+def FamilyBossFBOnWeek(curFamily):
     return
 
+def FamilyBossFBOnDay(curFamily):
+    __FamilyBossFBHurtOnDay(curFamily)
+    return
 
-## 玩家登录,通知家族副本信息
-#  @param curPlayer 玩家实例
-#  @return None
 def OnLogin(curPlayer):
-    NotifyFamilyBossFBInfo(curPlayer)
+    SyncFamilyBosFBInfo(curPlayer.GetFamilyID(), None, curPlayer)
     NotifyAllFamilyBossState(curPlayer)
     return
 
-
-## 开启家族boss副本
-#  @param curPlayer 玩家实例
-#  @param mapID 副本地图id
-#  @param tick 时间
-#  @return None
-def OpenFamilyBossFB(curPlayer, tick):
-    
-    GameWorld.DebugLog("OpenFamilyBossFB", curPlayer.GetPlayerID())
-    
-    curFamily = curPlayer.GetFamily()
-    if curFamily == None:
-        GameWorld.ErrLog("    player not family!", curPlayer.GetPlayerID())
-        return
-    
-    if not ChekcFamilyBossOpenTime():
-        GameWorld.DebugLog("    不在活动时间内")
-        return
-    
-    familyId = curFamily.GetID()
-
-    familyBossFBData = __GetFamilyBossFBActionData(familyId)
-        
-    if not familyBossFBData:
-        GameWorld.ErrLog("    can find Def_ActionType_FamilyBossFB familyId=%s" 
-                                                                % (familyId))
-        return
-    
-    if GetFamilyBossIsOpen(familyBossFBData):
-        GameWorld.DebugLog('    仙盟BOSS已开启,不能再次开启')
-        return
-    
-    curWeekOpenCnt = GetFamilyBossOpenCnt(familyBossFBData)
-    
-    # 次数判断
-    maxOpenCnt = GetFamilyBossLimitCnt(curFamily)
-    if curWeekOpenCnt >= maxOpenCnt:
-        GameWorld.Log("    本周开启次数=%s >= 最大开启次数=%s" % (curWeekOpenCnt, maxOpenCnt))
-        return
-    
-    foodCost = GetFamilyBossCostFood()
-    if not foodCost:
-        GameWorld.ErrLog("    无法找到开启家族boss副本消耗信息 familyId=%s, foodCost=%s" % (familyId, foodCost))
-        return
-    
-    # 处理消耗逻辑等
-    if not __DoOpenCostLogic(curFamily, curPlayer, foodCost):
-        return
-    SetFamilyBossOpenCnt(familyBossFBData, curWeekOpenCnt + 1) # 增加开启次数
-    SetFamilyBossIsOpen(familyBossFBData, 1)
-    
-    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyBossOpenCount, [familyId, curWeekOpenCnt + 1])
-    
-    # 广播给在线家族成员家族boss副本信息
-    __Notify_FamilyAllMemberBossFBInfo(curFamily)
-    GameWorld.Log("OpenFamilyBossFB ok familyId=%s,curWeekOpenCnt=%s!" % (familyId, curWeekOpenCnt + 1))
+def OnPlayerJionFamily(curFamily, curPlayer):
+    SyncFamilyBosFBInfo(curPlayer.GetFamilyID(), None, curPlayer)
     return
 
-
-## 开启家族boss副本消耗逻辑
-#  @param curFamily 家族实例
-#  @param curPlayer 玩家实例
-#  @param costInfoList 消耗信息列表
-#  @param openIndex 开启次数索引
-#  @return True-扣除消耗成功
-def __DoOpenCostLogic(curFamily, curPlayer, foodCost):
-    # 成员家族等级需求判断
-    curMember = curFamily.FindMember(curPlayer.GetPlayerID())
+def __FamilyBossFBHurtOnDay(curFamily):
+    familyID = curFamily.GetID()
     
-    if not curMember:
-        GameWorld.ErrLog("家族成员查找异常 = %s" % (curPlayer.GetPlayerID()))
-        return False
-    
-    if not PlayerFamily.GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanOpenBoss):
-        GameWorld.DebugLog("开启仙盟BOSS->你没有权限" )
-        return False
-    
-    # 家族兽粮消耗
-    familyBossFood = PlayerFamily.GetFamilyBossFood(curFamily)
-    if familyBossFood < foodCost:
-        GameWorld.Log("    __DoOpenCostLogic 需求家族兽粮=%s,当前家族兽粮=%s" 
-                      % (foodCost, familyBossFood))
-        return False
-    
-    # 扣除兽粮
-    PlayerFamily.SetFamilyBossFood(curFamily, max(0, familyBossFood - foodCost))
-    
-    #通知客户端刷新
-    curFamily.Broadcast_FamilyChange()
-    #通知地图服务器刷新
-    PlayerFamily.SendPack_MapServer_PlayerFamilyRefresh(curFamily)
-    GameWorld.Log("    __DoOpenCostLogic 扣除家族兽粮=%s OK!, familyID=%s,playerFamilyLV=%s" 
-                  % (foodCost, curPlayer.GetFamilyID(), curMember.GetFamilyLV()), curPlayer.GetPlayerID())
-    return True
-
-
-## 获取家族boss副本开启信息
-#  @param familyID 家族id
-#  @param mapID 地图id
-#  @return ActionData
-def __GetFamilyBossFBActionData(familyID):
+    #补发仙盟伤血奖励
+    hurtValueTotal = 0
+    memberHurtAwardStateDict = {}
     fActionType = ShareDefine.Def_ActionType_FamilyBossFB
     familyBossFBAction = GameWorld.GetFamilyActionManager().GetFamilyAction(familyID, fActionType)
-    if familyBossFBAction.Count() <= 0:
-        # 没有的话添加数据
-        tick = GameWorld.GetGameWorld().GetTick()
-        if not PlayerFamilyAction.AddFamilyActionNote("", familyID, fActionType, [], tick):
-            return
-    return familyBossFBAction.At(0)
-
-
-def NotifyFamilyBossFBInfo(curPlayer):
-    '''通知玩家仙盟BOSS副本信息'''
-    familyID = curPlayer.GetFamilyID()
-    if familyID:
-        familyBossFBInfoPack = __GetFamilyBossFBInfoPack(familyID)
-        NetPackCommon.SendFakePack(curPlayer, familyBossFBInfoPack)
-    return
-
-## 通知家族所有成员boss相关信息
-#  @param curFamily 家族对象
-#  @return None
-def __Notify_FamilyAllMemberBossFBInfo(curFamily):
-    familyID = curFamily.GetID()
-    familyBossFBInfoPack = __GetFamilyBossFBInfoPack(familyID)
-
-    for i in range(0, curFamily.GetCount()):
-        notifyMember = curFamily.GetAt(i)
+    for index in range(familyBossFBAction.Count()):
+        actionData = familyBossFBAction.At(index)
+        playerID = actionData.GetValue1()
+        
+        if playerID == 1:
+            hurtValueTotal = GetFamilyBossPlayerHurtValue(actionData)
+        else:
+            hurtAwardStateFamily = actionData.GetValue2()
+            memberHurtAwardStateDict[playerID] = hurtAwardStateFamily
             
-        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(notifyMember.GetPlayerID())        
-        if curPlayer == None:
+    #GameWorld.DebugLog("__FamilyBossFBHurtOnDay hurtValueTotal=%s,memberHurtAwardStateDict=%s" % (hurtValueTotal, memberHurtAwardStateDict), familyID)
+    awardIpyDataList = []
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for ipyIndex in range(ipyDataMgr.GetFamilyBossHurtAwardCount()):
+        ipyData = ipyDataMgr.GetFamilyBossHurtAwardByIndex(ipyIndex)
+        if ipyData.GetAwardType() != 2:
+            continue
+        needHurtTotal = ipyData.GetNeedHurtTotal()
+        if hurtValueTotal < needHurtTotal:
+            #GameWorld.DebugLog("    仙盟伤血不足,不补发该奖励! needHurtTotal=%s" % needHurtTotal, familyID)
+            continue
+        awardIpyDataList.append(ipyData)
+        
+    offLineHourMax = 48
+    for index in xrange(curFamily.GetCount()):
+        member = curFamily.GetAt(index)
+        playerID = member.GetPlayerID()
+        offLineHour = GameWorld.GetPastHour(GameWorld.ChangeTimeNumToStr(member.GetExattr2())) if member.GetExattr2() > 1 else 0
+        if offLineHour >= offLineHourMax:
+            #GameWorld.DebugLog("    离线过久,不补发. playerID=%s,offLineHour=%s" % (playerID, offLineHour), familyID)
             continue
         
-        # 发送副本开启信息
-        NetPackCommon.SendFakePack(curPlayer, familyBossFBInfoPack)
+        hurtAwardStateFamily = memberHurtAwardStateDict.get(playerID, 0)
+        for ipyData in awardIpyDataList:
+            recordIndex = ipyData.GetRecordIndex()
+            if hurtAwardStateFamily & pow(2, recordIndex):
+                #GameWorld.DebugLog("    已经领取过,不补发. playerID=%s,recordIndex=%s,%s" % (playerID, recordIndex, hurtAwardStateFamily), familyID)
+                continue
+            needHurtTotal = ipyData.GetNeedHurtTotal()
+            paramList = [needHurtTotal]
+            awardItemList = ipyData.GetAwardItemList()
+            PlayerCompensation.SendMailByKey("FamilyBossHurtAwardFamily", [playerID], awardItemList, paramList)
+            #GameWorld.DebugLog("    邮件补发伤血奖励. playerID=%s,recordIndex=%s" % (playerID, recordIndex), familyID)
             
+    # 最后清除action
+    PlayerFamilyAction.ClearFamilyAction(familyID, fActionType)
+    SyncFamilyBosFBInfo(familyID, curFamily)
     return
 
-
-## 获取家族副本boss相关信息包
-#  @param familyID 家族id
-#  @return tagGCFamilyBossFBInfo实例
-def __GetFamilyBossFBInfoPack(familyID):
-    familyBossFBInfo = ChPyNetSendPack.tagGCFamilyBossFBInfo()
-    familyBossFBInfo.Clear()
-    familyBossFBOpenData = __GetFamilyBossFBActionData(familyID)
-    familyBossFBInfo.IsOpen = GetFamilyBossIsOpen(familyBossFBOpenData) if familyBossFBOpenData else 0
-    familyBossFBInfo.OpenCnt = GetFamilyBossOpenCnt(familyBossFBOpenData) if familyBossFBOpenData else 0
-    return familyBossFBInfo
-
-
-## 家族boss开始、被击杀
-#  @param msgList 信息列表
-#  @param tick 时间
-#  @return None
-def FamilyBossOnKilled(msgList, tick):
-    familyID, isOpen = msgList
-    curFamily = GameWorld.GetFamilyManager().FindFamily(familyID)
-    GameWorld.Log("FamilyBossOnKilled familyID=%s" % (familyID))
+def GetFamilyBossFBActionData(familyID, playerID=1):
+    ## 获取仙盟boss伤血action
+    # playerID  1-特殊类型,记录仙盟总伤害信息;>1-玩家仙盟伤血奖励领奖记录
     
-    if not curFamily:
-        GameWorld.ErrLog("OnFamilyBossKilled can not find family! familyID=%s" % (familyID))
-        return
-    familyBossFBData = __GetFamilyBossFBActionData(familyID)
-    if not familyBossFBData:
-        return
-    if not GetFamilyBossIsOpen(familyBossFBData):
-        GameWorld.ErrLog("    boss已经被击杀,重复击杀!不处理! familyId=%s"  % (familyID))       
-        return
-    if isOpen == 1:
-        SetFamilyBossIsOpen(familyBossFBData, int(time.time()))
-    else:
-        #设置FB结束
-        SetFamilyBossIsOpen(familyBossFBData, isOpen)
-    
+    findActionData = None
+    fActionType = ShareDefine.Def_ActionType_FamilyBossFB
+    familyBossFBAction = GameWorld.GetFamilyActionManager().GetFamilyAction(familyID, fActionType)
+    for index in range(familyBossFBAction.Count()):
+        actionData = familyBossFBAction.At(index)
+        if playerID == actionData.GetValue1():
+            findActionData = actionData
+            break
+            
+    if not findActionData:
+        findActionData = familyBossFBAction.AddAction()
+        findActionData.SetFamilyId(familyID)
+        findActionData.SetActionType(fActionType)
+        findActionData.SetValue1(playerID)
         
-    # 广播给在线家族成员家族boss副本信息
-    __Notify_FamilyAllMemberBossFBInfo(curFamily)    
+    return findActionData
+
+def GetFamilyBossPlayerHurtValue(actionData):
+    return actionData.GetValue3() * ChConfig.Def_PerPointValue + actionData.GetValue2()
+def SetFamilyBossPlayerHurtValue(actionData, hurtValue):
+    actionData.SetValue2(hurtValue % ChConfig.Def_PerPointValue)
+    actionData.SetValue3(hurtValue / ChConfig.Def_PerPointValue)
     return
 
+def MapServer_FamilyBoss(msgList, tick):
+    msgType, msgData = msgList
+    
+    # 同步伤血
+    if msgType == "FBMemberHurt":
+        __addFBMemberHurtInfo(msgData)
+        return
+    
+    # 仙盟伤血领奖  - 请求
+    if msgType == "FamilyHurtAwardReq":
+        familyID = msgData[0]
+        actionData = GetFamilyBossFBActionData(familyID)
+        hurtValueTotal = GetFamilyBossPlayerHurtValue(actionData) if actionData else 0
+        return msgList + [hurtValueTotal]
+    
+    # 仙盟伤血领奖记录同步 - 用于加入仙盟时,同步到GameServer,方便统一处理补发奖励
+    if msgType == "FamilyHurtAwardStateFamily":
+        familyID, playerID, hurtAwardStateFamily = msgData
+        actionData = GetFamilyBossFBActionData(familyID, playerID)
+        actionData.SetValue2(hurtAwardStateFamily)
+        return
+    
+    return
 
+def __addFBMemberHurtInfo(msgData):
+    ## 增加仙盟boss仙盟总伤血
+    statsType, familyID, fightMemCount, addFamilyHurt = msgData
+    curFamily = GameWorld.GetFamilyManager().FindFamily(familyID)
+    if not curFamily:
+        return
+    
+    actionData = GetFamilyBossFBActionData(familyID)
+    if not actionData:
+        return
+    actionData.SetValue4(fightMemCount)
+    
+    hurtValueTotal = GetFamilyBossPlayerHurtValue(actionData) + addFamilyHurt
+    SetFamilyBossPlayerHurtValue(actionData, hurtValueTotal)
+    
+    #GameWorld.DebugLog("FamilyBossFBMemberHurt statsType=%s,familyID=%s,fightMemCount=%s,addFamilyHurt=%s,hurtValueTotal=%s" 
+    #                   % (statsType, familyID, fightMemCount, addFamilyHurt, hurtValueTotal))
+    
+    if statsType:
+        SyncFamilyBosFBInfo(familyID, curFamily)
+    return
+
+def SyncFamilyBosFBInfo(familyID, curFamily=None, curPlayer=None):
+    if not familyID:
+        return
+    if not curFamily and not curPlayer:
+        return
+    actionData = GetFamilyBossFBActionData(familyID)
+    if not actionData:
+        return
+    
+    clientPack = ChPyNetSendPack.tagGCFamilyBosFBInfo()
+    clientPack.Clear()
+    clientPack.HurtTotal = actionData.GetValue2()
+    clientPack.HurtTotalPoint = actionData.GetValue3()
+    clientPack.FightMemCount = actionData.GetValue4()
+    
+    if curFamily:
+        for i in range(0, curFamily.GetCount()):
+            notifyMember = curFamily.GetAt(i)
+            curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(notifyMember.GetPlayerID())        
+            if curPlayer == None:
+                continue
+            NetPackCommon.SendFakePack(curPlayer, clientPack)
+        return
+    
+    if curPlayer:
+        NetPackCommon.SendFakePack(curPlayer, clientPack)
+        
+    return
 
 #############################多仙盟BOSS#############################
 
@@ -321,4 +251,4 @@
 #是否在仙盟BOSS活动中
 def IsInAllFamilyBoss(lineID=-1):
     state1 = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyBoss1)
-    return state1
\ No newline at end of file
+    return state1
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
index f336ce1..f402a26 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -727,12 +727,6 @@
                 
         return
     
-    # 战盟副本boss开始、被击杀
-    if callName =="FamilyBossFBState":
-        PlayerFamilyBoss.FamilyBossOnKilled(eval(resultName), tick)
-        return
-    
-
     # 击杀boss掉落好物品
     if callName =="BossDropGoodItem":
         GameWorldBoss.OnKillBossDropGoodItem(eval(resultName), tick)
@@ -991,6 +985,13 @@
         ret = GameWorldArena.MapServer_Arena(curPlayer, eval(resultName))
         resultName = '%s' % ret if ret != None else '' # 需要重置间隔,每次都回复
         
+    # 仙盟boss
+    if callName =="FamilyBoss":
+        ret = PlayerFamilyBoss.MapServer_FamilyBoss(eval(resultName), tick)
+        if ret == None:
+            return
+        resultName = '%s' % ret
+        
     # 情缘
     if callName =="Love":
         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
@@ -1017,7 +1018,10 @@
 #        if not curPlayer:
 #            return
 #        resultName = '%s' % PlayerFamilyStore.DoMapServerFamilyStore(curPlayer, eval(resultName), tick)
-        
+    
+    if not srcPlayerID:
+        return
+    
     srcPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
     
     if not srcPlayer:
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index abe82a2..8977ad8 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -166,8 +166,6 @@
 Def_Notify_WorldKey_VSFamilyInfo = "VSFamilyInfo"  # 仙盟联赛对战仙盟信息
 Def_Notify_WorldKey_ChampionFamilyID = "ChampionFamilyID"  # 仙盟联赛上次冠军仙盟ID
 
-Def_Notify_WorldKey_FamilyBossOpenCount = "FamilyBossOpenCount"  # 仙盟boss开启次数
-
 Def_Notify_WorldKey_FamilyPartyInfo = "FamilyPartyInfo"  # 仙盟宴会数据
 Def_Notify_WorldKey_FamilyPartyAddFamilyActivity = "FamilyPartyAddFamilyActivity"  # 仙盟宴会地图成员增加仙盟活跃令
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index aa26923..625f7a3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -195,9 +195,9 @@
 PacketSubCMD_2=0x02
 PacketCallFunc_2=RequestAddFamily
 
-PacketCMD_3=0xA6
-PacketSubCMD_3=0x05
-PacketCallFunc_3=OnFamilyDonateItem
+PacketCMD_3=
+PacketSubCMD_3=
+PacketCallFunc_3=
 
 PacketCMD_4=0xA6
 PacketSubCMD_4=0x11
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index bd8dfd6..3c97a7c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1895,7 +1895,7 @@
 Def_MapID_LineIDToPropertyID = [Def_FBMapID_ElderBattlefield]
                       
 # 进入副本需要发送到GameServer的地图
-Def_MapID_SendToGameServer = [Def_FBMapID_HorsePetBoss, Def_FBMapID_FamilyInvade, Def_FBMapID_FamilyBossMap, Def_FBMapID_SealDemon, Def_FBMapID_DemonKing,
+Def_MapID_SendToGameServer = [Def_FBMapID_HorsePetBoss, Def_FBMapID_FamilyInvade, Def_FBMapID_SealDemon, Def_FBMapID_DemonKing,
                               Def_FBMapID_FamilyWar, Def_FBMapID_ZhuXianBoss, Def_FBMapID_AllFamilyBoss] + Def_MapID_LineIDToPropertyID + [Def_FBMapID_CrossChampionship]
 
 # 刷新标识点在无玩家的情况下也需要刷新的地图
@@ -1905,7 +1905,7 @@
 Def_NoLimitEnterCntMap = [Def_FBMapID_AllFamilyBoss, Def_FBMapID_FamilyParty, Def_FBMapID_FamilyWar, Def_FBMapID_FamilyInvade, Def_FBMapID_ElderBattlefield, Def_FBMapID_SealDemon]
 
 # 无玩家时不自动关闭的自伸缩副本
-Def_NoPlayerNotCloseAutoSizeMap = [Def_FBMapID_FamilyInvade, Def_FBMapID_FamilyBossMap, Def_FBMapID_GatherSoul]
+Def_NoPlayerNotCloseAutoSizeMap = [Def_FBMapID_FamilyInvade, Def_FBMapID_GatherSoul]
 # 无玩家时自动关闭的非自伸缩副本
 Def_NoPlayerCloseNotAutoSizeMap = [Def_FBMapID_ZhuXianBoss]
 
@@ -4039,9 +4039,15 @@
 Def_PDict_GatherSoulHoleData = "GatherSoulHoleData_%s"  # 聚魂镶嵌数据, 参数(第几孔)
 
 # 副本 Def_PDictType_FB
-Def_PDict_FamilyBossFBAwardState = "FamilyBossFBAwardState_%s"  # 家族boss副本领奖状态%s副本id
 Def_PDict_LastEnterFBPropertyID = "LastEnterFBPropertyID_%s"  # 上次进入副本的propertyID%s副本id
 Def_PDict_LastEnterFBTick = "LastEnterFBTick_%s"  # 上次进入副本的时间%s副本id
+
+# 仙盟boss
+Def_PDict_FamilyBossHurtValue = "FamilyBossHurtValue" # 仙盟boss个人总伤血,求余亿部分
+Def_PDict_FamilyBossHurtValuePoint = "FamilyBossHurtValuePoint" # 仙盟boss个人总伤血,整除亿部分
+Def_PDict_FamilyBossFightSeconds = "FamilyBossFightSeconds" # 仙盟boss个人已战斗时长,秒
+Def_PDict_FamilyBossHurtAward = "FamilyBossHurtAward" # 仙盟boss个人总伤血领奖记录
+Def_PDict_FamilyBossHurtAwardFamily = "FamilyBossHurtAwardFamily" # 仙盟boss仙盟总伤血领奖记录
 
 # 战斗力 Def_PDictType_FightPower
 Def_PDict_FightPower_Highest = "FightPower_Highest"  # 历史最高总战斗力
@@ -5735,7 +5741,8 @@
 Def_RewardType_BuyOne, #买一送多活动免费奖励 60
 Def_RewardType_CustomAward, #自定义奖励 61
 Def_RewardType_RealmXXZL, #境界修仙之路奖励 62
-)= range(63)
+Def_RewardType_FamilyBossHurt, #仙盟boss伤害奖励 63
+)= range(64)
 
 
 #boss复活相关活动定义
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index ffcc7ac..04f4a00 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -706,58 +706,6 @@
 
 
 #------------------------------------------------------
-# A4 05 开启家族boss副本 #tagCGOpenFamilyBossFB
-
-class  tagCGOpenFamilyBossFB(Structure):
-    _pack_ = 1
-    _fields_ = [
-                  ("Cmd", c_ubyte),
-                  ("SubCmd", c_ubyte),
-                  ("MapID", c_int),    # 开启的副本地图ID
-                  ]
-
-    def __init__(self):
-        self.Clear()
-        self.Cmd = 0xA4
-        self.SubCmd = 0x05
-        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 = 0xA4
-        self.SubCmd = 0x05
-        self.MapID = 0
-        return
-
-    def GetLength(self):
-        return sizeof(tagCGOpenFamilyBossFB)
-
-    def GetBuffer(self):
-        return string_at(addressof(self), self.GetLength())
-
-    def OutputString(self):
-        DumpString = '''// A4 05 开启家族boss副本 //tagCGOpenFamilyBossFB:
-                                Cmd:%s,
-                                SubCmd:%s,
-                                MapID:%d
-                                '''\
-                                %(
-                                self.Cmd,
-                                self.SubCmd,
-                                self.MapID
-                                )
-        return DumpString
-
-
-m_NAtagCGOpenFamilyBossFB=tagCGOpenFamilyBossFB()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGOpenFamilyBossFB.Cmd,m_NAtagCGOpenFamilyBossFB.SubCmd))] = m_NAtagCGOpenFamilyBossFB
-
-
-#------------------------------------------------------
 # A4 04 创建家族 #tagCGPyCreatFamily
 
 class  tagCGPyCreatFamily(Structure):
@@ -13946,54 +13894,6 @@
 
 m_NAtagCMFamilyActivityExchange=tagCMFamilyActivityExchange()
 ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMFamilyActivityExchange.Head.Cmd,m_NAtagCMFamilyActivityExchange.Head.SubCmd))] = m_NAtagCMFamilyActivityExchange
-
-
-#------------------------------------------------------
-# A6 05  家族捐献兽粮 #tagCMFamilyDonate
-
-class  tagCMFamilyDonate(Structure):
-    _pack_ = 1
-    _fields_ = [
-                  ("Cmd", c_ubyte),
-                  ("SubCmd", c_ubyte),
-                  ]
-
-    def __init__(self):
-        self.Clear()
-        self.Cmd = 0xA6
-        self.SubCmd = 0x05
-        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 = 0xA6
-        self.SubCmd = 0x05
-        return
-
-    def GetLength(self):
-        return sizeof(tagCMFamilyDonate)
-
-    def GetBuffer(self):
-        return string_at(addressof(self), self.GetLength())
-
-    def OutputString(self):
-        DumpString = '''// A6 05  家族捐献兽粮 //tagCMFamilyDonate:
-                                Cmd:%s,
-                                SubCmd:%s
-                                '''\
-                                %(
-                                self.Cmd,
-                                self.SubCmd
-                                )
-        return DumpString
-
-
-m_NAtagCMFamilyDonate=tagCMFamilyDonate()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMFamilyDonate.Cmd,m_NAtagCMFamilyDonate.SubCmd))] = m_NAtagCMFamilyDonate
 
 
 #------------------------------------------------------
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 7ca9139..9c95ee6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -1243,6 +1243,66 @@
 
 
 #------------------------------------------------------
+# A4 0E 家族boss副本信息 #tagGCFamilyBosFBInfo
+
+class  tagGCFamilyBosFBInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("HurtTotal", c_int),    # 仙盟累计伤血,亿求余部分
+                  ("HurtTotalPoint", c_int),    # 仙盟累计伤血,亿整除部分
+                  ("FightMemCount", c_ubyte),    # 目前正在仙盟boss副本中的成员数
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA4
+        self.SubCmd = 0x0E
+        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 = 0xA4
+        self.SubCmd = 0x0E
+        self.HurtTotal = 0
+        self.HurtTotalPoint = 0
+        self.FightMemCount = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagGCFamilyBosFBInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A4 0E 家族boss副本信息 //tagGCFamilyBosFBInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                HurtTotal:%d,
+                                HurtTotalPoint:%d,
+                                FightMemCount:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.HurtTotal,
+                                self.HurtTotalPoint,
+                                self.FightMemCount
+                                )
+        return DumpString
+
+
+m_NAtagGCFamilyBosFBInfo=tagGCFamilyBosFBInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCFamilyBosFBInfo.Cmd,m_NAtagGCFamilyBosFBInfo.SubCmd))] = m_NAtagGCFamilyBosFBInfo
+
+
+#------------------------------------------------------
 # A4 02 家族boss副本开启及击杀信息 #tagGCFamilyBossFBInfo
 
 class  tagGCFamilyBossFBInfo(Structure):
@@ -25962,6 +26022,74 @@
 
 
 #------------------------------------------------------
+# A5 07 家族boss副本玩家信息 #tagMCFamilyBosFBPlayerInfo
+
+class  tagMCFamilyBosFBPlayerInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("HurtTotal", c_int),    # 累计伤血,亿求余部分
+                  ("HurtTotalPoint", c_int),    # 累计伤血,亿整除部分
+                  ("FightSeconds", c_int),    # 已累计战斗时长,秒
+                  ("HurtAwardState", c_int),    # 个人总伤血领奖记录,按奖励位二进制位运算表示是否已领取
+                  ("HurtAwardStateFamily", c_int),    # 仙盟总伤血领奖记录,按奖励位二进制位运算表示是否已领取
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0x07
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xA5
+        self.SubCmd = 0x07
+        self.HurtTotal = 0
+        self.HurtTotalPoint = 0
+        self.FightSeconds = 0
+        self.HurtAwardState = 0
+        self.HurtAwardStateFamily = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCFamilyBosFBPlayerInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 07 家族boss副本玩家信息 //tagMCFamilyBosFBPlayerInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                HurtTotal:%d,
+                                HurtTotalPoint:%d,
+                                FightSeconds:%d,
+                                HurtAwardState:%d,
+                                HurtAwardStateFamily:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.HurtTotal,
+                                self.HurtTotalPoint,
+                                self.FightSeconds,
+                                self.HurtAwardState,
+                                self.HurtAwardStateFamily
+                                )
+        return DumpString
+
+
+m_NAtagMCFamilyBosFBPlayerInfo=tagMCFamilyBosFBPlayerInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCFamilyBosFBPlayerInfo.Cmd,m_NAtagMCFamilyBosFBPlayerInfo.SubCmd))] = m_NAtagMCFamilyBosFBPlayerInfo
+
+
+#------------------------------------------------------
 # A5 06 仙盟每日福利领取状态 #tagMCFamilyDayAward
 
 class  tagMCFamilyDayAward(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_FamilyBoss.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_FamilyBoss.py
index bdfd07b..f1a640e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_FamilyBoss.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_FamilyBoss.py
@@ -2,210 +2,168 @@
 # -*- coding: GBK -*-
 #-------------------------------------------------------------------------------
 #
-#-------------------------------------------------------------------------------
-#
 ##@package GameWorldLogic.FBProcess.GameLogic_FamilyBoss
 #
-# @todo:战盟boss副本
-# @author xdh
-# @date 2018-02-08
+# @todo:战盟boss副本/仙盟试炼
+# @author hxp
+# @date 2023-09-29
 # @version 1.0
 #
-# 详细描述: 战盟boss副本
+# 详细描述: 战盟boss副本/仙盟试炼
 #
-#---------------------------------------------------------------------
-#"""Version = 2018-02-08 17:20"""
-#---------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+#"""Version = 2023-09-29 02:00"""
+#-------------------------------------------------------------------------------
+
 import FBCommon
-import GameWorldProcess
+import GameWorld
 import IPY_GameWorld
 import PlayerControl
-import GameWorld
-import PlayerTongTianLing
 import NPCCustomRefresh
+import ChPyNetSendPack
+import ItemControler
+import NetPackCommon
 import IpyGameDataPY
-import PlayerFamily
-import ShareDefine
-import EventReport
+import SkillCommon
 import PyGameData
+import BuffSkill
 import ChConfig
-
-import math
 
 #当前副本地图的状态
 (
 FB_Step_Open, # 地图开启
 FB_Step_MapPrepare, # 地图准备
 FB_Step_Fighting, # 战斗中
-FB_Step_LeaveTime, # 自由时间(还可进入)
-FB_Step_LeaveTime1, # 自由时间(不可进入)
+FB_Step_LeaveTime, # 自由时间
 FB_Step_Over, # 副本关闭
-) = range(6)
+) = range(5)
 
-#---战盟副本---
-FamilyBossFB_Star = 'FamilyBossFB_Star' #评级
-Map_FamilyBossFB_FamilyID = "FamilyBossFB_FamilyID"     # 对应的家族id
-
-(
-Def_Time_MapPrepare, # 准备时间, 秒
-Def_Time_Fight, # 持续时间, 秒
-Def_Time_Leave, # 结束时间, 秒
-Def_StarTime, # 星级对应耗时配置, 秒
-) = range(4)
-
-def GetFamilyBossFBTimeCfg():return FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_FamilyBossMap, 0)
-
-def GameServerOpenFamilyBoss(familyID, openCount):
-    if familyID in PyGameData.g_familyBossOpenCountDict:
-        curOpenCount = PyGameData.g_familyBossOpenCountDict[familyID]
-        if curOpenCount == openCount:
-            return
-    PyGameData.g_familyBossOpenCountDict[familyID] = openCount
-    if familyID in PyGameData.g_familyBossPlayer:
-        PyGameData.g_familyBossPlayer.pop(familyID)
-    GameWorld.DebugLog("开启仙盟Boss: familyID=%s,openCount=%s" % (familyID, openCount))
-    return
-
-def AddFamilyBossPlayer(curPlayer):
-    familyID = curPlayer.GetFamilyID()
-    if not familyID:
-        return
-    if familyID not in PyGameData.g_familyBossOpenCountDict:
-        return
-    openCount = PyGameData.g_familyBossOpenCountDict[familyID]
-    familyPlayerList = PyGameData.g_familyBossPlayer.get(familyID, [])
-    playerID = curPlayer.GetPlayerID()
-    if playerID in familyPlayerList:
-        return
-    familyPlayerList.append(playerID)
-    PyGameData.g_familyBossPlayer[familyID] = familyPlayerList
-    GameWorld.DebugLog("仙盟参与玩家: %s" % PyGameData.g_familyBossPlayer)
-    EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_FamilyBossMap, openCount, ChConfig.CME_Log_Start)
-    PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_FamilyBoss, 1)
-    return
-
-
-
-##开启副本
-# @param tick 时间戳
-# @return 返回值无意义
-# @remarks 开启副本
-def OnOpenFB(tick):
-    gameFB = GameWorld.GetGameFB()
-    gameFB.SetGameFBDict(Map_FamilyBossFB_FamilyID, 0)
-    gameFB.SetGameFBDict(FamilyBossFB_Star, 0)
-    return
-
-
-##关闭副本
-# @param tick 时间戳
-# @return 无意义
-# @remarks 
-def OnCloseFB(tick):
-    #副本踢出玩家
-    # 通知GameServer副本结束
-    gameFB = GameWorld.GetGameFB()
-    familyID = gameFB.GetGameFBDictByKey(Map_FamilyBossFB_FamilyID)
-#    msgStr = str([familyID, 0])
-#    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))
+class BattlePlayer():
     
-    if familyID in PyGameData.g_familyBossOpenCountDict:
-        PyGameData.g_familyBossOpenCountDict.pop(familyID)
-        GameWorld.DebugLog("移除仙盟开启boss数:%s" % PyGameData.g_familyBossOpenCountDict)
-    if familyID in PyGameData.g_familyBossPlayer:
-        PyGameData.g_familyBossPlayer.pop(familyID)
-        GameWorld.DebugLog("移除仙盟参与玩家:%s" % PyGameData.g_familyBossPlayer)
+    def __init__(self, playerID):
+        self.playerID = playerID
+        self.hurtValue = 0 # 当前累计伤害
+        self.hurtValueLast = 0 # 上次同步结算时伤害
+        self.fightTickTotal = 0 # 累计战斗tick
+        self.statsTick = 0 # 统计tick
+        return
+    
+    def onEnter(self, curPlayer, tick):
+        hurtValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValue)
+        hurtValuePoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValuePoint)
+        self.hurtValue = hurtValuePoint * ChConfig.Def_PerPointValue + hurtValue
+        self.hurtValueLast = self.hurtValue
+        self.fightTickTotal = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossFightSeconds) * 1000
+        self.statsTick = tick
+        return
+    
+def OnFBPlayerOnLogin(curPlayer):
+    SyncFamilyBossPlayerInfo(curPlayer)
+    return
+
+def OnFBPlayerOnDay(curPlayer):
+    playerID = curPlayer.GetPlayerID()
+    hurtValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValue)
+    hurtValuePoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValuePoint)
+    hurtValueTotal = hurtValuePoint * ChConfig.Def_PerPointValue + hurtValue
+    
+    rewardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAward)
+    #仙盟伤血奖励GameServer处理补发
+    
+    #GameWorld.DebugLog("仙盟boss伤血过天. hurtValueTotal=%s,rewardRecord=%s" % (hurtValueTotal, rewardRecord), playerID)
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for index in range(ipyDataMgr.GetFamilyBossHurtAwardCount()):
+        ipyData = ipyDataMgr.GetFamilyBossHurtAwardByIndex(index)
+        if ipyData.GetAwardType() != 1:
+            continue
+        needHurtTotal = ipyData.GetNeedHurtTotal()
+        if hurtValueTotal < needHurtTotal:
+            #GameWorld.DebugLog("    伤血不足,不补发该奖励! needHurtTotal=%s" % needHurtTotal, playerID)
+            continue
+        recordIndex = ipyData.GetRecordIndex()
+        if rewardRecord & pow(2, recordIndex):
+            #GameWorld.DebugLog("    该个人奖励已领奖! recordIndex=%s,rewardRecord=%s" % (recordIndex, rewardRecord), playerID)
+            continue
         
+        paramList = [needHurtTotal]
+        awardItemList = ipyData.GetAwardItemList()
+        PlayerControl.SendMailByKey("FamilyBossHurtAward", [playerID], awardItemList, paramList)
+        #GameWorld.DebugLog("    邮件补发伤血奖励! recordIndex=%s" % recordIndex, playerID)
+        
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtValue, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtValuePoint, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossFightSeconds, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtAward, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtAwardFamily, 0)
+    SyncFamilyBossPlayerInfo(curPlayer)    
+    return
+
+def GetBattlePlayer(playerID):
+    if playerID in PyGameData.g_familyBossHurtPlayerDict:
+        batPlayer = PyGameData.g_familyBossHurtPlayerDict[playerID]
+    else:
+        batPlayer = BattlePlayer(playerID)
+        PyGameData.g_familyBossHurtPlayerDict[playerID] = batPlayer
+    return batPlayer
+
+def OnOpenFB(tick):
+    return
+
+def OnCloseFB(tick):
     GameWorld.GetGameWorld().SetPropertyID(0)
     FBCommon.DoLogic_FBKickAllPlayer()
     return
 
-
-## 是否能够通过活动查询进入
-#  @param curPlayer 玩家实例
-#  @param mapID 地图ID
-#  @param lineID 线路id
-#  @param tick 时间戳
-#  @return 布尔值
 def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
-    return __CheckEnter(curPlayer, mapID)
-
-
-##进入副本检查
-#  @param curPlayer 玩家实例
-#  @param mapID 地图ID
-#  @param lineID 线路id
-# @return None
-def __CheckEnter(curPlayer, mapID):
-    
-    # 是否有战盟
     if curPlayer.GetFamilyID() <= 0:
-        GameWorld.DebugLog("没有战盟,不能进入战盟boss副本!")
+        GameWorld.DebugLog("没有战盟,不能进入战盟boss副本!", curPlayer.GetPlayerID())
+        return False
+    
+    playerID = curPlayer.GetPlayerID()
+    fightSeconds = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossFightSeconds) # 已战斗时长
+    fightSecondsMax = IpyGameDataPY.GetFuncCfg("FamilyBossFB", 1)
+    if fightSeconds >= fightSecondsMax:
+        GameWorld.DebugLog("已经达到仙盟boss战斗时长上限,无法进入. fightSeconds=%s" % fightSeconds, playerID)
         return False
     
     return True
 
-
-##副本玩家进入点
-# @param curPlayer 玩家实例
-# @param mapID 地图ID
-# @param lineId 分线ID
-# @param ipyEnterPosInfo 功能线路IPY配置坐标信息
-# @param tick 时间戳
-# @return posX, posY, 随机半径(可选)
 def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
     return ipyEnterPosInfo
-   
 
-
-##是否可以进入
-# @param ask 请求结构体
-# @param tick 时间戳
-# @return TChangeMapError
-# @remarks 验证家族是否在今天的家族战表
 def OnChangeMapAsk(ask, tick):
     return IPY_GameWorld.cmeAccept
 
-
-##玩家进入副本
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 无意义
-# @remarks 玩家进入副本
 def DoEnterFB(curPlayer, tick):
-    mapID = GameWorld.GetGameWorld().GetMapID()
-  
-    if not __CheckEnter(curPlayer, mapID):
-        PlayerControl.PlayerLeaveFB(curPlayer)
-        return
+    
+    playerID = curPlayer.GetPlayerID()
     gameFB = GameWorld.GetGameFB()
     fbStep = gameFB.GetFBStep()
     
-    if fbStep == FB_Step_Open:
-        FBCommon.SetFBStep(FB_Step_MapPrepare, tick)
-        familyID = curPlayer.GetFamilyID()
-        gameFB.SetGameFBDict(Map_FamilyBossFB_FamilyID, familyID)
-        msgStr = str([familyID, 1])
-        GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))
-    familyBossFBCfg = GetFamilyBossFBTimeCfg()    
-    fbStep = gameFB.GetFBStep()
-    if fbStep == FB_Step_MapPrepare:
-        #初始化并通知等待倒计时
-        __EnterFBInPrepare(curPlayer, familyBossFBCfg[Def_Time_MapPrepare] * 1000, gameFB, tick)
-   
-    elif fbStep == FB_Step_Fighting:
-        #通知进入时间
-        notifyTick = max(familyBossFBCfg[Def_Time_Fight] * 1000 - (tick - gameFB.GetFBStepTick()), 0)
-        curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, notifyTick, True)
-        __UpdFamilyBossFBStar(tick, True, curPlayer)
-    elif fbStep == FB_Step_LeaveTime:
-        notifyTick = max(familyBossFBCfg[Def_Time_Leave] * 1000 - (tick - gameFB.GetFBStepTick()), 0)
-        curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, notifyTick, True)
-    DoFBHelp(curPlayer, tick)
+    batPlayer = GetBattlePlayer(playerID)
+    batPlayer.onEnter(curPlayer, tick)
+    GameWorld.DebugLog("DoEnterFB: fbStep=%s,fightTickTotal=%s,hurtValue=%s" % (fbStep, batPlayer.fightTickTotal, batPlayer.hurtValue), playerID)
     
-    AddFamilyBossPlayer(curPlayer)
+    fightSecondsMax = IpyGameDataPY.GetFuncCfg("FamilyBossFB", 1)
+    remainTick = fightSecondsMax * 1000 - batPlayer.fightTickTotal
+    if remainTick <= 0:
+        PlayerControl.PlayerLeaveFB(curPlayer)
+        return
+    
+    if fbStep != FB_Step_Fighting:
+        __SetFBToFight(tick)
+        
+    curPlayer.Sync_TimeTick(IPY_GameWorld.tttAddUpTime, 0, remainTick, True)\
+    
+    statsFBMemberHurt(tick, 1)
     return
 
+def __SetFBToFight(tick):
+    FBCommon.SetFBStep(FB_Step_Fighting, tick)
+    refreshMark, bossID = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_FamilyBossMap, 0)
+    if not GameWorld.FindNPCByNPCID(bossID):
+        NPCCustomRefresh.SetNPCRefresh(refreshMark, [bossID])
+    return
 
 ##副本定时器
 # @param tick 时间戳
@@ -214,217 +172,142 @@
 def OnProcess(tick):
     fbStep = GameWorld.GetGameFB().GetFBStep()
     
-    if fbStep == FB_Step_MapPrepare:
-        __DoLogic_MapPrepare(tick)
-    elif fbStep == FB_Step_Fighting:
+    if fbStep == FB_Step_Fighting:
         __DoLogic_MapFighting(tick)
-    elif fbStep == FB_Step_LeaveTime:
-        __DoLogic_MapLeave(tick)
-    elif fbStep == FB_Step_LeaveTime1:
-        __DoLogic_MapLeave(tick)
-    return
-
-
-## 更新当前副本星级
-def __UpdFamilyBossFBStar(tick, isForce=False, curPlayer=None):
-    gameFB = GameWorld.GetGameFB()
-    curStar = gameFB.GetGameFBDictByKey(FamilyBossFB_Star)
-    if curStar == 1:
-        return curStar
-    
-    useSecond = int(math.ceil((tick - gameFB.GetFBStepTick()) / 1000.0))
-    familyBossFBCfg = GetFamilyBossFBTimeCfg()
-    starTimeList = familyBossFBCfg[Def_StarTime]
-    diffSecond = 0
-    updStar = 1 # 默认至少1星
-    for star, starTime in enumerate(starTimeList, 2):
-        if useSecond <= starTime:
-            updStar = star
-            diffSecond = starTime-useSecond
-            
-    if curStar == updStar and not isForce:
-        return curStar
         
-    gameFB.SetGameFBDict(FamilyBossFB_Star, updStar)
-    
-    GameWorld.DebugLog("__UpdFamilyBossFBStar useSecond=%s,curStar=%s,updStar=%s, diffSecond=%s" 
-                       % (useSecond, curStar, updStar, diffSecond))
-    
-    if curPlayer:
-        DoFBHelp(curPlayer, tick)
-        if updStar != 1:
-            curPlayer.Sync_TimeTick(IPY_GameWorld.tttFlagTake, 0, diffSecond * 1000, True)
-    else:
-        playerManager = GameWorld.GetMapCopyPlayerManager()
-        for index in xrange(playerManager.GetPlayerCount()):
-            curPlayer = playerManager.GetPlayerByIndex(index)
-            if not curPlayer:
-                continue
-            DoFBHelp(curPlayer, tick)
-            if updStar != 1:
-                curPlayer.Sync_TimeTick(IPY_GameWorld.tttFlagTake, 0, diffSecond * 1000, True)
-                
-            
-    return updStar
-
-
-def __EnterFBInPrepare(curPlayer, downTime, gameFB, tick, notifyEff=False):
-    #通知准备倒计时
-    notifyTick = max(downTime - (tick - gameFB.GetFBStepTick()), 0)
-    curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, notifyTick, True)
-    
-    if notifyEff:
-        curPlayer.Sync_TimeTick(IPY_GameWorld.tttAddUpTime, 0, notifyTick, True)
     return
-
-
-def __DoLogic_MapPrepare(tick):
-    invadeCfg = GetFamilyBossFBTimeCfg()
-    if tick - GameWorld.GetGameFB().GetFBStepTick() < invadeCfg[Def_Time_MapPrepare] * 1000:
-        return
-    __OnFamilyBossFBStart(tick)
-    return
-
 
 def __DoLogic_MapFighting(tick):
-    invadeCfg = GetFamilyBossFBTimeCfg()
-    
-    if tick - GameWorld.GetGameFB().GetFBStepTick() >= invadeCfg[Def_Time_Fight] * 1000:
-        __DoFamilyBossFBOver(tick, False)
-        return
-    __UpdFamilyBossFBStar(tick)
-    return
-
-def __DoLogic_MapLeave(tick):
     gameFB = GameWorld.GetGameFB()
-    invadeCfg = GetFamilyBossFBTimeCfg()
-    remianTime = invadeCfg[Def_Time_Leave] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
-    if remianTime > 0:
-        fbStep = gameFB.GetFBStep()
-        if remianTime < 5000 and fbStep == FB_Step_LeaveTime:
-            gameFB.SetFBStep(FB_Step_LeaveTime1)
-            familyID = gameFB.GetGameFBDictByKey(Map_FamilyBossFB_FamilyID)
-            msgStr = str([familyID, 0])
-            GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))
+    lastTick = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NotifyFBHelpTick)
+    if tick - lastTick < 5000:
         return
-    
-    # 时间到,踢出还在副本的玩家等...
-    GameWorldProcess.CloseFB(tick)
-    FBCommon.SetFBStep(FB_Step_Over, tick)
-    FBCommon.DoLogic_FBKickAllPlayer()
+    gameFB.SetGameFBDict(ChConfig.Def_FB_NotifyFBHelpTick, tick)
+    statsFBMemberHurt(tick)
     return
 
-def __OnFamilyBossFBStart(tick):
-    FBCommon.SetFBStep(FB_Step_Fighting, tick)
-    refreshMark, bossID = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_FamilyBossMap, 0)
-    NPCCustomRefresh.SetNPCRefresh(refreshMark, [bossID])
-
-    # 战盟频道通知开始
-    familyBossFBCfg = GetFamilyBossFBTimeCfg()
-    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, familyBossFBCfg[Def_Time_Fight] * 1000) 
+def statsFBMemberHurt(tick, statsType=0, exitPlayerID=0):
+    ## 统计副本仙盟成员伤害
+    # statsType 0-常规;1-玩家进入;2-玩家退出
     
-    __UpdFamilyBossFBStar(tick)
-    return
-
-
-def __DoFamilyBossFBOver(tick, isKill):
-    # 副本结束逻辑
-    gameFB = GameWorld.GetGameFB()
-    if gameFB.GetFBStep() == FB_Step_LeaveTime:
-        return
-    GameWorld.DebugLog("处理仙盟BOSS副本结束逻辑")
-    invadeCfg = GetFamilyBossFBTimeCfg()
-    FBCommon.SetFBStep(FB_Step_LeaveTime, tick)
-
-    familyID = gameFB.GetGameFBDictByKey(Map_FamilyBossFB_FamilyID)
-    msgStr = str([familyID, 2])
-    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))
+    fightMemCount = 0
+    familyID = GameWorld.GetGameWorld().GetPropertyID()
+    playerManager = GameWorld.GetMapCopyPlayerManager()
+    for index in xrange(playerManager.GetPlayerCount()):
+        curPlayer = playerManager.GetPlayerByIndex(index)
+        if not curPlayer:
+            continue
+        playerID = curPlayer.GetPlayerID()
+        if playerID != exitPlayerID:
+            fightMemCount += 1
+            
+    needMemCount, skillTypeID = IpyGameDataPY.GetFuncEvalCfg("FamilyBossFB", 2)
     
-    grade = gameFB.GetGameFBDictByKey(FamilyBossFB_Star)
-    GameWorld.Log("仙盟BOSS副本结算: familyID=%s, grade=%s" % (familyID, grade), familyID)
-    leaveTick = invadeCfg[Def_Time_Leave] * 1000
-    copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()
-    playerCount = copyMapPlayerManager.GetPlayerCount()
-    for i in xrange(playerCount):
-        
-        curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)
-        
-        if curPlayer == None or curPlayer.IsEmpty():
+    fightSecondsMax = IpyGameDataPY.GetFuncCfg("FamilyBossFB", 1)
+    addFamilyHurt = 0
+    for index in xrange(playerManager.GetPlayerCount()):
+        curPlayer = playerManager.GetPlayerByIndex(index)
+        if not curPlayer:
             continue
         
-        curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)
-        if isKill:
-            PlayerFamily.AddFamilyActivity(curPlayer, ShareDefine.FamilyActive_BOSS)
+        playerID = curPlayer.GetPlayerID()
+        batPlayer = GetBattlePlayer(playerID)
+            
+        hurtValue = batPlayer.hurtValue
+        addHurtValue = max(0, hurtValue - batPlayer.hurtValueLast)
+        batPlayer.hurtValueLast = hurtValue
         
-    if isKill:
-        doCountRate = eval(IpyGameDataPY.GetFuncCompileCfg("FamilyBOSSDropRule", 1))
-        doCountAdd = eval(IpyGameDataPY.GetFuncCompileCfg("FamilyBOSSDropRule", 2))
-        FBCommon.SetNPCDropDoCountRate(gameFB, doCountRate, doCountAdd)
+        passTick = tick - batPlayer.statsTick
+        if passTick > 0:
+            batPlayer.fightTickTotal += passTick
+        batPlayer.statsTick = tick
+        
+        fightSeconds = batPlayer.fightTickTotal / 1000
+        
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtValue, hurtValue % ChConfig.Def_PerPointValue)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtValuePoint, hurtValue / ChConfig.Def_PerPointValue)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossFightSeconds, fightSeconds)
+        
+        addFamilyHurt += addHurtValue
+        #GameWorld.DebugLog("仙盟玩家伤血统计: fightSeconds=%s,hurtValue=%s,addHurtValue=%s, %s" % (fightSeconds, hurtValue, addHurtValue, addFamilyHurt), playerID)
+        
+        # 帮助信息
+        helpDict = {"hurtValue":hurtValue, "fightSeconds":fightSeconds, "fightMemCount":fightMemCount}
+        FBCommon.Notify_FBHelp(curPlayer, helpDict)
+        
+        if playerID == exitPlayerID:
+            BuffSkill.DelBuffBySkillID(curPlayer, skillTypeID, tick)
+            SyncFamilyBossPlayerInfo(curPlayer)
+        elif fightSeconds >= fightSecondsMax:
+            GameWorld.DebugLog("    没有战斗时长了,踢出副本", playerID)
+            PlayerControl.PlayerLeaveFB(curPlayer)
+        else:
+            # 处理buff
+            __parseFightBuff(curPlayer, fightMemCount, needMemCount, skillTypeID, tick)
+            
+    SendGameServer("FBMemberHurt", [statsType, familyID, fightMemCount, addFamilyHurt])
+    return
+
+def __parseFightBuff(curPlayer, fightMemCount, needMemCount, skillTypeID, tick):
+    if fightMemCount < needMemCount:
+        #GameWorld.DebugLog("    人数不足战斗buff", curPlayer.GetPlayerID())
+        BuffSkill.DelBuffBySkillID(curPlayer, skillTypeID, tick)
+        return
+    skillLV = fightMemCount - needMemCount + 1 
+    findBuff = SkillCommon.FindBuffByID(curPlayer, skillTypeID)[0]
+    if findBuff and findBuff.GetSkill().GetSkillLV() == skillLV:
+        #GameWorld.DebugLog("    战斗buff等级不变.skillTypeID=%s,skillLV=%s" % (skillTypeID, skillLV), curPlayer.GetPlayerID())
+        return
+    #GameWorld.DebugLog("    战斗buff等级改变.skillTypeID=%s,skillLV=%s" % (skillTypeID, skillLV), curPlayer.GetPlayerID())
+    BuffSkill.DelBuffBySkillID(curPlayer, skillTypeID, tick)
+    SkillCommon.AddBuffBySkillType(curPlayer, skillTypeID, tick, skillLV)
+    return
+
+def OnEnterFamily(curPlayer):
+    #进入仙盟时补同步领奖状态到GameServer
+    SendGameServer_FamilyHurtAwardStateFamily(curPlayer)
+    return
+
+def SendGameServer_FamilyHurtAwardStateFamily(curPlayer):
+    playerID = curPlayer.GetPlayerID()
+    familyID = curPlayer.GetFamilyID()
+    hurtAwardStateFamily = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAwardFamily)
+    SendGameServer("FamilyHurtAwardStateFamily", [familyID, playerID, hurtAwardStateFamily])
+    return
+
+##玩家退出副本
+def DoExitFB(curPlayer, tick):
+    statsFBMemberHurt(tick, 2, curPlayer.GetPlayerID())
+    return
+
+##玩家主动离开副本.
+def DoPlayerLeaveFB(curPlayer, tick):
+    return
+
+## 玩家对NPC造成伤害
+def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):
+    familyID = curPlayer.GetFamilyID()
+    if not familyID:
+        return
+    bossID = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_FamilyBossMap, 0)[1]
+    if bossID != curNPC.GetNPCID():
+        return
+    playerID = curPlayer.GetPlayerID()
+    batPlayer = GetBattlePlayer(playerID)
+    batPlayer.hurtValue += hurtHP
+    #GameWorld.DebugLog("增加伤血: familyID=%s,hurtHP=%s, %s" % (familyID, hurtHP, batPlayer.hurtValue), playerID)
     return
 
 ## 是否副本复活
-#  @param None
-#  @return 是否副本复活
 def OnPlayerReborn():
     return True
 
-## 重置副本复活玩家坐标点
-# @param None
-# @return 无意义
 def OnResetFBRebornPlacePos(curPlayer, rebornPlace, tick):
     ipyEnterPosInfo = FBCommon.GetFBLineEnterPosInfo(ChConfig.Def_FBMapID_FamilyBossMap, 0)
     posX, posY = ipyEnterPosInfo[:2]
     curPlayer.ResetPos(posX, posY)
     return
 
-##玩家退出家族处理
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 返回值无意义
-def OnLeaveFamily(curPlayer, tick):
-    #GameWorld.DebugLog("OnLeaveFamily...")
-    #curPlayerID = curPlayer.GetPlayerID()
-    PlayerControl.PlayerLeaveFB(curPlayer)
-    return
-
-##获得副本帮助信息
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 无意义
-# @remarks 用于通知阵营比分条
-def DoFBHelp(curPlayer, tick):
-    helpDict = {}
-  
-    gameFB = GameWorld.GetGameFB()
-    curStar = gameFB.GetGameFBDictByKey(FamilyBossFB_Star)
-    helpDict[FBCommon.Help_grade] = curStar
-    FBCommon.Notify_FBHelp(curPlayer, helpDict)
-    return
-
-
-## 执行副本杀怪逻辑
-#  @param curPlayer 杀怪的人
-#  @param curNPC 被杀的怪
-#  @param tick 当前时间
-#  @return None
-def DoFB_Player_KillNPC(curPlayer, curNPC, tick):
-    
-    bossID = curNPC.GetNPCID()
-    refreshMark, refreshBossID = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_FamilyBossMap, 0)
-
-    if bossID != refreshBossID:
-        return
-    GameWorld.DebugLog('仙盟BOSS已被击杀!')
-    
-#    # 全服广播
-#    PlayerControl.WorldNotify(0, "jiazu_liubo_202580", [curPlayer.GetFamilyName(), mapID, bossID])
-    __DoFamilyBossFBOver(tick, True)
-    return
-
-## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定
-#  @param attacker 攻击方
-#  @param defender 防守方
-#  @return bool
 def CheckCanAttackTagObjInFB(attacker, defender):
     gameFB = GameWorld.GetGameFB()
     if gameFB.GetFBStep() != FB_Step_Fighting:
@@ -432,5 +315,95 @@
     return True
 
 
+def GetFamilyBossHurtAward(curPlayer, awardType, awardIndex):
+    ## awardType 1-个人;2-仙盟
+    
+    awardIndex = GameWorld.ToIntDef(awardIndex)
+    playerID = curPlayer.GetPlayerID()
+    ipyData = IpyGameDataPY.GetIpyGameData("FamilyBossHurtAward", awardType, awardIndex)
+    if not ipyData:
+        return
+    needHurtTotal = ipyData.GetNeedHurtTotal()
+    awardItemList = ipyData.GetAwardItemList()
+    
+    familyID = curPlayer.GetFamilyID()
+    if awardType == 2:
+        if not familyID:
+            return
+        rewardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAwardFamily)
+        if rewardRecord & pow(2, awardIndex):
+            GameWorld.DebugLog("仙盟boss伤血仙盟奖励已领奖!awardIndex=%s,rewardRecord=%s" % (awardIndex, rewardRecord), playerID)
+            return
+        SendGameServer("FamilyHurtAwardReq", [familyID, awardType, awardIndex, needHurtTotal, awardItemList], playerID)
+        return
+    
+    hurtValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValue)
+    hurtValuePoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValuePoint)
+    hurtValueTotal = hurtValuePoint * ChConfig.Def_PerPointValue + hurtValue
+    
+    if hurtValueTotal < needHurtTotal:
+        GameWorld.DebugLog("仙盟boss伤血个人奖励伤血不足不能领取: awardIndex=%s,hurtValueTotal=%s < %s" % (awardIndex, hurtValueTotal, needHurtTotal), playerID)
+        return
+    
+    rewardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAward)
+    if rewardRecord & pow(2, awardIndex):
+        GameWorld.DebugLog("仙盟boss伤血个人奖励已领奖!awardIndex=%s,rewardRecord=%s" % (awardIndex, rewardRecord), playerID)
+        return
+    updRewardRecord = rewardRecord | pow(2, awardIndex)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtAward, updRewardRecord)
+    
+    GameWorld.DebugLog("仙盟boss伤血仙盟奖励发放: familyID=%s,awardType=%s,awardIndex=%s,updRewardRecord=%s,awardItemList=%s" 
+                       % (familyID, awardType, awardIndex, updRewardRecord, awardItemList), playerID)
+    
+    event = ["FamilyBossHurtAward", False, {"awardType":awardType, "awardIndex":awardIndex}]
+    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, None, event)
+    
+    SyncFamilyBossPlayerInfo(curPlayer)
+    return
 
+def SendGameServer(msgType, msgData, playerID=0):
+    msgInfo = str([msgType, msgData])
+    GameWorld.DebugLog("仙盟boss试炼同步GameServer: msgType=%s,%s" % (msgType, msgData), playerID)
+    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "FamilyBoss", msgInfo, len(msgInfo))
+    return
 
+def GameServer_FamilyBossInfo(curPlayer, resultList):
+    playerID = curPlayer.GetPlayerID()
+    msgType, msgData = resultList[:2]
+    
+    GameWorld.Log("仙盟Boss试炼GameServer返回: %s" % str(resultList), playerID)
+    if msgType == "FamilyHurtAwardReq":
+        familyID, awardType, awardIndex, needHurtTotal, awardItemList = msgData
+        hurtValueTotal = resultList[2]
+        if hurtValueTotal < needHurtTotal:
+            GameWorld.DebugLog("仙盟boss伤血仙盟奖励伤血不足不能领取: awardIndex=%s,hurtValueTotal=%s < %s" % (awardIndex, hurtValueTotal, needHurtTotal), playerID)
+            return
+        
+        rewardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAwardFamily)
+        if rewardRecord & pow(2, awardIndex):
+            GameWorld.DebugLog("仙盟boss伤血仙盟奖励返回时已领奖!awardIndex=%s,rewardRecord=%s" % (awardIndex, rewardRecord), playerID)
+            return
+        updRewardRecord = rewardRecord | pow(2, awardIndex)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtAwardFamily, updRewardRecord)
+        
+        GameWorld.DebugLog("仙盟boss伤血仙盟奖励发放: familyID=%s,awardType=%s,awardIndex=%s,updRewardRecord=%s,awardItemList=%s" 
+                           % (familyID, awardType, awardIndex, updRewardRecord, awardItemList), playerID)
+        
+        event = ["FamilyBossHurtAward", False, {"awardType":awardType, "awardIndex":awardIndex}]
+        ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, None, event)
+        
+        SendGameServer_FamilyHurtAwardStateFamily(curPlayer)
+        SyncFamilyBossPlayerInfo(curPlayer)
+        
+    return
+
+def SyncFamilyBossPlayerInfo(curPlayer):
+    clientPack = ChPyNetSendPack.tagMCFamilyBosFBPlayerInfo()
+    clientPack.Clear()
+    clientPack.HurtTotal = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValue)
+    clientPack.HurtTotalPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValuePoint)
+    clientPack.FightSeconds = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossFightSeconds)
+    clientPack.HurtAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAward)
+    clientPack.HurtAwardStateFamily = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAwardFamily)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index cf71868..c5b7167 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -1981,6 +1981,13 @@
                         ("dict", "Award2", 0),
                         ),
 
+                "FamilyBossHurtAward":(
+                        ("BYTE", "AwardType", 1),
+                        ("BYTE", "RecordIndex", 1),
+                        ("DWORD", "NeedHurtTotal", 0),
+                        ("list", "AwardItemList", 0),
+                        ),
+
                 "ItemWashMax":(
                         ("BYTE", "Type", 1),
                         ("BYTE", "Star", 1),
@@ -6223,6 +6230,21 @@
     def GetAward1(self): return self.Award1 # 奖励 [[独立概率万分率,[物品ID,数量,是否拍品]],..]
     def GetAward2(self): return self.Award2 # 饼图奖励{随机次数:[(概率,[物品ID,数量,是否拍品]),..]}
 
+# 仙盟试炼伤血奖励表
+class IPY_FamilyBossHurtAward():
+    
+    def __init__(self):
+        self.AwardType = 0
+        self.RecordIndex = 0
+        self.NeedHurtTotal = 0
+        self.AwardItemList = []
+        return
+        
+    def GetAwardType(self): return self.AwardType # 奖励类型 1-个人;2-仙盟
+    def GetRecordIndex(self): return self.RecordIndex # 奖励记录索引,同奖励类型时记录索引不可重复
+    def GetNeedHurtTotal(self): return self.NeedHurtTotal # 所需总伤血
+    def GetAwardItemList(self): return self.AwardItemList # 奖励物品列表[[物品ID,个数,是否拍品], ...]
+
 # 装备洗练等级上限
 class IPY_ItemWashMax():
     
@@ -6950,6 +6972,8 @@
         self.ipyEquipPlusEvolveLen = len(self.ipyEquipPlusEvolveCache)
         self.ipyFamilyBossAwardCache = self.__LoadFileData("FamilyBossAward", IPY_FamilyBossAward)
         self.ipyFamilyBossAwardLen = len(self.ipyFamilyBossAwardCache)
+        self.ipyFamilyBossHurtAwardCache = self.__LoadFileData("FamilyBossHurtAward", IPY_FamilyBossHurtAward)
+        self.ipyFamilyBossHurtAwardLen = len(self.ipyFamilyBossHurtAwardCache)
         self.ipyItemWashMaxCache = self.__LoadFileData("ItemWashMax", IPY_ItemWashMax)
         self.ipyItemWashMaxLen = len(self.ipyItemWashMaxCache)
         self.ipyHorsePetBossAwardCache = self.__LoadFileData("HorsePetBossAward", IPY_HorsePetBossAward)
@@ -7550,6 +7574,8 @@
     def GetEquipPlusEvolveByIndex(self, index): return self.ipyEquipPlusEvolveCache[index]
     def GetFamilyBossAwardCount(self): return self.ipyFamilyBossAwardLen
     def GetFamilyBossAwardByIndex(self, index): return self.ipyFamilyBossAwardCache[index]
+    def GetFamilyBossHurtAwardCount(self): return self.ipyFamilyBossHurtAwardLen
+    def GetFamilyBossHurtAwardByIndex(self, index): return self.ipyFamilyBossHurtAwardCache[index]
     def GetItemWashMaxCount(self): return self.ipyItemWashMaxLen
     def GetItemWashMaxByIndex(self, index): return self.ipyItemWashMaxCache[index]
     def GetHorsePetBossAwardCount(self): return self.ipyHorsePetBossAwardLen
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 da134b0..9d24aa1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -77,6 +77,7 @@
 import PlayerCrossBattlefield
 import GameFuncComm
 import PlayerMagicWeapon
+import GameLogic_FamilyBoss
 import GameLogic_TrialTower
 import GameLogic_FamilyWar
 import PlayerBossReborn
@@ -5686,6 +5687,9 @@
     #境界修仙之路奖励
     elif rewardType == ChConfig.Def_RewardType_RealmXXZL:
         PlayerPrestigeSys.GetXXZLAward(curPlayer, dataEx)
+    #仙盟boss伤害奖励
+    elif rewardType == ChConfig.Def_RewardType_FamilyBossHurt:
+        GameLogic_FamilyBoss.GetFamilyBossHurtAward(curPlayer, dataEx, dataExStr)
     #玩法前瞻奖励
     elif rewardType == ChConfig.Def_RewardType_GameNotice:
         OnGiveAwardByClient(curPlayer, rewardType, ChConfig.Def_PDict_GameNoticeAwardState, IpyGameDataPY.GetFuncEvalCfg("GameNoticeReward", 1))
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
index 09fe777..baab6fa 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -72,7 +72,6 @@
 import GameLogic_ElderBattlefield
 import GameLogic_AllFamilyBoss
 import GameLogic_HorsePetBoss
-import GameLogic_FamilyBoss
 import GameLogic_FamilyWar
 import OpenServerCampaign
 import PlayerCostRebate
@@ -1322,12 +1321,6 @@
         
         if key == ShareDefine.Def_Notify_WorldKey_VSFamilyInfo:
             PyGameData.VSFamilyInfo = eval(msgValue)
-            return
-        
-        if key == ShareDefine.Def_Notify_WorldKey_FamilyBossOpenCount:
-            if GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_FamilyBossMap:
-                familyID, openCount = eval(msgValue)
-                GameLogic_FamilyBoss.GameServerOpenFamilyBoss(familyID, openCount)
             return
         
         if key == ShareDefine.Def_Notify_WorldKey_FamilyPartyInfo:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
index 3fbf392..af014ae 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
@@ -26,6 +26,7 @@
 import ChPyNetSendPack
 import DataRecordPack
 import GameLogic_FamilyWar
+import GameLogic_FamilyBoss
 import ChMapToGamePyPack
 import PlayerFamilyTech
 import PlayerFamilyRedPacket
@@ -156,6 +157,7 @@
     PlayerFamilyTech.Sync_PlayerFamilyTechLV(curPlayer)
     DelAddFamilyRecord(curPlayer)
     GameLogic_FamilyWar.DoCheckChampionFamilyTitle(curPlayer)
+    GameLogic_FamilyBoss.OnEnterFamily(curPlayer)
     PlayerFamilyRedPacket.CreatCacheRedPacktet(curPlayer)
     return
 
@@ -661,82 +663,6 @@
     sendMsg = '%s'%(infoDict)
     #GameWorld.DebugLog("Send_GameServer_PyAddFamilyInfoValue sendMsg=%s" % sendMsg)
     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, 'PyAddFamilyInfoValue', sendMsg, len(sendMsg))
-    return
-
-
-
-#// A6 05  家族捐献兽粮 #tagCMFamilyDonate
-#
-#struct     tagCMFamilyDonate
-#{
-#    tagHead        Head;
-#};
-def OnFamilyDonateItem(index, clientData, tick):
-    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
-    if not curPlayer:
-        return
-    
-    playerFamilyID = curPlayer.GetFamilyID()
-    if playerFamilyID <= 0:
-        return
-    totalAddActiveValue = 0
-    delItemList = []
-    totalCnt = 0
-    curPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
-    for i in range(curPack.GetCount()):
-        item = curPack.GetAt(i)
-        if item == None or item.IsEmpty():
-            continue
-        if item.GetType() != ChConfig.Def_ItemType_FamilyBossFood:
-            continue
-        addActiveValue = item.GetEffectByIndex(0).GetEffectValue(0)
-#        if not addActiveValue:
-#            continue
-        itemCnt = item.GetCount() 
-        totalAddActiveValue += addActiveValue * itemCnt
-        delItemList.append([item, itemCnt])
-        totalCnt += itemCnt
-    if not totalCnt:
-        GameWorld.DebugLog('背包里没有可捐献的物品')
-        return
-    for eatItem, delCnt in delItemList:
-        ItemCommon.DelItem(curPlayer, eatItem, delCnt, False)
-        
-    #累加个人活跃度/贡献度
-    if totalAddActiveValue:
-        AddPlayerFamilyActiveValue(curPlayer, totalAddActiveValue, True, ShareDefine.Def_AddFAVReason_FamilyDonateItem)
-    AddFamilyBossFood(curPlayer, totalCnt, ShareDefine.Def_AddFAVReason_FamilyDonateItem)
-    GameWorld.DebugLog('    捐献仙盟兽粮 totalCnt=%s,totalAddActiveValue=%s'%(totalCnt,totalAddActiveValue))
-    return
-
-def DoAddFamilyBossFoodEx(curPlayer, itemID, itemCnt, reason=0):
-    itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
-    if not itemData:
-        return
-    if itemData.GetType() != ChConfig.Def_ItemType_FamilyBossFood:
-        return
-    addActiveValue = itemData.GetEffectByIndex(0).GetEffectValue(0)
-    if not addActiveValue:
-        return
-    totalAddActiveValue = addActiveValue * itemCnt
-    GameWorld.DebugLog('自动捐献仙盟兽粮 totalCnt=%s,totalAddActiveValue=%s,reason=%s' % (itemCnt, totalAddActiveValue, reason))
-    #累加个人活跃度/贡献度
-    AddPlayerFamilyActiveValue(curPlayer, totalAddActiveValue, True, reason)
-    AddFamilyBossFood(curPlayer, itemCnt, reason)
-    return True
-
-##增加兽粮
-# @param curPlayer 玩家实例
-# @param addExp 增加的经验点
-# @return 返回值无意义
-def AddFamilyBossFood(curPlayer, addExp, reason):
-    #没有家族不处理
-    familyID = curPlayer.GetFamilyID()
-    if familyID == 0:
-        return
-    if addExp <= 0:
-        return
-    SendPack_GameServer_AddFamilyDetailEx(curPlayer, 0, 0, addExp, reason)
     return
 
 #---------------------------------------------------------------------
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_FamilyBoss.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_FamilyBoss.py
new file mode 100644
index 0000000..442509f
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_FamilyBoss.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.RemoteQuery.GY_Query_FamilyBoss
+#
+# @todo:战盟boss副本/仙盟试炼
+# @author hxp
+# @date 2023-09-29
+# @version 1.0
+#
+# 详细描述: 战盟boss副本/仙盟试炼
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2023-09-29 02:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import GameLogic_FamilyBoss
+
+#---------------------------------------------------------------------
+#逻辑实现
+## 请求逻辑
+#  @param query_Type 请求类型
+#  @param query_ID 请求的玩家ID
+#  @param packCMDList 发包命令 [ ]
+#  @param tick 当前时间
+#  @return "True" or "False" or ""
+#  @remarks 函数详细说明.
+def DoLogic(query_Type, query_ID, packCMDList, tick):
+    return ""
+
+#---------------------------------------------------------------------
+#执行结果
+## 执行结果
+#  @param curPlayer 发出请求的玩家
+#  @param callFunName 功能名称
+#  @param funResult 查询的结果
+#  @param tick 当前时间
+#  @return None
+#  @remarks 函数详细说明.
+def DoResult(curPlayer, callFunName, funResult, tick):
+    
+    GameWorld.DebugLog("GY_Query_FamilyBoss funResult=%s" % str(funResult))
+    if funResult == "":
+        return
+    GameLogic_FamilyBoss.GameServer_FamilyBossInfo(curPlayer, eval(funResult))
+    return
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index 85ff7dd..58b580d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -52,8 +52,6 @@
 FBOpenTimeRecord = {} #限时副本开启时间记录
 
 VSFamilyInfo = [] # 仙盟联赛开启的副本信息 [是否最终决赛场次, roundNum, groupID, [familyIDA, failyIDB], [familyNameA, familyNameB], [familyRankA, familyRankB]]
-g_familyBossOpenCountDict = {} # 仙盟boss开启次数 {familyID:次数, ...}
-g_familyBossPlayer = {} # 仙盟boss参与玩家 {familyID:[playerID, ...], ...}
 g_familyKillHorsePetRobBossCntDict = {} # 骑宠争夺仙盟已击杀boss数 {familyID:击杀数, ...}
 
 g_PassiveEffManager = None  # 被动技能(效果)单例
@@ -111,6 +109,7 @@
 
 g_Qudao_DoubleBill = {} # 渠道删档充值返利
 
+g_familyBossHurtPlayerDict = {} # 仙盟boss战斗玩家 {playerID:BattlePlayer, ...}
 g_allfamilyBossDict = {} # 多仙盟boss信息 {familyID:[familyName, 伤害, [playerID], ...}
 g_horsePetBossPlayerHurtDict = {} #骑宠boss信息 {lineID:{playerID:[playerName,hurt]}}
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index abe82a2..8977ad8 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -166,8 +166,6 @@
 Def_Notify_WorldKey_VSFamilyInfo = "VSFamilyInfo"  # 仙盟联赛对战仙盟信息
 Def_Notify_WorldKey_ChampionFamilyID = "ChampionFamilyID"  # 仙盟联赛上次冠军仙盟ID
 
-Def_Notify_WorldKey_FamilyBossOpenCount = "FamilyBossOpenCount"  # 仙盟boss开启次数
-
 Def_Notify_WorldKey_FamilyPartyInfo = "FamilyPartyInfo"  # 仙盟宴会数据
 Def_Notify_WorldKey_FamilyPartyAddFamilyActivity = "FamilyPartyAddFamilyActivity"  # 仙盟宴会地图成员增加仙盟活跃令
 

--
Gitblit v1.8.0