hxp
2023-09-29 2a659639d74889599ed54458863a2f7b31ff4eff
9946 【BT0.1】【主干】仙盟BOSS修改
22个文件已修改
1个文件已添加
1741 ■■■■ 已修改文件
PySysDB/PySysDBG.h 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/PyNetPack.ini 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py 368 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_FamilyBoss.py 633 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_FamilyBoss.py 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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
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
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
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
#------------------------------------------------------
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):
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
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:
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
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))
def FamilyBossFBOnWeek(curFamily):
        return
    
    __Notify_FamilyAllMemberBossFBInfo(curFamily)
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())
def OnPlayerJionFamily(curFamily, curPlayer):
    SyncFamilyBosFBInfo(curPlayer.GetFamilyID(), None, curPlayer)
        return
    
    if not ChekcFamilyBossOpenTime():
        GameWorld.DebugLog("    不在活动时间内")
        return
def __FamilyBossFBHurtOnDay(curFamily):
    familyID = curFamily.GetID()
    
    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))
    return
## 开启家族boss副本消耗逻辑
#  @param curFamily 家族实例
#  @param curPlayer 玩家实例
#  @param costInfoList 消耗信息列表
#  @param openIndex 开启次数索引
#  @return True-扣除消耗成功
def __DoOpenCostLogic(curFamily, curPlayer, foodCost):
    # 成员家族等级需求判断
    curMember = curFamily.FindMember(curPlayer.GetPlayerID())
    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)
    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
def NotifyFamilyBossFBInfo(curPlayer):
    '''通知玩家仙盟BOSS副本信息'''
    familyID = curPlayer.GetFamilyID()
    if familyID:
        familyBossFBInfoPack = __GetFamilyBossFBInfoPack(familyID)
        NetPackCommon.SendFakePack(curPlayer, familyBossFBInfoPack)
    #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
        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 curFamily 家族对象
#  @return None
def __Notify_FamilyAllMemberBossFBInfo(curFamily):
    familyID = curFamily.GetID()
    familyBossFBInfoPack = __GetFamilyBossFBInfoPack(familyID)
def GetFamilyBossFBActionData(familyID, playerID=1):
    ## 获取仙盟boss伤血action
    # playerID  1-特殊类型,记录仙盟总伤害信息;>1-玩家仙盟伤血奖励领奖记录
    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)
    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, familyBossFBInfoPack)
            NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
    if curPlayer:
        NetPackCommon.SendFakePack(curPlayer, clientPack)
## 获取家族副本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))
    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)
    # 广播给在线家族成员家族boss副本信息
    __Notify_FamilyAllMemberBossFBInfo(curFamily)
    return
#############################多仙盟BOSS#############################
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)
@@ -1018,6 +1019,9 @@
#            return
#        resultName = '%s' % PlayerFamilyStore.DoMapServerFamilyStore(curPlayer, eval(resultName), tick)
        
    if not srcPlayerID:
        return
    srcPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
    
    if not srcPlayer:
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"  # 仙盟宴会地图成员增加仙盟活跃令
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
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复活相关活动定义
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
#------------------------------------------------------
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):
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
class BattlePlayer():
(
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))
    def __init__(self, playerID):
        self.playerID = playerID
        self.hurtValue = 0 # 当前累计伤害
        self.hurtValueLast = 0 # 上次同步结算时伤害
        self.fightTickTotal = 0 # 累计战斗tick
        self.statsTick = 0 # 统计tick
    return
def AddFamilyBossPlayer(curPlayer):
    familyID = curPlayer.GetFamilyID()
    if not familyID:
    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
    if familyID not in PyGameData.g_familyBossOpenCountDict:
def OnFBPlayerOnLogin(curPlayer):
    SyncFamilyBossPlayerInfo(curPlayer)
        return
    openCount = PyGameData.g_familyBossOpenCountDict[familyID]
    familyPlayerList = PyGameData.g_familyBossPlayer.get(familyID, [])
def OnFBPlayerOnDay(curPlayer):
    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)
    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
##开启副本
# @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))
    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)
    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)
    batPlayer = GetBattlePlayer(playerID)
    batPlayer.onEnter(curPlayer, tick)
    GameWorld.DebugLog("DoEnterFB: fbStep=%s,fightTickTotal=%s,hurtValue=%s" % (fbStep, batPlayer.fightTickTotal, batPlayer.hurtValue), playerID)
   
    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)
    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):
def __DoLogic_MapFighting(tick):
    gameFB = GameWorld.GetGameFB()
    curStar = gameFB.GetGameFBDictByKey(FamilyBossFB_Star)
    if curStar == 1:
        return curStar
    lastTick = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NotifyFBHelpTick)
    if tick - lastTick < 5000:
        return
    gameFB.SetGameFBDict(ChConfig.Def_FB_NotifyFBHelpTick, tick)
    statsFBMemberHurt(tick)
    return
    
    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
def statsFBMemberHurt(tick, statsType=0, exitPlayerID=0):
    ## 统计副本仙盟成员伤害
    # statsType 0-常规;1-玩家进入;2-玩家退出
            
    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:
    fightMemCount = 0
    familyID = GameWorld.GetGameWorld().GetPropertyID()
        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)
        playerID = curPlayer.GetPlayerID()
        if playerID != exitPlayerID:
            fightMemCount += 1
                
    needMemCount, skillTypeID = IpyGameDataPY.GetFuncEvalCfg("FamilyBossFB", 2)
            
    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))
        return
    # 时间到,踢出还在副本的玩家等...
    GameWorldProcess.CloseFB(tick)
    FBCommon.SetFBStep(FB_Step_Over, tick)
    FBCommon.DoLogic_FBKickAllPlayer()
    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)
    __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))
    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)
        
    if isKill:
        doCountRate = eval(IpyGameDataPY.GetFuncCompileCfg("FamilyBOSSDropRule", 1))
        doCountAdd = eval(IpyGameDataPY.GetFuncCompileCfg("FamilyBOSSDropRule", 2))
        FBCommon.SetNPCDropDoCountRate(gameFB, doCountRate, doCountAdd)
        hurtValue = batPlayer.hurtValue
        addHurtValue = max(0, hurtValue - batPlayer.hurtValueLast)
        batPlayer.hurtValueLast = hurtValue
        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
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
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))
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:
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
#---------------------------------------------------------------------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_FamilyBoss.py
New file
@@ -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
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]}}
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"  # 仙盟宴会地图成员增加仙盟活跃令