#!/usr/bin/python
# -*- coding: GBK -*-
#---------------------------------------------------------------------
#
#---------------------------------------------------------------------
##@package PlayerFamily
# @todo: ¼Ò×åÂß¼¹ÜÀíÆ÷
#
# @author: eggxp
# @date 2010-3-31
# @version 1.0
#
# @note: 
#---------------------------------------------------------------------
#------------------------------------------------------------------------------ 
#"""Version = 2017-03-06 14:30"""
#---------------------------------------------------------------------
import GameWorld
import IPY_GameServer
import ChConfig
import PlayerRequest
import PlayerControl
import DirtyList
import ReadChConfig
import PlayerDBGSEvent
import ShareDefine
#import PlayerFamilyTech
import PlayerFamilyAction
import DataRecordPack
import PlayerFamilyBoss
import IpyGameDataPY
import PlayerFamilyRedPacket
import GameWorldFamilyWar
import ChPyNetSendPack
import NetPackCommon
import PyDataManager
import PyGameData
import PlayerCompensation
import PlayerFamilyParty
import PlayerFamilySWRH
import PlayerViewCache
import GameWorldBoss
import AuctionHouse
import PlayerTalk
import PlayerTeam
import copy
import random
import time
#---------------------------------------------------------------------
# µ¯ÛÀʱ¼äµÄÅäÖÃλÖÃ
(
ImpeachNoteTime, # °ïÖ÷ÏÂÏß¶à¾Ã¸øµ¯ÛÀÌáʾ
CanImpeachTime, # °ïÖ÷ÏÂÏß¶à¾Ã£¬¿ÉÒÔ¿ªÊ¼µ¯ÛÀ
ImpeachLastTime  # µ¯ÛÀÐèÒª³ÖÐøµÄʱ¼ä
) = range(3)
## ------------------ ÏÉÃË ----------------------
## ÏÉÃËÁªÈüÅÅÃû
def GetFamilyWarRank(curFamily): return curFamily.GetPoint()
def SetFamilyWarRank(curFamily, rank): return curFamily.SetPoint(rank)
## ÏÉÃË×ÜÕ½Á¦£¬ÐèÖ§³Ö³¬¹ý20E
def GetFamilyTotalFightPower(curFamily): return curFamily.GetExtra4() * ChConfig.Def_PerPointValue + curFamily.GetExtra5()
def SetFamilyTotalFightPower(curFamily, totalFightPower):
    curFamily.SetExtra4(totalFightPower / ChConfig.Def_PerPointValue)
    curFamily.SetExtra5(totalFightPower % ChConfig.Def_PerPointValue)
    return
def GetFamilyTotalFightPowerByID(familyID):
    family = GameWorld.GetFamilyManager().FindFamily(familyID)
    if not family:
        return 0
    return GetFamilyTotalFightPower(family)
# ¹«¸æÐ޸ĴÎÊý
def GetFamilyBroadcastCnt(curFamily): return curFamily.GetExtra3()
def SetFamilyBroadcastCnt(curFamily, setCnt): return curFamily.SetExtra3(min(setCnt, ChConfig.Def_UpperLimit_DWord))
# ÊÞÁ¸
def GetFamilyBossFood(curFamily): return curFamily.GetHornor()
def SetFamilyBossFood(curFamily, setCnt): return curFamily.SetHornor(min(setCnt, ChConfig.Def_UpperLimit_DWord))
# ±¾ÖÜÈÎÎñÒÑ»ñµÃ×ʽðÊýÁ¿
def GetCurWeekMissionMoney(curFamily): return curFamily.GetExtra2()
def SetCurWeekMissionMoney(curFamily, value): return curFamily.SetExtra2(min(value, ChConfig.Def_UpperLimit_DWord))
# ÏÉÃËÉϴδ¦ÀíµÄºÏ·þÌì
def GetFamilyMixServerDay(curFamily): return curFamily.GetExtra1()
def SetFamilyMixServerDay(curFamily, value): return curFamily.SetExtra1(value)
## ------------------ ³ÉÔ± ----------------------
def GetMemberFightPower(curMember): return curMember.GetExattr3()
def SetMemberFightPower(curMember, fightPower): return curMember.SetExattr3(fightPower)
def GetMemberJoinTime(curMember): return curMember.GetExattr4()
def SetMemberJoinTime(curMember, joinTime): return curMember.SetExattr4(joinTime)
#----------------------------------------------------------------------
def RandomFakeFamily():
    '''Ëæ»ú3¸ö¼ÙÏÉÃË'''
    fakeFamilyNameList = IpyGameDataPY.GetFuncEvalCfg('FakeFamilyName')
    randomList = range(1, len(fakeFamilyNameList) + 1)
    
    randomCnt = IpyGameDataPY.GetFuncCfg('FakeFamilyName', 2)
    familyManager = GameWorld.GetFamilyManager()
    lackFakeCnt = max(0, randomCnt - familyManager.GetCount()) #»¹Ðè¼ÙÏÉÃ˸öÊý
    
    fakeIDList = []
    curfakeCnt = 0
    for i in xrange(randomCnt):
        fakeIndex = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_FakeFamilyIndex % i)
        fakeIDList.append(fakeIndex)
        if fakeIndex:
            curfakeCnt += 1
    
    lackCnt = lackFakeCnt - curfakeCnt #ÐèÒªËæ»ú¸öÊý
    if lackCnt > 0:
        randomList = list(set(randomList) - set(fakeIDList))
        random.shuffle(randomList)
        for value in randomList:
            familyName = fakeFamilyNameList[value - 1]
            familyName = GameWorld.GbkToCode(familyName)
            findFamily = GameWorld.GetFamilyManager().FindFamilyByName(familyName)
            if findFamily:
                continue
            if 0 not in fakeIDList:
                return []
            changeIndex = fakeIDList.index(0)
            PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_FakeFamilyIndex % changeIndex, value)
            GameWorld.DebugLog('    Ëæ»ú¼ÙÏÉÃË  changeIndex=%s,value=%s'%(changeIndex, value))
            fakeIDList[changeIndex] = value
            lackCnt -= 1
            if not lackCnt:
                break
    elif lackCnt < 0:
        GameWorld.ErrLog('    Ëæ»ú¼ÙÏÉÃËÒì³£ ÒÑ´æÔÚµÄËæ»úÊý´óÓÚ»¹ÐèÒªµÄËæ»ú¸öÊýlackFakeCnt=%s,fakeIDList=%s'%(lackFakeCnt, fakeIDList))
        return []
    return fakeIDList
def SyncFakeFamilyInfo(curPlayer=None):
    '''֪ͨ¼ÙÏÉÃËÐÅÏ¢'''
    fakeIDList = RandomFakeFamily()
    fakeIDList = list(set(fakeIDList)-set([0])) #È¥µô0
    fakeFamilyPack = ChPyNetSendPack.tagGCFakeFamilyInfo()
    fakeFamilyPack.Clear()
    fakeFamilyPack.Count = len(fakeIDList)
    fakeFamilyPack.FakeIDList = fakeIDList
    
    if not curPlayer:
        # È«·þ¹ã²¥ÔÚÏßÍæ¼Ò
        playerManager = GameWorld.GetPlayerManager()
        for i in range(0, playerManager.GetPlayerCount()):
            curPlayer = playerManager.GetPlayerByIndex(i)
            if curPlayer == None or not curPlayer.GetInitOK():
                continue
            
            if PlayerControl.GetIsTJG(curPlayer):
                continue
            NetPackCommon.SendFakePack(curPlayer, fakeFamilyPack)
    else:
        if PlayerControl.GetIsTJG(curPlayer):
            return
        NetPackCommon.SendFakePack(curPlayer, fakeFamilyPack)
    return
def SyncCreatFamilyTimes(curPlayer=None):
    # ֪ͨ½¨ÃË´ÎÊý
    packData = ChPyNetSendPack.tagGCServerCreatFamilyTimes()
    packData.Clear()
    packData.Times = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerCreatFamilyTimes)
    if not curPlayer:
        # È«·þ¹ã²¥ÔÚÏßÍæ¼Ò
        playerManager = GameWorld.GetPlayerManager()
        for i in range(0, playerManager.GetPlayerCount()):
            curPlayer = playerManager.GetPlayerByIndex(i)
            if curPlayer == None or not curPlayer.GetInitOK():
                continue
            
            if PlayerControl.GetIsTJG(curPlayer):
                continue
            NetPackCommon.SendFakePack(curPlayer, packData)
    else:
        if PlayerControl.GetIsTJG(curPlayer):
            return
        NetPackCommon.SendFakePack(curPlayer, packData)
    return
#ÊäÈë¼Ò×åÃû³Æ
#class   IPY_CInputFamilyName
#{
#public:
#
#    char *      GetName();
#};
## ´´½¨¼Ò×å
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param familyName ¼Ò×åÃû³Æ
#  @param fakeIndex ¼ÙÏÉÃËË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def DoCreateFamily(curPlayer, familyName, fakeIndex, tick):
    #---ÑéÖ¤Íæ¼ÒÊôÐÔ---
    curPlayerID = curPlayer.GetPlayerID()
    #¿Í»§¶Ë·¢ËÍ·â°ü, ´´½¨¼Ò×å, ½áÊøÊ¼þ, ÒòMapserver½áÊøÊ¼þ°ü³£³£Ïȵ½, µ¼ÖÂÕâÀï¾³£±»À¹½Ø
    #·ÀÖ¹Íâ¹Ò·¢°ü Mapserverµ÷ÓýӿÚÉèÖÃGameServer_SetPlayerViewFamilyState
#    if curPlayer.GetViewFamilyState() != ShareDefine.TViewFamilyType_CreateFamily:
#        GameWorld.ErrLog("DoCreateFamily GetViewFamilyState = %s, err"%(curPlayer.GetViewFamilyState()), curPlayerID)
#        return
#    if GameWorld.GetPlayerManager().GetForbiddenEnterFamily(curPlayerID):
#        #Founding_Family_Fail ¶Ô²»Æð, À뿪¼Ò×åºóµ±ÈÕÎÞ·¨²»ÄÜ´´½¨¼Ò×å ,²Ù×÷ÎÞЧ!
#        PlayerControl.NotifyCode(curPlayer, "Founding_Family_Fail")
#        return
    if curPlayer.GetFamily() != None:
        #Íæ¼ÒÒѾÓмÒ×å, ´´½¨Ê§°Ü
        PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_85890")
        return
    if curPlayer.GetFamilyID() != 0:
        #·ÀÖ¹Êý¾Ý´íÎó, Ôö¼ÓÒ»²ãÅж¨
        #Íæ¼ÒÒѾÓмÒ×å, ´´½¨Ê§°Ü
        PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_85890")
        return
    #¿Í»§¶ËÅжϵȼ¶¼´¿É
#    if curPlayer.GetLV() < createFamily_MinLV:
#        #GeRen_hwj35_717982 ¶Ô²»Æð,ÄãµÄµÈ¼¶²»×ã {%S1%}¼¶,ÎÞ·¨´´½¨°ï»á!
#        PlayerControl.NotifyCode(curPlayer, "GeRen_hwj35_717982", [createFamily_MinLV])
#        return
    #---ÑéÖ¤´´½¨µÄ¼Ò×åÐÅÏ¢ÊÇ·ñÕýÈ·---
    #C++¹ýÂ˿ոñ
    familyName = GameWorld.GetGameWorld().GetCharTrim(familyName)
    
    fullFamilyName = GetFamilyFullName(curPlayer, familyName)
    if not fullFamilyName:
        return
    if not CheckFamilName(curPlayer, familyName, fullFamilyName):
        return
    
    familyManager = GameWorld.GetFamilyManager()
    curCnt = familyManager.GetCount()
    if curCnt >= familyManager.GetFamilyUpperLimitCount():
        #¶Ô²»Æð,Ŀǰ·þÎñÆ÷¼Ò×åÊýÁ¿ÒÑÂú,´´½¨¼Ò×åʧ°Ü
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_Family_Full")
        return
    fakeIndexList = RandomFakeFamily()
    #´´½¨¼Ò×åÂß¼
    curFamily = familyManager.AddFamily(fullFamilyName)
    if curFamily == None:
        GameWorld.ErrLog("¼Ò×å´´½¨ÊýÄ¿ÒÑÂú, ´´½¨¼Ò×åʧ°Ü", curPlayerID)
        return
    GameWorld.Log("´´½¨ÏÉÃË: familyID=%s,playerID=%s" % (curFamily.GetID(), curPlayerID))
    #---´´½¨¼Ò×å---
    curFamily.SetCreateTime(GameWorld.GetCurrentDataTimeStr())
    curFamily.SetLV(1)
    curFamily.SetAcceptJoin(ShareDefine.FamilyAcceptJoin_Agree)     #ÉèÖÃÊÕÈË·½Ê½ÎªÖ±½Óͨ¹ýÉêÇë
    PyDataManager.GetFamilyStoreItemManager().DelFamilyStoreItemAll(curFamily.GetID())
    
    #д´½¨µÄÏÉÃËĬÈÏÉèÖÃÒÑ´¦Àí¹ýºÏ·þ
    SetFamilyMixServerDay(curFamily, PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_LastMixServerDay))
    
    #-ÉèÖüÒ×å³ÉÔ±ÊôÐÔ
    DoPlayerJionFamily(curFamily, curPlayer, IPY_GameServer.fmlLeader)
    creatFamilyTimes = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerCreatFamilyTimes)
    #¿ÛµÀ¾ß(ǰN¸öÕ½Ã˲¢ÇÒ¼Ù±àºÅÔÚËæ»ú±àºÅÀﲻҪǮ)
    if fakeIndex and fakeIndex in fakeIndexList:
        PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_FakeFamilyIndex % fakeIndexList.index(fakeIndex), 0)
        GameWorld.Log('    ´´½¨Ç°n¸ö¼ÙÏÉÃ˲»¿ÛÇ®! ¼ÙÏÉÃËË÷Òý%s'%fakeIndexList.index(fakeIndex))
    elif creatFamilyTimes < IpyGameDataPY.GetFuncCfg('CreateFamilyNeedMoney', 3):
        GameWorld.Log('    ´´½¨Ç°n¸öÏÉÃ˲»¿ÛÇ®! creatFamilyTimes=%s' % creatFamilyTimes)
    else:
        for i, findex in enumerate(fakeIndexList):
            if findex:
                PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_FakeFamilyIndex % i, 0)
                break
            
        needMoney = IpyGameDataPY.GetFuncCfg('CreateFamilyNeedMoney')
        if needMoney:
            moneyType = IpyGameDataPY.GetFuncCfg('CreateFamilyNeedMoney', 2)
            sendMsg = str([moneyType, needMoney])
            curPlayer.MapServer_QueryPlayerResult(0, 0, "CreateFamilyPayMoney", sendMsg, len(sendMsg))
            #curPlayer.MapServer_PayMoney(moneyType, needMoney)
            #Íæ¼Ò´´½¨¼Ò×å·ÑÓÃת»¯Îª¼Ò×å³õʼ×ʽð
            #PlayerAddFamilyMoney(curPlayer, curFamily, needMoney)
  
    SyncFakeFamilyInfo()    
    
    #¿ª·þǰ¼¸Ìì´´½¨Ôò¸ø³ÆºÅ
#    needOpenServerDay, dienstgradID = ReadChConfig.GetEvalChConfig("FamilyCreateAddTitle")
#    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay)
#    if openServerDay < needOpenServerDay:
#        result = str(dienstgradID)
#        curPlayer.MapServer_QueryPlayerResult(0, 0, "AddDienstgrad", result, len(result))
    
#===============================================================================
#    ´ËÂß¼·ÅÈëDoPlayerJionFamilyº¯Êý
#    #Ë͸øÍæ¼Ò¼Ò×åÐÅÏ¢
#    curPlayer.SetPlayerGetFamilyInfoTick(tick)
#    curPlayer.Sync_FamilyInfo()
#===============================================================================
    #---´´½¨¼Ò×åÍê±Ï---
    #ÖØÐÂÅÅÐò¼Ò×å
    #GameWorld.GetFamilyManager().SortByLV()
    DoFamilySort() # ´´ÃËÊ±Ç¿ÖÆ¸üÐÂÒ»´ÎÕ½Á¦
    
    #XW_JZ_EstablishSud ¹§Ï²Äú£¬¼Ò×彨Á¢³É¹¦!    25  -   -
    PlayerControl.NotifyCode(curPlayer, "XW_JZ_EstablishSud")
    PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerCreatFamilyTimes, min(creatFamilyTimes + 1, ShareDefine.Def_UpperLimit_DWord))
    SyncCreatFamilyTimes()
    #°ï»á´´½¨Á÷Ïò
    DataRecordPack.DR_CreateFamily(curPlayer.GetAccID(), curPlayerID, curPlayer.GetName(),
                                   fullFamilyName, curFamily.GetID(), creatFamilyTimes+1)
    GameWorld.Log('´´½¨¼Ò×å : %s(%s), fakeIndex=%s, creatFamilyTimes=%s' % (fullFamilyName, curFamily.GetID(), fakeIndex, creatFamilyTimes+1), curPlayerID)
    PlayerControl.WorldNotify(0, "jiazu_liubo_671654", [curPlayer.GetName(), fullFamilyName, curFamily.GetID()])
    return
## »ñÈ¡¼Ò×åÈ«Ãû
def GetFamilyFullName(curPlayer, familyName):
    serverID = GameWorld.GetPlayerServerID(curPlayer)
    roleNameFormat = eval(ReadChConfig.GetChConfig("FamilyNameFormat"))
    nameFormat, paramList, maxLen, maxServerID, specServerDict = roleNameFormat
    if serverID > maxServerID or serverID <= 0:
        GameWorld.ErrLog("GetFamilyFullName serverID=%s error! maxServerID=%s, check FamilyNameFormat.txt" % (serverID, maxServerID))
        return ""
    
    nameFormatInfo = GameWorld.GetDictValueByRangeKey(specServerDict, serverID)
    if nameFormatInfo:
        nameFormat, paramList = nameFormatInfo
        
    fullName = nameFormat % tuple(paramList)
    if len(fullName) > maxLen:
        GameWorld.ErrLog("GetFamilyFullName familyName=%s,È«Ãû=%s len=%s > %s, check FamilyNameFormat.txt" % (familyName, fullName, len(fullName), maxLen))
        PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_980181", [maxLen / 2, maxLen])
        return ""
    
    return fullName
#---------------------------------------------------------------------
##Íæ¼Ò¼ÓÈë¼Ò×å.
# @param curFamily ¼Ò×åʵÀý
# @param jionPlayer Íæ¼ÒʵÀý
# @param jionFamilySetLv Íæ¼ÒÒÔʲôµÈ¼¶¼ÓÈë¼Ò×å
# @return ·µ»ØÖµÎÞÒâÒå
# @remarks Íæ¼Ò¼ÓÈë¼Ò×å
def DoPlayerJionFamily(curFamily, jionPlayer, jionFamilySetLv):
    #¼ÓÈë¼Ò×å
    familyMember = curFamily.AddMember(jionPlayer)
    #ˢлù±¾ÐÅÏ¢
    RefreshFamilyMemberBaseMsg(familyMember, jionPlayer)
    
    #×峤ÉèÖÃ
    if jionFamilySetLv == IPY_GameServer.fmlLeader:
        curFamily.SetLeaderID(familyMember.GetPlayerID())
        curFamily.SetLeaderName(familyMember.GetName())
        curFamily.SetLeaderOfficialRank(familyMember.GetOfficialRank())
    SetMemberJoinTime(familyMember, int(time.time()))
    #ÉèÖüÒ×åµÈ¼¶¶ÔÓ¦µÄȨÏÞ
    ChangeFamilyMemberLv(familyMember, jionFamilySetLv, True)
    
    #ÉèÖüÒ×åIDºÍÖ¸Õë
    jionPlayer.SetFamilyID(curFamily.GetID())
    jionPlayer.SetFamily(curFamily)
    #֪ͨµØÍ¼·þÎñÆ÷
    jionPlayer.MapServer_FamilyRefresh()
    #֪ͨ¼Ò×åÐÅÏ¢
    #Èç¹û²»¸æËß, ¿Í»§¶ËµÃ²»µ½¼Ò×åË¢ÐÂ, µ¼Ö²»´ò¿ª¼Ò×å½çÃæµÄʱºò, ²»ÄÜÖ±½Óµã»÷Í·ÏñÕÐÈË
    if GetFamilyMemberHasPow(familyMember, ChConfig.Def_PurviewDictKey_CanCall):
        jionPlayer.Sync_FamilyInfo()
        PlayerFamilyAction.ViewFamilyRequestInfo(jionPlayer)
    #֪ͨ¿Í»§¶Ë¼Ò×å¿Æ¼¼ÐÅÏ¢
    #jionPlayer.Sync_FamilyTechInfo()
    # ֪ͨËùÓмÒ×å³ÉÔ±µ¯ÛÀÐÅÏ¢
    #SendClientImpeachMag(jionPlayer, curFamily)
    
    # Íæ¼ÒÕ½ÃËÃû±ä¸ü´¦Àí
    __OnFamilyNameChange(jionPlayer.GetPlayerID(), curFamily.GetName())
    #Íæ¼Ò»º´æ
    PlayerViewCache.OnPlayerFamilyChange(jionPlayer.GetPlayerID(), curFamily.GetID(), curFamily.GetName())
    PlayerTeam.OnTeamMemFamilyRefresh(jionPlayer, curFamily.GetID())
    #¼ÓÈëÏÉÃËÁªÈü³ÉÔ±
    GameWorldFamilyWar.AddFamilyWarMem(jionPlayer.GetPlayerID(), curFamily.GetID())
    GameWorldFamilyWar.CheckPlayerJoinFamilyWarInfo(jionPlayer)
    #֪ͨսÃ˺ì°üÐÅÏ¢
    PlayerFamilyRedPacket.NotifyRedPacketInfo(jionPlayer)
    
    #֪ͨսÃËBOSS¿ªÆôÐÅÏ¢
    PlayerFamilyBoss.NotifyFamilyBossFBInfo(jionPlayer)
    #֪ͨ¼Ò×å²Ö¿â
    PyDataManager.GetFamilyStoreItemManager().SyncFamilyStoreItem(jionPlayer, curFamily.GetID())
    #ÏÉÃËÅÄÆ·
    AuctionHouse.Sync_FamilyAuctionItemInfo(jionPlayer, curFamily.GetID())
    SetMemberFightPower(familyMember, jionPlayer.GetFightPower())
    AddFamilyIDToFightPowerChangeList(curFamily.GetID())
    
    #֪ͨÏÉÃËÊ¢ÑçÌâÄ¿
    PlayerFamilyParty.NotifyFamilyPartyQuestion(jionPlayer)
    #Í¨ÖªÊØÎÀÈË»ÊÐÅÏ¢
    PlayerFamilySWRH.NotifySWRHInfo(jionPlayer, curFamily.GetID())
    #oss¼Ç¼¼ÓÈë¼Ò×åÐÅÏ¢
    DataRecordPack.DR_PlayerJoinFamily(jionPlayer, curFamily.GetID(), curFamily.GetName(), curFamily.GetCount())
    return
##  Íæ¼ÒÕ½ÃËÃû±ä¸ü´¦Àí
def __OnFamilyNameChange(playerID, familyName):
    GameWorld.DebugLog('    Íæ¼ÒÕ½ÃËÃû±ä¸ü´¦Àí, newFamilyName=%s' % familyName, playerID)
    #²»´¦ÀíÅÅÐаñ
    needChangeFamilyBillboardList = [
                                     ]
    billboardMgr = GameWorld.GetBillboard()
    for billboardIndex in needChangeFamilyBillboardList:
        billBoard = billboardMgr.FindBillboard(billboardIndex)
        if not billBoard:
            GameWorld.DebugLog('    Íæ¼ÒÕ½ÃËÃû±ä¸ü´¦Àí ÕÒ²»µ½ÕâÀàÐÍÅÅÐаñ billboardIndex=%s' % billboardIndex)
            #ÕÒ²»µ½ÕâÀàÐÍÅÅÐаñ
            continue
        playerBillBoardData = billBoard.FindByID(playerID)
        if not playerBillBoardData:
            GameWorld.DebugLog('    Íæ¼ÒÕ½ÃËÃû±ä¸ü´¦Àí ¸ÃÍæ¼ÒûÓÐÔÚÅÅÐаñÉÏ ', playerID)
            #¸ÃÍæ¼ÒûÓÐÔÚÅÅÐаñÉÏ
            continue
        #¸üÐÂÍæ¼ÒÕ½ÃËÃû×Ö
        playerBillBoardData.SetName2(familyName)
    return
#---------------------------------------------------------------------
##Íæ¼Ò¾èÔù¼Ò×å½ðÇ®
# @param curPlayer Íæ¼ÒʵÀý
# @param curFamily ¼Ò×åʵÀý
# @param playeMoney Íæ¼Ò½ðÇ®
# @return ²¼¶ûÖµ
# @remarks Íæ¼Ò¾èÔù¼Ò×å½ðÇ®
def PlayerAddFamilyMoney(curPlayer, curFamily, playerMoney):
    curFamilyMoney = curFamily.GetMoney()
    #×ʽðÒÑ´ïÉÏÏÞ
    if curFamilyMoney >= ChConfig.Def_UpperLimit_DWord:
        return False
    
    curFamily.SetMoney(min(curFamilyMoney + GetPlayerMoney_Change_FamilyMoney(playerMoney),
                               ChConfig.Def_UpperLimit_DWord))
    #Õ½ÃËÉý¼¶
    #DoFamilyLvUp(curFamily)
    return True
#---------------------------------------------------------------------
##Íæ¼Ò½ðǮת»»Îª¼Ò×å½ðÇ®
# @param playerMoney Íæ¼Ò½ðÇ®
# @return ¼Ò×å½ðÇ®
# @remarks Íæ¼Ò½ðǮת»»Îª¼Ò×å½ðÇ®
def GetPlayerMoney_Change_FamilyMoney(playerMoney):
    return int(playerMoney * ShareDefine.Def_PlayerMoney_Change_FamilyMoney_Rate)
#---------------------------------------------------------------------
## ¼ì²â¼Ò×åÃû³Æ
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param familyName ¼Ò×åÃû³Æ
#  @return None or True
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def CheckFamilName(curPlayer, familyName, fullFamilyName):
    #δͨ¹ýÔà»°ÁбíÅж¨
    if DirtyList.IsWordForbidden(familyName):
        #XW_JZ_Family_NameNoLegality ¶Ô²»Æð,¼Ò×åÃû³ÆÖк¬ÓзǷ¨×Ö·û,´´½¨¼Ò×åʧ°Ü
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_Family_NameNoLegality")
        return
    
    if len(familyName) <= 0 or len(familyName) > ChConfig.Def_CreatFamily_MaxStr:
        PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_980181", [ChConfig.Def_CreatFamily_MaxStr / 2, ChConfig.Def_CreatFamily_MaxStr])
        return
    
    #------------²é¿´ÊÇ·ñÓÐͬÃûµÄ¼Ò×å
    findFamily = GameWorld.GetFamilyManager().FindFamilyByName(fullFamilyName)
    
    if findFamily != None :
        
        if findFamily.GetID() == curPlayer.GetFamilyID():
            #ÔÊÐíÐ޸ijÉ×Ô¼º¼Ò×åÔÀ´µÄÃû×Ö
            return True
        
        else:
            #XW_JZ_EstablishErr_Name    ¶Ô²»Æð£¬ÄúÊäÈëµÄ¼Ò×åÃûÒÑ´æÔÚ£¬½¨Á¢¼Ò×åʧ°Ü£¡ 25  -   -
            PlayerControl.NotifyCode(curPlayer, "XW_JZ_EstablishErr_Name")
            return
    
    return True
#---------------------------------------------------------------------
## ÊäÈë¼Ò×åÃû³Æ£¨´´½¨¼Ò×壩
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.      
def InputFamilyName(index, tick):
    #GameWorld.GetPsycoFunc(__Func_InputFamilyName)(index, tick)
    return
#---------------------------------------------------------------------
## ÊäÈë¼Ò×åÃû³Æ£¨´´½¨¼Ò×壩
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def __Func_InputFamilyName(index, tick):
    return
#// A4 04 ´´½¨¼Ò×å #tagCGPyCreatFamily
#
#struct    tagCGPyCreatFamily
#{
#    tagHead        Head;
#    char        Name[33];
#    WORD        FakeID;
#};
## ²é¿´ÉêÇë°ï»áµÄ³ÉÔ±ÐÅÏ¢
#  @param index Íæ¼ÒË÷Òý
#  @param clientData ·â°üÊý¾Ý½á¹¹Ìå
#  @param tick ʱ¼ä´Á
#  @return None
def PyCreatFamily(index, clientPack, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    inputName = clientPack.Name
    fakeIndex = clientPack.FakeID
    #Ö´Ðд´½¨¼Ò×åÂß¼
    DoCreateFamily(curPlayer, inputName, fakeIndex, tick)
    #ÖØÖò鿴¼Ò×å״̬(½ö´´½¨¼Ò×åʱºòÖØÖÃ, ÆäÓà״̬ÓÉMapServerÍ˳öʼþÊ±ÖØÖÃ)
    __ClearViewFamilyState(curPlayer)
    #Íæ¼ÒÀ뿪ʼþ
    curPlayer.MapServer_LeaveEvent()
    return
#---------------------------------------------------------------------
##ÖØÖüÒ×å²é¿´×´Ì¬.
# @param curPlayer ʵÀý
# @return ·µ»ØÖµÎÞÒâÒå
# @remarks ÖØÖüÒ×å²é¿´×´Ì¬.
def __ClearViewFamilyState(curPlayer):
    curPlayer.SetViewFamilyState(ShareDefine.TViewFamilyType_None)
    return
#---------------------------------------------------------------------
#class   IPY_CCheckFamilyNameExist
#{
#public:
#
#    char *      GetName();
#};
## ¼ì²é¼Ò×åÊÇ·ñ´æÔÚ
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def CheckFamilyNameExist(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    
#    if curPlayer.GetViewFamilyState() != ShareDefine.TViewFamilyType_CreateFamily:
#        GameWorld.ErrLog("CheckFamilyNameExist : viewState = %s"%(curPlayer.GetViewFamilyState()), curPlayer.GetPlayerID())
#        return
    
    pack = IPY_GameServer.IPY_CCheckFamilyNameExist()
    familyName = GameWorld.GetGameWorld().GetCharTrim(pack.GetName())
    
    curFamily = GameWorld.GetFamilyManager().FindFamilyByName(familyName)
    
    if curFamily != None:
        #XW_JZ_Query_Being  ÄúÊäÈëµÄ¼Ò×åÃûÒÑ´æÔÚ,²»¿ÉÒÔʹÓã¡  25  -   -
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_Query_Being")
        return
    
    #XW_JZ_Query_NoBeing    ÄúÊäÈëµÄ¼Ò×åÃû²»´æÔÚ,¿ÉÒÔʹÓã¡   25  -   -
    PlayerControl.NotifyCode(curPlayer, "XW_JZ_Query_NoBeing")   
    return
#---------------------------------------------------------------------
##֪ͨ¿Í»§¶Ë·þÎñÆ÷¼Ò×åÐÅÏ¢.
# @param curPlayer Íæ¼ÒʵÀý
# @param viewPage ²é¿´Ò³
# @param pageCnt ÿҳÊýÁ¿
# @param sortRule ÅÅÐò¹æÔò(°´ÈÙÓþ, ¼Ò×åµÈ¼¶µÈ)
# @return ·µ»ØÖµÎÞÒâÒå
# @remarks ֪ͨ¿Í»§¶Ë·þÎñÆ÷¼Ò×åÐÅÏ¢
def Sync_AllFamilyInfo(curPlayer, viewPage, pageCnt=ChConfig.Def_ViewAllFamilyPageCount, sortRule=IPY_GameServer.fsrHornor):
    #familyCount = GameWorld.GetFamilyManager().GetCount()
    familyCount = len(PyGameData.g_sortFamilyIDList)
    allPageCnt = GameWorld.GetIntUpper(familyCount, pageCnt)
    if allPageCnt != 0 and (viewPage < 0 or viewPage >= allPageCnt):
        GameWorld.Log("¿Í»§¶Ë²é¿´¼Ò×åÒ³·â°ü´íÎó,ÎÞ´ËÒ³ viewPage = %s, allPageCnt = %s" % (viewPage, allPageCnt), curPlayer.GetPlayerID())
        return
    
    startIndex, endIndex = GameWorld.GetViewPageBeginIndexAndEndIndex(viewPage, pageCnt, familyCount)
    
    # ÅÅÐò¹æÔò±ä¸ü£¬Ê¹ÓÃpy×Ô¶¨Òå°ü֪ͨ
    Sync_PyAllFamilyInfo(curPlayer, allPageCnt, viewPage, startIndex, endIndex)
    
    #===============================================================================================
    # #ÉèÖüÒ×åÐÅÏ¢ÅÅÐò¹æÔò
    # GameWorld.GetFamilyManager().SortBySortRule(sortRule)
    # 
    # #֪ͨ¼Ò×åÐÅÏ¢
    # curPlayer.Sync_AllFamilyInfo(allPageCnt, viewPage, startIndex, endIndex, sortRule)
    #===============================================================================================
    return
def SendFamilyFakePack(familyID, clientPack):
    ## ¹ã²¥¼Ò×å³ÉÔ±PY·â°ü
    family = GameWorld.GetFamilyManager().FindFamily(familyID)
    if not family:
        return
    
    for index in xrange(family.GetCount()):
        member = family.GetAt(index)
        memPlayer = member.GetPlayer()
        if memPlayer:
            NetPackCommon.SendFakePack(memPlayer, clientPack)
    return
def Sync_PyAllFamilyInfo(curPlayer, allPageCnt, viewPage, startIndex, endIndex):
    familyCount = len(PyGameData.g_sortFamilyIDList)
    if startIndex < 0 or endIndex >= familyCount:
        return
    
    familyMgr = GameWorld.GetFamilyManager()
    familyViewPack = ChPyNetSendPack.tagGCPyAllFamilyView()
    familyViewPack.Clear()
    familyViewPack.TotalCount = allPageCnt
    familyViewPack.CurPage = viewPage
    familyViewPack.Family = []
    for i in xrange(startIndex, endIndex + 1):
        familyID = PyGameData.g_sortFamilyIDList[i]
        family = familyMgr.FindFamily(familyID)
        if not family:
            continue
        familyViewPack.Family.append(__GetFamilyView(i, family))
    familyViewPack.PageCount = len(familyViewPack.Family)
    NetPackCommon.SendFakePack(curPlayer, familyViewPack)
    return
def __GetFamilyView(index, family):
    familyView = ChPyNetSendPack.tagGCPyFamilyView()
    familyView.Clear()
    familyView.FamilyIndex = index
    familyView.FamilyID = family.GetID()
    familyView.FamilyName = family.GetName()
    familyView.FamilyNameLen = len(familyView.FamilyName)
    familyView.LeaderID = family.GetLeaderID()
    familyView.LeaderName = family.GetLeaderName()
    familyView.LeaderNameLen = len(familyView.LeaderName)
    familyView.LeaderOfficialRank = family.GetLeaderOfficialRank()
    familyView.FamilyLV = family.GetLV()
    familyView.FamilyMemberCount = family.GetCount()
    familyView.JoinAccept = family.GetAcceptJoin()
    familyView.WarRank = GetFamilyWarRank(family)
    totalFightPower = GetFamilyTotalFightPower(family)
    familyView.TotalFightPower = totalFightPower % ChConfig.Def_PerPointValue
    familyView.TotalFightPowerEx = totalFightPower / ChConfig.Def_PerPointValue
    return familyView
## Íæ¼ÒÄ£ºý²éѯ¼Ò×壬0F 0D·â°ü
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä 
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def SearchFamily(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    pack = IPY_GameServer.IPY_CSearchFamily()
    msg = pack.GetMsg()
    
    if not msg:
        #ûÓвéѯÄÚÈÝ, ·µ»ØµÚÒ»Ò³
        Sync_AllFamilyInfo(curPlayer, 0)
        return
    
    Sync_SearchFamily(curPlayer, msg)
    #curPlayer.Sync_SearchFamily(msg)
    return
def Sync_SearchFamily(curPlayer, msg):
    familyMgr = GameWorld.GetFamilyManager()
    familyViewPack = ChPyNetSendPack.tagGCPyAllFamilyView()
    familyViewPack.Clear()
    familyViewPack.IsSearching = 1
    familyViewPack.TotalCount = 1
    #familyViewPack.CurPage = viewPage
    familyViewPack.Family = []
    for i, familyID in enumerate(PyGameData.g_sortFamilyIDList):
        family = familyMgr.FindFamily(familyID)
        if not family:
            continue
        if msg not in family.GetName():
            continue
        familyViewPack.Family.append(__GetFamilyView(i, family))
    familyViewPack.PageCount = len(familyViewPack.Family)
    NetPackCommon.SendFakePack(curPlayer, familyViewPack)
    return
#// A4 12 ËÑË÷¼Ò×å #tagCGPySearchFamily
#
#struct    tagCGPySearchFamily
#{
#    tagHead        Head;
#    BYTE        MsgLen;        //Ä£ºýËÑË÷¼Ò×壬Èç¹ûÊäÈëΪ¿Õ£¬ÔòΪ²»ÏÞÖÆ¸ÃÌõ¼þ
#    char        Msg[MsgLen];    //size = MsgLen
#    BYTE        LV;        //×îµÍ¼Ò×åµÈ¼¶,Èç¹ûΪ0£¬Ôò²»ÏÞÖÆ¸ÃÌõ¼þ
#    BYTE        MaxCount;    //ËÑË÷½á¹ûËùÐè×î´óÌõÊý£¬ºó¶ËÏÞÖÆ×î¶à·µ»Ø20Ìõ
#    BYTE        IsSearching;    //ĬÈÏ1£¬Èç¹ûÓÐÖ¸¶¨ÆäËûÖµ£¬Ôò·µ»ØÖ¸¶¨Öµ
#};
def PySearchFamily(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    
    msg = clientData.Msg
    minFamilyLV = clientData.LV
    maxCount = min(20, clientData.MaxCount)
    IsSearching = clientData.IsSearching
    
    familyMgr = GameWorld.GetFamilyManager()
    familyViewPack = ChPyNetSendPack.tagGCPyAllFamilyView()
    familyViewPack.Clear()
    familyViewPack.IsSearching = IsSearching
    familyViewPack.TotalCount = 1
    #familyViewPack.CurPage = viewPage
    familyViewPack.Family = []
    for i, familyID in enumerate(PyGameData.g_sortFamilyIDList):
        family = familyMgr.FindFamily(familyID)
        if not family:
            continue
        if msg not in family.GetName():
            continue
        if minFamilyLV and family.GetLV() < minFamilyLV:
            continue
        familyViewPack.Family.append(__GetFamilyView(i, family))
        if len(familyViewPack.Family) >= maxCount:
            break
    familyViewPack.PageCount = len(familyViewPack.Family)
    NetPackCommon.SendFakePack(curPlayer, familyViewPack)
    return
#class   IPY_CFamilyChangeBroadcast
#{
#public:
#
#    char *      GetMsg();
#};
## ¸üй«¸æ
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def UpdateBroadcast(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    curPlayerID = curPlayer.GetPlayerID()
    curFamily = curPlayer.GetFamily()
    if curFamily == None:
        GameWorld.Log("¸üй«¸æ -> ¿Í»§¶Ë·â°üÒì³£ ->Íæ¼ÒÎÞ¼Ò×å" , curPlayerID)
        return
    
    curMember = curFamily.FindMember(curPlayerID)
    if curMember == None:
        GameWorld.Log("¸üй«¸æ -> ¿Í»§¶Ë·â°üÒì³£ ->ÕÒµ½³ÉÔ±´íÎó" , curPlayerID)
        return
    
    if not GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanBroadcast):
        GameWorld.Log("¸üй«¸æ -> ¿Í»§¶Ë·â°üÒì³£ ->ÄãûÓÐȨÏÞ" , curPlayerID)
        return
    
    #ÅжϴÎÊý
    curBroadcastCnt = GetFamilyBroadcastCnt(curFamily)
    maxBroadcastCnt = IpyGameDataPY.GetFuncCfg('FamilyBroadcast')
    if curBroadcastCnt >= maxBroadcastCnt:
        #Ãâ·Ñ´ÎÊýÓÃÍê ÏûºÄÇ®
        croadcastCostGold = IpyGameDataPY.GetFuncCfg('FamilyBroadcast', 2)
        result = str(croadcastCostGold)
        curPlayer.MapServer_QueryPlayerResult(0, 0, "FamilyBroadcastCost", result, len(result))
        
    #¸üдÎÊý
    SetFamilyBroadcastCnt(curFamily, curBroadcastCnt + 1)
    
    pack = IPY_GameServer.IPY_CFamilyChangeBroadcast()
    #¸ü¸Ä¼Ò×幫¸æ
    curFamily.SetBroadcast(pack.GetMsg())
    GameWorld.Log('¸ü¸ÄÏÉÃ˹«¸æ Family=%s,¹«¸æ=%s'%(GameWorld.CodeToGBK(curFamily.GetName()), GameWorld.CodeToGBK(pack.GetMsg())), curPlayerID)
    #֪ͨ¿Í»§¶Ë¼Ò×åÐÅÏ¢¸Ä±ä
    curFamily.Broadcast_FamilyChange()
    playerManager = GameWorld.GetPlayerManager()
    for i in range(0, curFamily.GetCount()):
        notifyMember = curFamily.GetAt(i)
        notifyPlayer = playerManager.FindPlayerByID(notifyMember.GetPlayerID())
        
        if notifyPlayer == None:
            continue
        if notifyPlayer.GetPlayerID() == curPlayer.GetPlayerID():
            #²»°üÀ¨×Ô¼º
            continue
        curPlayer.ChatMi(notifyPlayer, 1, pack.GetMsg(), 0, PlayerTalk.GetTalkExtraValue(curPlayer))
        PyDataManager.GetContactsManager().AddContactsBoth(curPlayer.GetID(), notifyPlayer.GetID())
    return
## ¼ì²âÄ¿±êÍæ¼ÒÊÇ·ñ¿ÉÒÔ¼ÓÈë¼Ò×å
#  @param curPlayer ²Ù×÷ÈËÔ±
#  @param tagPlayer ±»¼ÓÈëÈËÔ±
#  @return ²¼¶ûÖµ
#  @remarks ¼ì²âÄ¿±êÍæ¼ÒÊÇ·ñ¿ÉÒÔ¼ÓÈë¼Ò×å
def __CheckCanAddFamilyMember(curPlayer, curFamily, tagPlayer):
    curPlayerID = curPlayer.GetPlayerID()
    #---¼ì²é¼Ò×åÊôÐÔ---
    #¼Ò×åÊÇ·ñÂúÈË
    maxMemberCnt = GetFamilySetting(curFamily, ChConfig.Def_FamilySetting_MaxMemberCnt) 
    
    if curFamily.GetCount() >= maxMemberCnt:
        #jiazu_lhs_202580 ¶Ô²»Æð,°ï»áÈËÊýÒÑ´ïÉÏÏÞ,ÎÞ·¨ÕÐÊÕгÉÔ±!
        PlayerControl.NotifyCode(curPlayer, "jiazu_lhs_202580")
        return False
    
    #---¼ì²éÍæ¼Ò¼Ò×åȨÏÞ---
    curMember = curFamily.FindMember(curPlayerID)
    
    if curMember == None:
        GameWorld.ErrLog("Ìí¼Ó¼Ò×å³ÉÔ± - >ÕÒµ½³ÉÔ±´íÎó", curPlayerID)
        return False
    
    if not GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanCall):
        #XW_JZ_InviteErr_Popedom    ¶Ô²»Æð£¬ÄúûÓÐÑûÇë¼Ò×åµÄȨÏÞ£¬ÑûÇë¼Ò×åʧ°Ü£¡ 25  -   -
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_InviteErr_Popedom")            
        return False
    
    #Ä¿±êÒѾÊDZ¾¼Ò×å³ÉÔ±ÁË
    tagMember = curFamily.FindMember(tagPlayer.GetID())
    
    if tagMember != None:
        #XW_JZ_InviteErr_Repeat ¶Ô²»Æð£¬Ä¿±êÍæ¼ÒÒÑÓмÒ×壬ÑûÇë¼Ò×åʧ°Ü£¡   25  -   -
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_InviteErr_Repeat")
        return False
    
    #---¼ì²éÄ¿±êÍæ¼ÒÊôÐÔ---
    if tagPlayer.GetFamily() != None:
        #XW_JZ_InviteErr_Repeat ¶Ô²»Æð£¬Ä¿±êÍæ¼ÒÒÑÓмÒ×壬ÑûÇë¼Ò×åʧ°Ü£¡   25  -   -
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_InviteErr_Repeat")
        return False
    
#    if GameWorld.GetPlayerManager().GetForbiddenEnterFamily(tagPlayer.GetPlayerID()):
#        #Invite_Family_Fail ¶Ô²»Æð,Ä¿±êÍæ¼ÒÀ뿪¼Ò×å²»×ã1Ìì,²Ù×÷ÎÞЧ!
#        PlayerControl.NotifyCode(curPlayer, "Invite_Family_Fail")
#        return False
    
    if tagPlayer.GetLV() < ChConfig.Def_Family_JionMinLV:
        #XW_JZ_InviteErr_Lv Ä¿±êµÈ¼¶µÍÓÚ"S1"£¬ÑûÇë¼Ò×åʧ°Ü£¡ 25  -   -
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_InviteErr_Lv", [ChConfig.Def_Family_JionMinLV])
        return False
    
    if not GameWorld.IsSameCountry(curPlayer, tagPlayer):
        #XW_JZ_InviteErr_Antagonize Ä¿±êΪµÐ¶Ô¹úÍæ¼Ò£¬ÑûÇë¼Ò×åʧ°Ü£¡   25  -   -
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_InviteErr_Antagonize")
        return False
    return True
#---------------------------------------------------------------------
#===============================================================================
# #//0F 05 ¼Ò×åÊÕÈË#tagCAddFamilyPlayer
# #class   IPY_CAddFamilyPlayer
# #{
# #public:
# #    //Íæ¼ÒÃû³Æ
# #    char *      GetTagName();
# #    //Íæ¼ÒID
# #    int      GetTagID();
# #};
#===============================================================================
## ÑûÇëÍæ¼Ò¼ÓÈë¼Ò×å
#  @param index Íæ¼ÒË÷Òý
#  @param tick ʱ¼ä´Á
#  @return None
#  @remarks ÑûÇëÍæ¼Ò¼ÓÈë¼Ò×å //0F 05 ¼Ò×åÊÕÈË#tagCAddFamilyPlayer
def AddFamilyPlayer(index, tick):
    GameWorld.GetPsycoFunc(__Func_AddFamilyPlayer)(index, tick)
    return
## ÑûÇëÍæ¼Ò¼ÓÈë¼Ò×å
#  @param index Íæ¼ÒË÷Òý
#  @param tick ʱ¼ä´Á
#  @return None
#  @remarks ÑûÇëÍæ¼Ò¼ÓÈë¼Ò×å //0F 05 ¼Ò×åÊÕÈË#tagCAddFamilyPlayer
def __Func_AddFamilyPlayer(index, tick):
    playerManager = GameWorld.GetPlayerManager()
    curPlayer = playerManager.GetPlayerByIndex(index)
    curPlayerID = curPlayer.GetID()
    #---ÑéÖ¤Íæ¼ÒÊôÐÔ---
    curFamily = curPlayer.GetFamily()
    
    if curFamily == None:
        GameWorld.ErrLog('AddFamilyPlayer, Íæ¼ÒÎÞ¼Ò×å', curPlayerID)
        return
    
    #---»ñÈ¡·â°ü²ÎÊý---
    pack = IPY_GameServer.IPY_CAddFamilyPlayer()
    pack_FindPlayerID = pack.GetTagID()
    pack_FindPlayerName = pack.GetTagName()
    
    #---²éÕÒÑûÇë¼ÓÈë¼Ò×åµÄÍæ¼Ò---
    findPlayer = None
    
    if pack_FindPlayerID != 0:
        findPlayer = playerManager.FindPlayerByID(pack_FindPlayerID)
    else:
        findPlayer = playerManager.FindPlayerByName(pack_FindPlayerName)
    
    #---ÑéÖ¤ÑûÇë¼ÓÈë¼Ò×åµÄÍæ¼Ò---
    if findPlayer == None:
        #jiazu_hwj35_367906 ¶Ô²»Æð,ÄúÊäÈëµÄÍæ¼Ò²»ÔÚÏß,ÑûÇëʧ°Ü
        PlayerControl.NotifyCode(curPlayer, "jiazu_hwj35_367906")
        return
    
    #¼ì²é¼Ò×åÊÇ·ñ¿ÉÒÔ¼ÓÈë¸Ä³ÉÔ±
    if not __CheckCanAddFamilyMember(curPlayer, curFamily, findPlayer):
        return
    
    #---·¢ËÍÑûÇëÇëÇóÖÁÑûÇëµÄÍæ¼Ò---
    curPlayer.AddRequest(findPlayer.GetID(), IPY_GameServer.reqFamily, tick, ChConfig.Def_EventClearTime)
    findPlayer.Frm_FamilyAskIfJoin(curPlayerID, curPlayer.GetName(), curFamily.GetID(), curFamily.GetName())
    
    #--֪ͨϵͳÌáʾ
    #XW_JZ_InviteEnter  Äã¶Ô{%S1%}ÑûÇë¼ÓÈë¼Ò×åµÄÇëÇóÒѾ·¢³ö,ÇëµÈ´ý¶Ô·½Ó¦´ð£¡   25  -   -
    PlayerControl.NotifyCode(curPlayer, "XW_JZ_InviteEnter", [findPlayer.GetName()])
#===============================================================================
#    #ÕâÀïÖ»·¢ÇëÇó, δ¸Ä±ä, ÎÞÐèË¢ÐÂ
#    #֪ͨ¿Í»§¶Ë¼Ò×åÐÅÏ¢¸Ä±ä
#    curFamily.Broadcast_FamilyChange()    
#===============================================================================
    return
#//////////////////////////////////////////////////////////////
#//0F 08 ÇëÇó¼ÓÈë¼Ò×åµÄ»ØÓ¦#tagAskJoinFamilyReply
#tagAskJoinFamilyReply       *   GettagAskJoinFamilyReply();
#
#class   IPY_AskJoinFamilyReply
#{
#public:
#
#    int      GetTagPlayerID();
#    //ÊÇ·ñͬÒâ¼ÓÈë
#    int      GetIsOK();
#};
## ÑûÇëÍæ¼Ò¼ÓÈë¼Ò×åµÄ»ØÓ¦
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks ÑûÇëÍæ¼Ò¼ÓÈë¼Ò×åµÄ»ØÓ¦
def AskJoinFamilyReply(index, tick):
    GameWorld.GetPsycoFunc(__Func_AskJoinFamilyReply)(index, tick)
    return
## ÑûÇëÍæ¼Ò¼ÓÈë¼Ò×åµÄ»ØÓ¦
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks ÑûÇëÍæ¼Ò¼ÓÈë¼Ò×åµÄ»ØÓ¦
def __Func_AskJoinFamilyReply(index, tick):
    playerManager = GameWorld.GetPlayerManager()
    noFamilyPlayer = playerManager.GetPlayerByIndex(index)
    #»ñÈ¡·â°ü
    pack = IPY_GameServer.IPY_AskJoinFamilyReply()
    srcPlayer = playerManager.FindPlayerByID(pack.GetTagPlayerID())
    
    #ÑûÇëÄ¿±ê¼ÓÈë¼Ò×åµÄÍæ¼ÒÒѾ²»ÔÚÏß
    if srcPlayer == None:
        #jiazu_hwj35_329496 ¶Ô²»Æð,ÑûÇëÄú½øÈë°ï»áµÄÍæ¼ÒÒÑÏÂÏß,²Ù×÷ÎÞЧ
        PlayerControl.NotifyCode(noFamilyPlayer, "jiazu_hwj35_329496")
        return
    
    #ÇëÇóÒѾʧЧ
    if not PlayerRequest.CheckRequest(srcPlayer, noFamilyPlayer, IPY_GameServer.reqFamily):
        return
    
    if not pack.GetIsOK():
        #XW_JZ_InviteErr_Refuse Ä¿±ê¾Ü¾øÁËÄú·¢³öµÄÑûÇëÇëÇó£¬ÑûÇë¼Ò×åʧ°Ü£¡  25  -   -
        PlayerControl.NotifyCode(srcPlayer, "XW_JZ_InviteErr_Refuse")
        return
    
    srcFamily = srcPlayer.GetFamily()
    
    if not srcFamily:
        GameWorld.ErrLog('AskJoinFamilyReply, Íæ¼ÒÎÞ¼Ò×å', srcPlayer.GetID())
        return
    
    #¼Ò×å¼ì²éδͨ¹ý
    if not __CheckCanAddFamilyMember(srcPlayer, srcFamily, noFamilyPlayer):
        return
    #---Ä¿±ê¼ÓÈë¼Ò×å---
    DoPlayerJionFamily(srcFamily, noFamilyPlayer, IPY_GameServer.fmlMember)
    
    noFamilyPlayerName = noFamilyPlayer.GetName()
    
    #֪ͨËùÓмÒ×å³ÉÔ±, Õâ¸öÈ˼ÓÈëÁ˼Ò×å
    NotifyAllFamilyMemberMsg(srcFamily, noFamilyPlayer, "XW_JZ_EnterFamily", [noFamilyPlayerName])
    PlayerControl.NotifyCode(noFamilyPlayer, 'XW_JZ_EnterFamilyInfo', [srcFamily.GetName()])
    #֪ͨ¿Í»§¶Ë¼Ò×åÐÅÏ¢¸Ä±ä
    srcFamily.Broadcast_FamilyChange()
    return
#===============================================================================
# //A4 03 ¼ÓÈë¼Ò×åÉóºËÇé¿ö #tagCGJoinFamilyReply
# 
# struct tagCGJoinFamilyReply
# {
#    tagHead    Head;
#    DWORD    TagPlayerID;    //±»ÉóºËÍæ¼ÒID
#    BYTE    IsOK;        //ÊÇ·ñͬÒâ¼ÓÈë
# 
# };
#===============================================================================
## ¼ÓÈë¼Ò×åÉóºËÇé¿ö
#  @param index Íæ¼ÒË÷Òý
#  @param clientData: ·â°ü½á¹¹Ìå
#  @param tick µ±Ç°Ê±¼ä
#  @return None
def AddFamilyReply(index, clientData, tick):
    
    playerManager = GameWorld.GetPlayerManager()
    curPlayer = playerManager.GetPlayerByIndex(index)
    
    if not GameWorld.RefurbishPlayerTick(curPlayer, ChConfig.TYPE_Player_Tick_AddFamilyReply, tick):
        #¼ä¸ôδµ½
        return
    
    familyId = curPlayer.GetFamilyID()
    if familyId <= 0:
        #ÉóºËÈËûÓмÒ×å
        return
    
    tagPlayerID = clientData.TagPlayerID
    
    tagPlayerIDList = []  # ÊÇ·ñÔÚÉêÇëÁбíÖÐ
    allFamilyActionManager = GameWorld.GetFamilyActionManager()  
    familyAction = allFamilyActionManager.GetFamilyAction(familyId, ShareDefine.Def_ActionType_FamilyAdd)
    for index in range(0, familyAction.Count()):
        familyActionData = familyAction.At(index)
        playerID = familyActionData.GetValue1()  # ID
        if tagPlayerID == 0:
            tagPlayerIDList.append(playerID)
        if tagPlayerID == playerID:
            tagPlayerIDList.append(playerID)
            break
    
    if not tagPlayerIDList:
        return
    
    family = curPlayer.GetFamily()
    isNeedSync = False
    for playerID in tagPlayerIDList:
        tagPlayer = playerManager.FindPlayerByID(playerID)
        #¾Ü¾ø
        if not clientData.IsOK:
            
            if tagPlayer:
                #jiazu_pan_592934:{%S}¾Ü¾øÁËÄúµÄÈë°ïÉêÇë
                PlayerControl.NotifyCode(tagPlayer, "jiazu_pan_592934", [family.GetName()])
                
                #·¢Ë;ܾø¼ÓÈë°ï»áµ½µØÍ¼·þÎñÆ÷
                sendMsg = "[%s, %s]" % (familyId, 0)
                tagPlayer.MapServer_QueryPlayerResult(0, 0, 'AddFamilyReply', sendMsg, len(sendMsg))
            else:
                #Çå³ýÉêÇë¼ÓÈë¼Ò×åµÄÐÐΪÊý¾Ý
                PlayerFamilyAction.ClearFamilyAction(familyId, ShareDefine.Def_ActionType_FamilyAdd, playerID=tagPlayerID)
            continue
    
        #ÉêÇëÄ¿±ê²»ÔÚÏß
        if not tagPlayer:
            continue
        
        #¼Ò×å¼ì²éδͨ¹ý
        if not __CheckCanAddFamilyMember(curPlayer, family, tagPlayer):
            continue
    
        #---Ä¿±ê¼ÓÈë¼Ò×å---
        DoPlayerJionFamily(family, tagPlayer, IPY_GameServer.fmlMember)
        isNeedSync = True
        #֪ͨËùÓмÒ×å³ÉÔ±, Õâ¸öÈ˼ÓÈëÁ˼Ò×å
        NotifyAllFamilyMemberMsg(family, tagPlayer, "XW_JZ_EnterFamily", [tagPlayer.GetName()])
        PlayerControl.NotifyCode(tagPlayer, 'XW_JZ_EnterFamilyInfo', [family.GetName()])
        ##·¢Ëͳɹ¦¼ÓÈë°ï»áµ½µØÍ¼·þÎñÆ÷
        sendMsg = "[%s, %s]" % (familyId, 1)
        tagPlayer.MapServer_QueryPlayerResult(0, 0, 'AddFamilyReply', sendMsg, len(sendMsg))
    
    if isNeedSync:
        #֪ͨ¿Í»§¶Ë¼Ò×åÐÅÏ¢¸Ä±ä
        family.Broadcast_FamilyChange()
    return
#===============================================================================
        
## ֪ͨËùÓмÒ×å³ÉÔ±ÐÅÏ¢
#  @param curFamily µ±Ç°¼Ò×å
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param code "XW_JZ_EnterFamily"
#  @param parList [playerName]
#  @param includeSelf ÊÇ·ñͬʱ֪ͨ±¾ÈË
#  @return None
#  @remarks ֪ͨËùÓмÒ×å³ÉÔ±ÐÅÏ¢
def NotifyAllFamilyMemberMsg(curFamily, curPlayer, code, parList=[], includeSelf=True):
    if curPlayer and PlayerControl.GetIsTJG(curPlayer):
        # ÍÑ»ú¹ÒÍæ¼Ò²»Í¨ÖªÆäËûÍæ¼Ò
        return
    
    #֪ͨËùÓмÒ×å³ÉÔ±, Õâ¸öÈ˼ÓÈëÁ˼Ò×å
    playerManager = GameWorld.GetPlayerManager()
    for i in range(0, curFamily.GetCount()):
        notifyMember = curFamily.GetAt(i)
        notifyPlayer = playerManager.FindPlayerByID(notifyMember.GetPlayerID())
        
        if notifyPlayer == None:
            continue
        
        if (not includeSelf and curPlayer and notifyPlayer.GetPlayerID() == curPlayer.GetPlayerID()):
            #²»°üÀ¨×Ô¼º
            continue
        
        if PlayerControl.GetIsTJG(notifyPlayer):
            continue
        
        #ÀýÈç: XW_JZ_EnterFamily  {%S1%}¼ÓÈëÁ˼Ò×壡  25  -   -
        PlayerControl.NotifyCode(notifyPlayer, code, parList)
    
    return
#---------------------------------------------------------------------
## ²éÕÒ¼Ò×åÖÐÓµÓиÃȨÏÞµÄÍæ¼ÒÊý
#  @param curFamily ¼Ò×å
#  @param familyLV Íæ¼ÒµÈ¼¶
#  @return ÊýÁ¿
#  @remarks ²éÕÒ¼Ò×åÖÐÓµÓиÃȨÏÞµÄÍæ¼ÒÊý
def FindFamilyMemberCntByPowLv(curFamily, familyLV):
    memberCnt = 0
    
    for i in range(0, curFamily.GetCount()):
        familyMember = curFamily.GetAt(i)
        if familyMember.GetFamilyLV() != familyLV:
            continue
        
        memberCnt += 1
        
    return memberCnt
#---------------------------------------------------------------------
## »ñÈ¡¼Ò×åµÈ¼¶ÐÅÏ¢
#  @param info infoKey
#  @return keyStr
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def __GetFamilyLVInfo(info):
    if info == IPY_GameServer.fmlMember:
        return 'fmlMember'
    if info == IPY_GameServer.fmlCounsellor:
        return 'fmlCounsellor'
    if info == IPY_GameServer.fmlViceLeader:
        return 'fmlViceLeader'
    if info == IPY_GameServer.fmlLeader:
        return 'fmlLeader'
    
    return ''
#class   IPY_CFamilyChangeMember
#{
#public:
#
#    int      GetPlayerID();
#
#    int      GetFamilyLV();
#};
## ¸ü¸Ä¼Ò×å³ÉԱȨÏÞ
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks ¸ü¸Ä¼Ò×å³ÉԱȨÏÞ
def FamilyChangeMemberLV(index, tick):
    GameWorld.GetPsycoFunc(__Func_FamilyChangeMemberLV)(index, tick)
    return
## ¸ü¸Ä¼Ò×å³ÉԱȨÏÞ
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks ¸ü¸Ä¼Ò×å³ÉԱȨÏÞ
def __Func_FamilyChangeMemberLV(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    curPlayerID = curPlayer.GetPlayerID()
    #---Íæ¼ÒȨÏÞÑéÖ¤---
    curFamily = curPlayer.GetFamily()
    
    if curFamily == None:
        GameWorld.Log("¸ü¸Ä¼Ò×å³ÉÔ±µÈ¼¶->·â°üÒì³£->Íæ¼ÒûÓмÒ×å", curPlayerID)
        return
    
    #---¿ªÊ¼±ä¸üְλ---
    pack = IPY_GameServer.IPY_CFamilyChangeMember()
    pack_tagID = pack.GetPlayerID()
    pack_FamilyLv = pack.GetFamilyLV()
    DoChangeFamilyMemberLV(curFamily, curPlayer, pack_tagID, pack_FamilyLv)
    return
    
def DoChangeFamilyMemberLV(curFamily, curPlayer, tagID, pack_FamilyLv, isGMOP=False):
    curPlayerID = curPlayer.GetPlayerID()
    curMember = curFamily.FindMember(curPlayerID)
    
    if curPlayer == None or curMember == None:
        GameWorld.Log("¸ü¸Ä¼Ò×å³ÉÔ±µÈ¼¶->·â°üÒì³£->Î޴˳ÉÔ±", curPlayerID)
        return
    
    # ·ÇGM²Ù×÷µÄÐè¼ì²éȨÏÞ
    if not isGMOP:
        if not GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanChangeFamilyJob):
            return
        
        if curPlayerID == tagID:
            GameWorld.Log("¸ü¸Ä¼Ò×å³ÉÔ±µÈ¼¶->·â°üÒì³£->²»ÄÜÈÎÃâ×Ô¼º", curPlayerID)
            return
    
    tagMember = curFamily.FindMember(tagID)
    
    if tagMember == None:
        GameWorld.Log("¸ü¸Ä¼Ò×å³ÉÔ±µÈ¼¶->·â°üÒì³£->Ä¿±ê²»´æÔÚ, tagID=%s" % tagID, curPlayerID)
        return    
    
    if pack_FamilyLv not in ChConfig.Def_Family_MemberLVList:
        GameWorld.Log("¸ü¸Ä¼Ò×å³ÉÔ±µÈ¼¶->·â°üÒì³£->µÈ¼¶ = %s²»´æÔÚ" % (pack_FamilyLv), curPlayerID)
        return
    if not isGMOP:
        if curMember.GetFamilyLV() != IPY_GameServer.fmlLeader:
            if tagMember.GetFamilyLV() >= curMember.GetFamilyLV() or pack_FamilyLv >= curMember.GetFamilyLV():
                GameWorld.Log("¸ü¸Ä¼Ò×å³ÉÔ±µÈ¼¶->Ä¿±êְλ±È×Ô¼ºµÄ¸ß»òÕß¶Ô·½µÄµ±Ç°Ö°Î»±È×Ô¼º¸ß", curPlayerID)
                return
    
    familyID = curFamily.GetID()  # ¼Ò×åID
    familyName = curFamily.GetName()  # ¼Ò×åÃû×Ö
    
    #---תÈüÒ×峤---
    if pack_FamilyLv == IPY_GameServer.fmlLeader: 
        createFamily_MinLV = IpyGameDataPY.GetFuncCfg('CreateFamilyMinLV')
        if tagMember.GetLV() < createFamily_MinLV:
            PlayerControl.NotifyCode(curPlayer, "DBB17139-6C93-4E66-9CC1314EAEB6F455", [createFamily_MinLV])
            return
        
        leaderID = curFamily.GetLeaderID()
        leaderMember = curFamily.FindMember(leaderID)
        if not leaderMember:
            return
        
        #°Ñ×峤½µÎªÆÕͨ³ÉÔ±
        ChangeFamilyMemberLv(leaderMember, IPY_GameServer.fmlMember)
        #oss¼Ç¼×峤ְλ±ä¸ü
        DataRecordPack.DR_PlayerChangeFamilyJob(curPlayer, familyID, familyName, leaderMember.GetPlayerID(),
                                                leaderMember.GetName(), leaderMember.GetFamilyLV(), isGMOP)
        
        #ÉèÖÃÄ¿±êÍæ¼ÒÊôÐÔ, °ÑÄ¿±êÌáʾΪ×峤
        SetFamilyLeader(curFamily, tagMember)
        #֪ͨ¼Ò×å³ÉÔ±ÐÅÏ¢
        NotifyAllFamilyMemberMsg(curFamily, curPlayer, "XW_JZ_AppointFamily", [tagMember.GetName(), pack_FamilyLv])
        #֪ͨµØÍ¼·þÎñÆ÷Ë¢ÐÂ
        curPlayer.MapServer_FamilyRefresh()
        
        leaderPlayer = leaderMember.GetPlayer()
        if isGMOP and leaderPlayer:
            leaderPlayer.MapServer_FamilyRefresh()
        
        GameWorld.Log("%s¼Ò×åתÈÃ×峤, ÉèÖÃΪ×峤:%s" % (curFamily.GetID(), tagMember.GetName()), curPlayerID)
    #---ÉèÖÃȨÏÞ---
    else:
        #²é¿´¸ÃȨÏÞÊÇ·ñÒѾ´ïµ½ÉÏÏÞ
        familyLvMemberCnt = FindFamilyMemberCntByPowLv(curFamily, pack_FamilyLv)
        #Ŀǰ¸ÃȨÏÞµÄÈËÊýÒѾ´ïµ½ÉÏÏÞ
        if familyLvMemberCnt >= GetFamilySetting(curFamily, ChConfig.Def_FamilyPowLvChangeFamilySettingDict[pack_FamilyLv]):
            # jiazu_hwj35_272921 ¸ÄΪ jiazu_chenxin_31379
            PlayerControl.NotifyCode(curPlayer, "jiazu_chenxin_31379")
            return
        
        #ÈÎÃü֪ͨ
        if tagMember.GetFamilyLV() != pack_FamilyLv: 
            #XW_JZ_AppointFamily ¹§Ï²{%S1%}£¬±»ÈÎÃüΪ{%S2%}£¡    25  -   -
            NotifyAllFamilyMemberMsg(curFamily, curPlayer, "XW_JZ_AppointFamily", [tagMember.GetName(), pack_FamilyLv])
        if tagMember.GetFamilyLV() == IPY_GameServer.fmlViceLeader and tagMember.GetPlayerID() in PyGameData.g_autoViceleaderDict.get(familyID, []):
            #×Ô¶¯°²Åŵĸ±ÃËÖ÷±»³·Ö°Ôò¸ÃÃ˲»ÔÙ×Ô¶¯°²ÅÅ
            if familyID not in PyGameData.g_forbidAutoViceleaderFamily:
                PyGameData.g_forbidAutoViceleaderFamily.append(familyID)
        #¸ü¸Ä¼Ò×åµÈ¼¶
        ChangeFamilyMemberLv(tagMember, pack_FamilyLv)
    
    #¼Ç¼¶Ô·½³ÉÔ±±ä¸üÐÅÏ¢
    DataRecordPack.DR_PlayerChangeFamilyJob(curPlayer, curFamily.GetID(), curFamily.GetName(), tagMember.GetPlayerID(),
                                            tagMember.GetName(), tagMember.GetFamilyLV(), isGMOP)
    
    #֪ͨµØÍ¼·þÎñÆ÷¼Ò×å±ä¸üÏûÏ¢
    tagPlayer = tagMember.GetPlayer()
    
    if tagPlayer != None:
        #֪ͨµØÍ¼·þÎñÆ÷¼Ò×åµÈ¼¶¸Ä±ä
        tagPlayer.MapServer_FamilyRefresh()
        #Èç¹û²»¸æËß, ¿Í»§¶ËµÃ²»µ½¼Ò×åË¢ÐÂ, µ¼Ö²»´ò¿ª¼Ò×å½çÃæµÄʱºò, ²»ÄÜÖ±½Óµã»÷Í·ÏñÕÐÈË
        if GetFamilyMemberHasPow(tagMember, ChConfig.Def_PurviewDictKey_CanCall):
            tagPlayer.Sync_FamilyInfo()
            PlayerFamilyAction.ViewFamilyRequestInfo(tagPlayer)
    if isGMOP:
        curFamily.SetBroadcast('')
    curFamily.Broadcast_FamilyChange()
    return True
#---------------------------------------------------------------------
#class   IPY_CGetFamilyInfo
#{
#public:
#
#    int      GetType();
#};
## ÒªÇóµÃµ½¼Ò×å³ÉÔ±ÐÅÏ¢
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def GetFamilyMember(index, tick):
    GameWorld.GetPsycoFunc(__Func_GetFamilyMember)(index, tick)
    return
## ÒªÇóµÃµ½¼Ò×å³ÉÔ±ÐÅÏ¢
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def __Func_GetFamilyMember(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    
    curPlayerFamily = curPlayer.GetFamily()
    
    if not curPlayerFamily:
        GameWorld.Log('###²é¿´¼Ò×å½çÃæ·â°üÒì³££¬Íæ¼ÒÎÞ¼Ò×å' , curPlayer.GetPlayerID())
        return
    
    if tick - curPlayer.GetPlayerGetFamilyInfoTick() < ChConfig.Def_PlayerGetFamilyInfoTick:
        GameWorld.Log("ÒªÇóµÃµ½¼Ò×å³ÉÔ±ÐÅÏ¢ -> ¿Í»§¶Ë -> µÃµ½ÐÅÏ¢Ëٶȹý¿ì" , curPlayer.GetPlayerID())
        return
        
    #Ë͸øÍæ¼Ò¼Ò×åÐÅÏ¢
    curPlayer.SetPlayerGetFamilyInfoTick(tick)
    curPlayer.Sync_FamilyInfo()
    
    #----------Åж¨ÊÇ·ñ¿ÉÒÔ¼Ò×å¸ÄÃû
    if __CheckCanRenameFamilyName(curPlayer):
        curPlayer.Frm_RenameFamilyAsk(curPlayerFamily.GetName())
    
    return
#----------------------------------------------------------------------
#class   IPY_GSetPlayerViewFamilyState
#{
#public:
#    //0: ÎÞ״̬ 1:²é¿´ÖÐ
#    int      GetState();
#};
## µØÍ¼·þÎñÆ÷Ë¢ÐÂÍæ¼Ò²é¿´¼Ò×åµÄ״̬
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def MapServer_PlayerViewFamilyState(index, tick):
    #µØÍ¼·þÎñÆ÷Ë¢ÐÂÍæ¼Ò²é¿´¼Ò×åµÄ״̬
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    pack = IPY_GameServer.IPY_GSetPlayerViewFamilyState()
    curPlayer.SetViewFamilyState(pack.GetState())
    return
#//////////////////////////////////////////////////////////////
#//0F 09 ɾ³ý¼Ò×å³ÉÔ±#tagCDeleteFamilyMember
#tagCDeleteFamilyMember       *   GettagCDeleteFamilyMember();
#
#class   IPY_CDeleteFamilyMember
#{
#public:
#
#    int      GetMemberID();
#};
## ɾ³ý¼Ò×å³ÉÔ±
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def DeleteFamilyMember(index, tick):
    GameWorld.GetPsycoFunc(__Func_DeleteFamilyMember)(index, tick)
    return
## ɾ³ý¼Ò×å³ÉÔ±
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def __Func_DeleteFamilyMember(index, tick):
    playerManager = GameWorld.GetPlayerManager()
    curPlayer = playerManager.GetPlayerByIndex(index)
    pack = IPY_GameServer.IPY_CDeleteFamilyMember()
    tagMemberID = pack.GetMemberID()
    
    if curPlayer.GetPlayerID() == tagMemberID:
        GameWorld.Log("ɾ³ý¼Ò×å³ÉÔ± ->·â°ü´íÎó ->²»ÄÜÌß³ö×Ô¼º" , curPlayer.GetPlayerID())
        return
    
    #----------------×Ô¼º---------------
    curFamily = curPlayer.GetFamily()
    if curFamily == None:
        GameWorld.Log("ɾ³ý¼Ò×å³ÉÔ± ->·â°ü´íÎó ->Íæ¼ÒûÓмÒ×å" , curPlayer.GetPlayerID())
        return
    
    curMember = curFamily.FindMember(curPlayer.GetPlayerID())
    
    if curMember == None:
        GameWorld.Log("ɾ³ý¼Ò×å³ÉÔ± ->·â°ü´íÎó ->Î޴˳ÉÔ±" , curPlayer.GetPlayerID())
        return
    
    #ȨÏÞ²»×ã
    if not GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanKickMember):
        return
    #----------------¶Ô·½---------------
    curTagMember = curFamily.FindMember(tagMemberID)
    if curTagMember == None:
        GameWorld.Log("ɾ³ý¼Ò×å³ÉÔ± ->·â°ü´íÎó ->Î޴˳ÉÔ±" , curPlayer.GetPlayerID())
        return
    
    if curTagMember.GetFamilyLV() == IPY_GameServer.fmlLeader:
        GameWorld.Log("ɾ³ý¼Ò×å³ÉÔ± ->·â°ü´íÎó ->²»ÄÜÌß³ö×峤" , curPlayer.GetPlayerID())
        return
    
    curFamilyLV = curMember.GetFamilyLV()
    if curFamilyLV != IPY_GameServer.fmlLeader and curTagMember.GetFamilyLV() == IPY_GameServer.fmlViceLeader:
        GameWorld.Log("ɾ³ý¼Ò×å³ÉÔ± ->·â°ü´íÎó ->»¤·¨²»ÄÜÌß³ö»¤·¨", curPlayer.GetPlayerID())
        return
    
    if GameWorldFamilyWar.IsFamilyInWarFighting(curFamily.GetID()):
        PlayerControl.NotifyCode(curPlayer, "FamilyWarFightingDeleteMemLimiit")
        return
    
    if PlayerFamilySWRH.IsInFamilySWRH():
        PlayerControl.NotifyCode(curPlayer, "DungeonGuardSkyText2")
        return
    
    if GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyRobBoss):        
        PlayerControl.NotifyCode(curPlayer, "FairyGrabBossExitError")
        return
    if PlayerFamilyBoss.IsInAllFamilyBoss():
        PlayerControl.NotifyCode(curPlayer, "LeagueBOSSExitError1")
        return
    if AuctionHouse.IsFamilyMemberBiddingAuctionItem(curFamily.GetID(), tagMemberID):
        PlayerControl.NotifyCode(curPlayer, "Paimai7")
        return
    tagPlayerName = curTagMember.GetName()  # ±»ÌßÍæ¼ÒÃû
    tagPlayerID = curTagMember.GetPlayerID()  # ±»ÌßÍæ¼ÒID
    tagFamilyLV = curTagMember.GetFamilyLV()  # ±»ÌßÍæ¼Òְλ
    
    #XW_JZ_LeaveFamily   {%S1%}Í˳öÁ˼Ò×壡  25  -   -
    NotifyAllFamilyMemberMsg(curFamily, curPlayer, "XW_JZ_LeaveFamily", [tagPlayerName])
    #¼Ç¼±»ÌßÐÅÏ¢
    PlayerFamilyAction.AddFamilyActionNote(tagPlayerName, curFamily.GetID(), ShareDefine.Def_ActionType_FamilyEvent,
                                           [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_KickOut], tick)
    #ɾ³ýÍæ¼Ò
    curFamily.DeleteMember(tagPlayerID)
    __DoPlayerLeaveFamilyByID(curFamily, tagPlayerID)
    
    tagPlayer = playerManager.FindPlayerByID(tagMemberID)
    #Íæ¼ÒÔÚÏß, ÉèÖÃÕâ¸öÍæ¼ÒµÄÊôÐÔ
    PlayerForceLeaveFamily(tagPlayer, tick)
    
    #¼Ç¼Á÷Ïò 150
    DataRecordPack.DR_PlayerLeaveFamily(curPlayer, curFamily.GetID(), curFamily.GetName(), curFamily.GetCount(),
                                        curFamilyLV, tagPlayerID, tagPlayerName, tagFamilyLV)
    
    #֪ͨ¿Í»§¶Ë¼Ò×åÐÅÏ¢¸Ä±ä
    curFamily.Broadcast_FamilyChange()
    return
#//////////////////////////////////////////////////////////////
#//0F 0A Í˳ö¼Ò×å#tagCLeaveFamily
#tagCLeaveFamily       *   GettagCLeaveFamily();
#
#class   IPY_CLeaveFamily
#{
#public:
#
#    int      GetType();
#};
## À뿪¼Ò×å
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def LeaveFamily(index, tick):
    GameWorld.GetPsycoFunc(__Func_LeaveFamily)(index, tick)
    return
## À뿪¼Ò×å
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def __Func_LeaveFamily(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #pack = IPY_GameServer.IPY_CLeaveFamily()
    curFamily = curPlayer.GetFamily()
    if curFamily == None:
        GameWorld.Log("À뿪¼Ò×å -> ·â°ü´íÎó -> Íæ¼ÒûÓмÒ×å" , curPlayer.GetPlayerID())
        return
    
    curMember = curFamily.FindMember(curPlayer.GetPlayerID())
    if curMember == None:
        GameWorld.Log("À뿪¼Ò×å -> ·â°ü´íÎó ->Î޴˳ÉÔ±" , curPlayer.GetPlayerID())
        return
    
    familyLV = curMember.GetFamilyLV()  # ְλ
    if curFamily.GetCount() > 1 and familyLV == IPY_GameServer.fmlLeader:
        #XW_JZ_FamilyHeadCannotExit ¶Ô²»Æð£¬¼Ò×å×峤²»ÄÜÖ±½ÓÍ˳ö¼Ò×å£¬ÍÆ³ö¼Ò×åʧ°Ü£¡   25  -   -
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_FamilyHeadCannotExit")   
        return
    
    if GameWorldFamilyWar.IsFamilyInWarFighting(curFamily.GetID()):
        PlayerControl.NotifyCode(curPlayer, "FamilyWarFightingLeaveLimiit")
        return
    if PlayerFamilySWRH.IsInFamilySWRH():
        PlayerControl.NotifyCode(curPlayer, "DungeonGuardSkyText1")
        return
    
    if GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyRobBoss):        
        PlayerControl.NotifyCode(curPlayer, "FairyGrabBossExitError")
        return
    if PlayerFamilyBoss.IsInAllFamilyBoss():
        PlayerControl.NotifyCode(curPlayer, "LeagueBOSSExitError1")
        return
    if AuctionHouse.IsFamilyMemberBiddingAuctionItem(curFamily.GetID(), curMember.GetPlayerID()):
        PlayerControl.NotifyCode(curPlayer, "Paimai8")
        return
    #ÅжÏÍ˳öʱ¼ä¼ä¸ô
    curTime = int(time.time())
    lastLeaveFamilyTime = PlayerControl.GetLeaveFamilyTime(curPlayer)
    if lastLeaveFamilyTime > 100:
        remainTime = IpyGameDataPY.GetFuncCfg('ExitFairyTime', 2) - (curTime - lastLeaveFamilyTime)
        if remainTime > 0:
            PlayerControl.NotifyCode(curPlayer, "ExitFairyTime", [remainTime*1000])
            return
        updTime = 1 if IpyGameDataPY.GetFuncCfg('ExitFairyTime') > 1 else curTime
    elif lastLeaveFamilyTime >= IpyGameDataPY.GetFuncCfg('ExitFairyTime')-1:
        updTime = curTime
    else:
        updTime = lastLeaveFamilyTime+1
    PlayerControl.SetLeaveFamilyTime(curPlayer, updTime)
    
    #XW_JZ_LeaveFamily   {%S1%}Í˳öÁ˼Ò×壡  25  -   -
    NotifyAllFamilyMemberMsg(curFamily, curPlayer, "XW_JZ_LeaveFamily", [curPlayer.GetName()])
    
    # ¼Ç¼Í˳öÐÅÏ¢
    PlayerFamilyAction.AddFamilyActionNote(curPlayer.GetName(), curFamily.GetID(), ShareDefine.Def_ActionType_FamilyEvent,
                                           [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_Leave], tick)
    curPlayerID = curMember.GetPlayerID()
    #ɾ³ýÍæ¼Ò
    curFamily.DeleteMember(curMember.GetPlayerID())
    #Íæ¼ÒÔÚÏß, ÉèÖÃÕâ¸öÍæ¼ÒµÄÊôÐÔ
    PlayerForceLeaveFamily(curPlayer, tick)  
    __DoPlayerLeaveFamilyByID(curFamily, curPlayerID)
    DataRecordPack.DR_PlayerLeaveFamily(curPlayer, curFamily.GetID(), curFamily.GetName(), curFamily.GetCount(),
                                        familyLV, curPlayer.GetPlayerID(), curPlayer.GetName(), familyLV, updTime)
    
    if curFamily.GetCount() == 0:
        #Íæ¼ÒÀ뿪ºó, ¼Ò×åûÓÐÈËÁË , ɾ³ýÕâ¸ö¼Ò×å
        __DelFamily(curPlayer , curFamily)
        return
    
    #֪ͨ¿Í»§¶Ë¼Ò×åÐÅÏ¢¸Ä±ä
    curFamily.Broadcast_FamilyChange()
    return
## Íæ¼ÒÀ뿪¼Ò×å´¦Àí£¬¸ù¾ÝID£¬ÎÞÊÓÍæ¼ÒÊÇ·ñÔÚÏß
#  @param curFamily À뿪µÄ¼Ò×å
#  @param leavePlayerID À뿪µÄÍæ¼ÒID
#  @return None
def __DoPlayerLeaveFamilyByID(curFamily, leavePlayerID):
    PlayerFamilyAction.DelFamilyOfficerModelEquip(curFamily.GetID(), leavePlayerID)
    # Íæ¼ÒÕ½ÃËÃû±ä¸ü´¦Àí
    __OnFamilyNameChange(leavePlayerID, '')
    AddFamilyIDToFightPowerChangeList(curFamily.GetID())
    PlayerViewCache.OnPlayerFamilyChange(leavePlayerID, 0, "")
    if leavePlayerID in PyGameData.g_autoViceleaderDict.get(curFamily.GetID(),[]):
        PyGameData.g_autoViceleaderDict[curFamily.GetID()].remove(leavePlayerID)
    return
#//////////////////////////////////////////////////////////////
#//05 02 ²é¿´ËùÓмÒ×å#tagGViewAllFamily
#tagGViewAllFamily       *   GettagGViewAllFamily();
#
#class   IPY_GViewAllFamily
#{
#public:
#
#    int      GetType();
#};
## ²é¿´ËùÓмÒ×å
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def MapServer_PlayerViewAllFamily(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #¹Ì¶¨·µ»ØµÚÒ»Ò³
    Sync_AllFamilyInfo(curPlayer, 0)
    return
#class   IPY_GAddFamilyDetail
#{
#public:
#    //Ôö¼Ó¼Ò×åÈÙÓþ
#    int      GetAddFamilyHornor();
#    //Ôö¼Ó¼Ò×å×ʽð
#    int      GetAddFamilyMoney();
#    //Ôö¼Ó¼Ò×å»îÔ¾¶È
#    int      GetFamilyActiveValue();
#};
## mapÇëÇóÍæ¼ÒÔö¼Ó¹±Ï׵ļÒ×åÐÅÏ¢
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä 
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def MapServer_PlayerAddFamilyDetail(index, tick):
    GameWorld.GetPsycoFunc(__Func_MapServer_PlayerAddFamilyDetail)(index, tick)
    return
def __Func_MapServer_PlayerAddFamilyDetail(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    pack = IPY_GameServer.IPY_GAddFamilyDetail()
    addFamilyHornor = pack.GetAddFamilyHornor()
    addFamilyMoney = pack.GetAddFamilyMoney()
    addFamilyActiveValue = pack.GetFamilyActiveValue()
    __DoLogic_MapServer_PlayerAddFamilyDetail(curPlayer, addFamilyHornor, addFamilyMoney, addFamilyActiveValue, 0)
    return
#// 03 05 Ôö¼Ó¼Ò×åÊôÐÔ#tagMGAddFamilyDetail
#
#struct    tagMGAddFamilyDetail
#{
#    tagHead        Head;
#    DWORD        PlayerID;        //Íæ¼ÒID
#    DWORD        AddFamilyHornor;        //Ôö¼Ó¼Ò×åÈÙÓþ
#    DWORD        AddFamilyMoney;        //Ôö¼Ó¼Ò×å×ʽð
#    DWORD        FamilyActiveValue;        //¼Ò×å»îÔ¾¶È
#    BYTE        AddResion;        //Ôö¼ÓÔÒò
#};
def OnMGAddFamilyDetail(routeIndex, mapID, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPackData.PlayerID)
    addFamilyHornor = curPackData.AddFamilyHornor
    addFamilyMoney = curPackData.AddFamilyMoney
    addFamilyActiveValue = curPackData.FamilyActiveValue
    addResion = curPackData.AddResion
    __DoLogic_MapServer_PlayerAddFamilyDetail(curPlayer, addFamilyHornor, addFamilyMoney, addFamilyActiveValue, addResion)
    return
def __DoLogic_MapServer_PlayerAddFamilyDetail(curPlayer, addFamilyHornor, addFamilyMoney, addFamilyActiveValue, addResion):
    if not curPlayer:
        #@warning: ÄÚÍø·¢ÏÖÕâÀïΪNone, ÔÒò´ý²é, ÏȼӷÀ·¶
        GameWorld.ErrLog('MapServer_PlayerAddFamilyDetail Player = None')
        return
    curPlayerID = curPlayer.GetPlayerID()
    curFamily = curPlayer.GetFamily()
    
    if curFamily == None:
        GameWorld.Log("AddFamilyDetail ->Íæ¼ÒûÓмÒ×å" , curPlayerID)
        return
    
    curMember = curFamily.FindMember(curPlayerID)
    
    if curMember == None:
        GameWorld.Log("AddFamilyDetail ->Î޴˳ÉÔ±" , curPlayerID)
        return
    
    GameWorld.DebugLog("PlayerAddFamilyDetail addFamilyHornor=%s,addFamilyMoney=%s,addFamilyActiveValue=%s,addResion=%s" 
                       % (addFamilyHornor, addFamilyMoney, addFamilyActiveValue, addResion), curPlayerID)
    weekMissionMoneyMax = GetFamilySetting(curFamily, ChConfig.Def_FamilySetting_WeekMissionMoneyMax)
    if addFamilyMoney != 0 and addResion == ShareDefine.Def_AddFAVReason_DoFamilyMisson and weekMissionMoneyMax:
        curWeekMissionMoney = GetCurWeekMissionMoney(curFamily)
        addFamilyMoney = min(addFamilyMoney, max(weekMissionMoneyMax - curWeekMissionMoney, 0))
        GameWorld.DebugLog("    ±¾ÖÜÈÎÎñÒÑ»ñµÃÏÉÃË×ʽðÊý!curWeekMissionMoney=%s,weekMissionMoneyMax=%s,addFamilyMoney=%s" 
                           % (curWeekMissionMoney, weekMissionMoneyMax, addFamilyMoney), curPlayerID)
        
    #----------ÉèÖÃÖµ
    if addFamilyHornor != 0:
        SetFamilyBossFood(curFamily, min(GetFamilyBossFood(curFamily) + addFamilyHornor, ChConfig.Def_UpperLimit_DWord))
    if addFamilyMoney != 0:
        curFamily.SetMoney(min(curFamily.GetMoney() + addFamilyMoney, ChConfig.Def_UpperLimit_DWord))
        if addResion == ShareDefine.Def_AddFAVReason_DoFamilyMisson and weekMissionMoneyMax:
            SetCurWeekMissionMoney(curFamily, GetCurWeekMissionMoney(curFamily) + addFamilyMoney)
            
    if addFamilyActiveValue != 0:
        curFamily.SetFamilyActiveValue(min(curFamily.GetFamilyActiveValue() + addFamilyActiveValue, ChConfig.Def_UpperLimit_DWord))
        ReFreshPlayerFamilyTotalActiveValue(curPlayer, addFamilyActiveValue)
    
    #¼Ç¼Á÷Ïò151
    if addFamilyMoney != 0:
        DataRecordPack.DR_AddFamilyDetail(curFamily.GetName(), curFamily.GetID(), curFamily.GetLV(), curFamily.GetMoney(),
                                          addFamilyMoney, curFamily.GetFamilyActiveValue(), addFamilyActiveValue)
    
    #֪ͨ¿Í»§¶Ë
    #curFamily.Broadcast_FamilyChange()
    curPlayer.Sync_FamilyInfo()
    
    #½ðÇ®±ä¸üʱ²Å֪ͨ
    if addFamilyMoney != 0:
        #֪ͨµØÍ¼·þÎñÆ÷ˢмÒ×åÊôÐÔ
        SendPack_MapServer_PlayerFamilyRefresh(curFamily)
    #Õ½ÃËÉý¼¶
    #DoFamilyLvUp(curFamily)
    return
    
## ¸üмÒ×å³ÉÔ±Õ½Á¦
def UpdFamilyMemberFightPower(familyID, playerID, fightPower):
    curFamily = GameWorld.GetFamilyManager().FindFamily(familyID)
    if not curFamily:
        return
    
    curMember = curFamily.FindMember(playerID)
    if not curMember:
        return
    
    SetMemberFightPower(curMember, fightPower)
    GameWorld.DebugLog("ÏÉÃ˳ÉÔ±Õ½Á¦±ä¸ü familyID=%s,fightPower=%s" % (familyID, fightPower), playerID)
    AddFamilyIDToFightPowerChangeList(familyID)
    return
## A4 07 Éý¼¶¼Ò×å#tagCGFamilyLVUp
#  @param index: Íæ¼ÒË÷Òý
#  @param clientData: ¿Í»§¶Ë·â°ü½á¹¹Ìå
#  @param tick: ʱ¼ä´Á
#  @return None 
def OnPlayerLVUpFamily(index, clientData, tick):
    GameWorld.GetPsycoFunc(__Func_MapServer_PlayerLVUpFamily)(index, tick)
    return
#class   IPY_GFamilyLVUp
#{
#public:
#    //ĿǰÎÞÒâÒå
#    int      GetType();
#};
## Íæ¼ÒΪ¼Ò×åÉý¼¶
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def MapServer_PlayerLVUpFamily(index, tick):
    GameWorld.GetPsycoFunc(__Func_MapServer_PlayerLVUpFamily)(index, tick)
    return
## Íæ¼ÒΪ¼Ò×åÉý¼¶
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def __Func_MapServer_PlayerLVUpFamily(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    curPlayerID = curPlayer.GetPlayerID()
    curFamily = curPlayer.GetFamily()
    
    if curFamily == None:
        #jiazu_pan_161795 ¶Ô²»Æð,ÄãδӵÓмÒ×å,ÎÞ·¨ÌáÉý¼Ò×åµÈ¼¶!   25  -   -
        PlayerControl.NotifyCode(curPlayer, "jiazu_pan_161795")
        return
    curMember = curFamily.FindMember(curPlayerID)
    if curMember == None:
        GameWorld.ErrLog("FamilyLVUp -> Î޴˳ÉÔ±", curPlayerID)
        return
    
    #Ñé֤ȨÏÞ
    if not GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanFamilyLvUp):
        PlayerControl.NotifyCode(curPlayer, "jiazu_liubo_272921")
        return
#===============================================================================
#    if curMember.GetFamilyLV() != IPY_GameServer.fmlLeader:
#        #XW_JZ_LvUpNoLeader ¶Ô²»Æð,Äú²»ÊǼÒ×å×峤,ÎÞ·¨ÌáÉý¼Ò×åµÈ¼¶!  25  -   -
#        PlayerControl.NotifyCode(curPlayer, "XW_JZ_LvUpNoLeader")
#        return
#===============================================================================
    DoFamilyLvUp(curFamily)
    
    return
## Ö´ÐмÒ×åÉý¼¶
#  @param curFamily
#  @return None
def DoFamilyLvUp(curFamily):
    #ÒѾÊÇ×î¸ßµÈ¼¶
    if curFamily.GetLV() >= ChConfig.Def_Family_MaxLv:
        #PlayerControl.NotifyCode(curPlayer, "jiazu_hwj35_0")
        return
    
    #[Éý¼¶ÐèÒª·±ÈÙ, ËùÐè×ʽð, ËùÐè×êʯ, ËùÐèµÍ¼¶ÁîÅÆÊý, ËùÐè¸ß¼¶ÁîÅÆÊý]
    needMoney = GetFamilySetting(curFamily, ChConfig.Def_FamilySetting_LvUpCost)
 
    if curFamily.GetMoney() < needMoney:
        GameWorld.DebugLog("Õ½ÃË×ʽð²»×ã! needMoney=%s" % (needMoney))
        return
    
    #---¿ªÊ¼Éý¼¶---
    curFamily.SetMoney(curFamily.GetMoney() - needMoney)
    curFamily.SetLV(curFamily.GetLV() + 1)
    
    #Êä³öϵͳÌáʾ
    PlayerControl.FamilyNotify(curFamily.GetID(), 'jiazu_chenxin_272921', [needMoney])
    
    #°ï»áÉý¼¶Á÷Ïò
    DataRecordPack.DR_FamilyLvUp(curFamily.GetName(), curFamily.GetID(), curFamily.GetLV())
    
    #¼Ç¼Éý¼¶ÐÅÏ¢
    tick = GameWorld.GetGameWorld().GetTick()
    leaderID = curFamily.GetLeaderID()
    memLeader = curFamily.FindMember(leaderID)
    leaderName = memLeader.GetName() if memLeader else '' #ĬÈϼÇÃËÖ÷Ãû×Ö
    PlayerFamilyAction.AddFamilyActionNote(leaderName, curFamily.GetID(), ShareDefine.Def_ActionType_FamilyEvent,
                                           [ShareDefine.Def_FamilyActionEvent_LVUP, curFamily.GetLV()], tick)
    #XW_JZ_LvAdvance ¼Ò×åµÄµÈ¼¶ÌáÉýÁË£¡  25  -   -
    #NotifyAllFamilyMemberMsg(curFamily, curPlayer, "XW_JZ_LvAdvance")
    
    #֪ͨµØÍ¼·þÎñÆ÷ˢмÒ×åÊôÐÔ
    SendPack_MapServer_PlayerFamilyRefresh(curFamily)
    
    #֪ͨ¿Í»§¶Ë¼Ò×åÐÅÏ¢¸Ä±ä
    curFamily.Broadcast_FamilyChange()
    
    #ÊÀ½ç·þÎñÆ÷¼Ò×åÖØÐÂÅÅÐò
    #GameWorld.GetFamilyManager().SortByLV()
    DoFamilySort() # Éý¼¶Ö±½ÓÇ¿ÅÅÒ»´Î
    return True
#---------------------------------------------------------------------
## ɾ³ý¼Ò×å£¬Íæ¼ÒÇ¿ÖÆÀ뿪¼Ò×å
#  @param curPlayer Íæ¼ÒʵÀý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def PlayerForceLeaveFamily(curPlayer, tick):
    if curPlayer == None:
        return
    #ÉèÖõ±Ìì¼ÓÈë¼Ò×å
    GameWorld.GetPlayerManager().SetForbiddenEnterFamily(curPlayer.GetPlayerID(), True)
    # ֪ͨmapÍæ¼Ò²»ÄܲμӼÒ×å»î¶¯
    #NoteForbiddenFamilyAction(curPlayer)
    
    #GameServerÍæ¼ÒÀ뿪¼Ò×å
    curPlayer.SetFamily(None)
    curPlayer.SetFamilyID(0)
    #MapServerÍæ¼ÒÀ뿪¼Ò×å
    curPlayer.MapServer_FamilyRefresh()
    #֪ͨ¼Ò×å¿Æ¼¼ÐÅÏ¢£¬À뿪¼Ò×å£¬Íæ¼Ò×ÔÉí¿Æ¼¼²»ÊÜÓ°Ïì
    
    #µ¯ÛÀÐÅÏ¢·â°ü
    SendPackClientImpeachMsg(curPlayer, 0, 0)
    PlayerTeam.OnTeamMemFamilyRefresh(curPlayer, 0)
    
    return
#---------------------------------------------------------------------
## ֪ͨmapÍæ¼Ò²»ÄܲμӼÒ×å»î¶¯
#  @param curPlayer Íæ¼ÒʵÀý
#  @return None
def NoteForbiddenFamilyAction(curPlayer):
    # ֪ͨmapÍæ¼Ò²»ÄܲμӼÒ×å»î¶¯
    isForbid = GameWorld.GetPlayerManager().GetForbiddenEnterFamily(curPlayer.GetPlayerID())
    msg = str(GameWorld.ToIntDef(isForbid, 0))
    curPlayer.MapServer_QueryPlayerResult(0, 0, 'ForbiddenFamilyAction', msg, len(msg))
    return
#---------------------------------------------------------------------
## µ±Íæ¼Ò»»Ïߣ¬ÒªÍ¬²½¸øÍæ¼Ò×îеļÒ×åÐÅÏ¢
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def OnPlayerChangeMap(curPlayer, tick):
    #ͬ²½¸øÍæ¼Ò, ×îеļÒ×åÐÅÏ¢(¼Ò×åµÈ¼¶Ë¢ÐÂ)
    curPlayer.MapServer_FamilyRefresh()
    return
#---------------------------------------------------------------------
## µÇ¼Âß¼
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def PlayerLoginRefreshFamily(curPlayer, tick):
    SyncFakeFamilyInfo(curPlayer)
    SyncCreatFamilyTimes(curPlayer)
    familyID = curPlayer.GetFamilyID()
    curFamily = None
    
    #Íæ¼ÒûÓмÒ×å
    #Ôٴμì²éÒ»´Î, Íæ¼ÒµÄ¼Ò×åÊÇ·ñ´æÔÚ
    #2009.6.27
    #bugÆðÔ´ÓÚ:
    #Êý¾ÝÖеÄtagDBPlayer±íµÄFamilyID×Ö¶ÎΪ0, µ«ÊÇtagPlayerFamilyÖл¹ÓÐËû
    #ÓÚÊÇËûÀ뿪¼Ò×åÁË
    #ÓÚ½ñÈ¥µôÁ˲»ºÍгµÄË«ÏòÁ´Ìõ
    #Ö±½ÓÔÚÊý¾ÝÖÐÕÒ, Èç¹ûÄÜÕÒµ½Õâ¸öÈË, ÄÇôÕâ¸öÍæ¼Ò¾ÍÓмÒ×å
    #·ÀÖ¹ÔËÐдÎÊý¹ý¶à
    for i in range(2):
        if familyID == 0:
            curPlayerFamily = GameWorld.GetFamilyManager().FindPlayerFamilyIndex(curPlayer.GetPlayerID())
            if curPlayerFamily == None:
                return
            
            #Íæ¼ÒÈÔÈ»ÓмÒ×å, ²¹¾È
            familyID = curPlayerFamily.GetFamilyID()
            GameWorld.Log('Íæ¼Ò(%s)ÈÔÈ»ÓмÒ×å(%s), ²¹¾È' % (curPlayer.GetPlayerID(), familyID))
            curPlayer.SetFamilyID(familyID)
            
    
        #Íæ¼ÒµÇ¼, ˢмÒ×å
        familyManager = GameWorld.GetFamilyManager()
        curFamily = familyManager.FindFamily(familyID)
        if curFamily == None:
            PlayerForceLeaveFamily(curPlayer, tick)
            GameWorld.Log("PlayerLoginRefreshFamily -> Íæ¼ÒÀ뿪¼Ò×å = %s" % (familyID) , curPlayer.GetPlayerID())
            familyID = 0
            continue
            
    
        #ÔÚ¼Ò×åÖÐÕÒµ½Õâ¸öÍæ¼Ò, ¿´¿´ÓÐûÓÐÕâ¸öÈË(Õâ¸öÈËÔÚÀëÏß¹ý³ÌÖÐÓпÉÄܱ»Ìß³ö)
        curMember = curFamily.FindMember(curPlayer.GetPlayerID())
        if curMember == None:
            #Íæ¼ÒÒѾ±»Ìß³ö
            PlayerForceLeaveFamily(curPlayer, tick)
            GameWorld.Log("PlayerLoginRefreshFamily -> Íæ¼Ò±»Ìß³ö¼Ò×å = %s" % (familyID) , curPlayer.GetPlayerID())
            familyID = 0
            continue
    
    
    #Ë͸øÍæ¼Ò¼Ò×åÐÅÏ¢
    curPlayer.SetPlayerGetFamilyInfoTick(tick)
    
    #ÕâÈË»¹ÔÚ¼Ò×åÖÐ
    curPlayer.SetFamily(curFamily)
    curMember.SetPlayer(curPlayer)
    
    if not PlayerControl.GetIsTJG(curPlayer):
        #ÉÏÏßÖØÖÃÀëÏßʱ¼äΪ0, ·ÇÍÑ»ú¹Ò²ÅÉèÖÃ
        curMember.SetExattr2(0)
        curPlayer.Sync_FamilyInfo()
    
    curPlayer.MapServer_FamilyRefresh()
    curMember = GetPlayerFamilyMember(curPlayer)
    if curMember and GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanCall):
        PlayerFamilyAction.ViewFamilyRequestInfo(curPlayer)
    
    #XW_JZ_LeaguerOnline {%S1%}ÉÏÏßÁË£¡    25  -   -
    NotifyAllFamilyMemberMsg(curFamily, curPlayer, "XW_JZ_LeaguerOnline", [curPlayer.GetName()], False)
    
    # °ïÖ÷µ¯ÛÀ´¦Àí
    #LeaderImpeachOnLogin(curPlayer)
    
    PlayerRefresh(curPlayer, tick)
    
    GameWorldFamilyWar.OnPlayerLogin(curFamily, curPlayer)
    
    # ÃËÖ÷ÉÏÏß´¦Àí
    if curMember.GetFamilyLV() == IPY_GameServer.fmlLeader:
        OnFamilyLeaderLogin(curPlayer, curFamily)
    return
def OnFamilyLeaderLogin(curPlayer, curFamily):
    ## ÃËÖ÷µÇ¼´¦Àí
    __DoFamilyMixServerLogicOnLeaderLogin(curPlayer, curFamily)
    return
def __DoFamilyMixServerLogicOnLeaderLogin(curPlayer, curFamily):
    ## ºÏ·þÏÉÃËÃËÖ÷µÇ¼´¦Àí
    
    isMixServer = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_IsMixServer)
    if not isMixServer:
        return
    lastMixServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_LastMixServerDay)
    familyID = curFamily.GetID()
    familyMixServerDay = GetFamilyMixServerDay(curFamily)
    if familyMixServerDay == lastMixServerDay:
        GameWorld.DebugLog("ÒѾ´¦Àí¹ýÏÉÃËÃËÖ÷ºÏ·þµÇ¼Âß¼! lastMixServerDay=%s" % (lastMixServerDay), familyID)
        return
    SetFamilyMixServerDay(curFamily, lastMixServerDay)
    GameWorld.Log("´¦ÀíºÏ·þÏÉÃËÃËÖ÷µÇ¼! lastMixServerDay=%s" % (lastMixServerDay), familyID)
    
    mailItemList = IpyGameDataPY.GetFuncEvalCfg("MixServerMail", 4)
    playerID = curPlayer.GetPlayerID()
    detailDict = {}
    GameWorld.Log("    ·¢ËͺϷþÃËÖ÷רÊô²¹³¥Óʼþ! familyID=%s,mailItemList=%s" % (familyID, mailItemList), playerID)
    PlayerCompensation.SendMailByKey("MixServer2", [playerID], mailItemList, detail=detailDict)
    return
#---------------------------------------------------------------------
## Íæ¼ÒÏÂÏß¼Ò×åË¢ÐÂÂß¼
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def PlayerLogoffRefreshFamily(curPlayer, tick):
    familyID = curPlayer.GetFamilyID()
    if familyID == 0:
        #Íæ¼ÒûÓмÒ×å
        return
    
    family = curPlayer.GetFamily()
    if family == None:
        return
    
    curMember = family.FindMember(curPlayer.GetPlayerID())
    
    if not curMember:
        GameWorld.Log('###Íæ¼Ò¼Ò×åÒì³££¬Íæ¼Ò = %s,ÓмÒ×å = %s£¬¼Ò×åÖÐÎÞ·¨²éÕÒ´ËÍæ¼Ò' % (curPlayer.GetPlayerID() , curPlayer.GetFamilyID()))
        return
    
    curMember.SetPlayer(None)
    
    #XW_JZ_LeaguerLeaveline  {%S1%}ÏÂÏßÁË£¡    25  -   -
    NotifyAllFamilyMemberMsg(family, curPlayer, "XW_JZ_LeaguerLeaveline", [curPlayer.GetName()], False)
    return
#---------------------------------------------------------------------
## ˢмÒ×å³ÉÔ±»ù±¾ÐÅÏ¢
#  @param curMember ¼Ò×åÍæ¼Ò
#  @param curPlayer ÕæÊµÍæ¼Ò
#  @return None
#  @remarks ˢмÒ×å³ÉÔ±»ù±¾ÐÅÏ¢
def RefreshFamilyMemberBaseMsg(curMember, curPlayer):
    curMember.SetName(curPlayer.GetName())
    curMember.SetLV(curPlayer.GetLV())
    curMember.SetReincarnationLv(curPlayer.GetReincarnationLv())
    curMember.SetJob(curPlayer.GetJob())
    curMember.SetOperateInfo(curPlayer.GetOperateInfo())
    curMember.SetOfficialRank(curPlayer.GetOfficialRank())
    return
#---------------------------------------------------------------------
## Íæ¼ÒË¢ÐÂ
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def PlayerRefresh(curPlayer, tick):
    #»ñµÃIPY_PlayerFamilyʵÀý
    curMember = GetPlayerFamilyMember(curPlayer)
    
    if curMember == None:
        return
    
    RefreshFamilyMemberBaseMsg(curMember, curPlayer)
    #¼Ò×峤¾³½ç
    family = curPlayer.GetFamily()
    if family.GetLeaderID() == curPlayer.GetID():
        family.SetLeaderOfficialRank(curPlayer.GetOfficialRank())
    return
#---------------------------------------------------------------------
##Ë¢ÐÂÍæ¼Ò¼Ò×å»îÔ¾¶È
# @param curPlayer Íæ¼ÒʵÀý
# @param value ÊýÖµ
# @return ·µ»ØÖµÎÞÒâÒå
# @remarks Ë¢ÐÂÍæ¼Ò¼Ò×å»îÔ¾¶È
def ReFreshPlayerFamilyActiveValue(curPlayer, value):
    #»ñµÃIPY_PlayerFamilyʵÀý
    curMember = GetPlayerFamilyMember(curPlayer)
    
    if curMember == None:
        return
    #GameWorld.DebugLog('ÉèÖóÉÔ±Íæ¼Ò¼Ò×å»îÔ¾¶È value=%s'%value) 
    curMember.SetFamilyActiveValue(value)
    return
def ReFreshPlayerFamilyTotalActiveValue(curPlayer, addValue):
    '''ÉèÖóÉÔ±ÀúÊ·¹±Ï×¶È'''
    curMember = GetPlayerFamilyMember(curPlayer)
    
    if curMember == None:
        return
    #GameWorld.DebugLog('ÉèÖóÉÔ±ÀúÊ·¹±Ï×¶È value=%s'%addValue)
    curValue = curMember.GetExattr1()
    curMember.SetExattr1(min(curValue+addValue, ChConfig.Def_UpperLimit_DWord))
    return
#---------------------------------------------------------------------
##´ÓIPY_Player»ñµÃIPY_PlayerFamily
# @param curPlayer IPY_PlayerʵÀý
# @return IPY_PlayerFamilyʵÀý»òNone
# @remarks ´ÓIPY_Player»ñµÃIPY_PlayerFamily
def GetPlayerFamilyMember(curPlayer):
    family = curPlayer.GetFamily()
    if family == None:
        return
    return family.FindMember(curPlayer.GetPlayerID())
#---------------------------------------------------------------------
## ɾ³ý¼Ò×å
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def DeleteFamily(curPlayer, tick):
    family = curPlayer.GetFamily()
    #Íæ¼ÒÎÞ¼Ò×å
    if not family:
        return
    
    #-------Ö´ÐÐɾ³ýÂß¼
    DoLogic_DeleteFamily(curPlayer , family , tick)
    return
#---------------------------------------------------------------------
## ɾ³ý¼Ò×å
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param family µ±Ç°¼Ò×å
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def DoLogic_DeleteFamily(curPlayer, family, tick):
    #ɾ³ý¼Ò×åËùÓгÉÔ±
    #½«Éæ¼°µ½C++ÖÐÁбíɾ³ýµÄ¹¦ÄÜ,ͳһ¸Ä³É -> ¸´ÖÆPyÁбíºó,È»ºó½øÐÐɾ³ýÂß¼ (ÒòWhileÓм¸Âʽ«µ¼ÖÂËÀËø)
    member_List = []
    for index in range(family.GetCount()):
        player = family.GetAt(index)
        member_List.append(player)
    
    for familyMember in member_List:
        tagPlayer = familyMember.GetPlayer()
        family.DeleteMember(familyMember.GetPlayerID())
        #Íæ¼Ò²»ÔÚÏß
        if not tagPlayer:
            continue
        
        #Íæ¼ÒÔÚÏß, ÉèÖÃÕâ¸öÍæ¼ÒµÄÊôÐÔ
        PlayerForceLeaveFamily(tagPlayer, tick)
    
    #Êä³öÒ»ÌõÐÅÏ¢¼Ç¼
    if curPlayer != None:
        GameWorld.Log('Íæ¼ÒID = %s, Íæ¼ÒÃû = %s, ɾ³ý¼Ò×å =%s' % (curPlayer.GetID(), curPlayer.GetName(), family.GetID()))
    
    #ɾ³ýÕâ¸ö¼Ò×å
    __DelFamily(curPlayer, family)
    return
#---------------------------------------------------------------------
## ɾ³ý¼Ò×å
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param family µ±Ç°¼Ò×å
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def __DelFamily(curPlayer, family):
    familyID = family.GetID()
    familyName = family.GetName()
    familyWarRank = GetFamilyWarRank(family)
    
    if curPlayer != None:
        #92£¬Íæ¼Ò×ÔÐнâÉ¢Íþ
        DataRecordPack.DR_DismissFamilyByPlayer(curPlayer.GetAccID(), curPlayer.GetPlayerID(),
                                                curPlayer.GetName(), familyName, familyID,
                                                family.GetMoney(), family.GetLV(),
                                                family.GetHornor(), family.GetPoint())
        
    else:
        #Á÷Ïò206£¬ÏµÍ³½âÉ¢°ï»á
        DataRecordPack.DR_DismissFamilyBySystem(familyName, familyID, family.GetMoney(),
                                                 family.GetLV(), family.GetHornor(), family.GetPoint())
        
    #ɾ³ý¼Ò×å 
    GameWorld.GetFamilyManager().DelFamily(familyID)
    
    #ÖØÐÂÅÅÐò¼Ò×å
    #GameWorld.GetFamilyManager().SortByLV()
    if familyID in PyGameData.g_sortFamilyIDList:
        PyGameData.g_sortFamilyIDList.remove(familyID) # Ö±½Ó´ÓÅÅÐòÁбíÖÐÒÆ³ý, ²»ÐèÒªÖØÐÂÅÅÐò
        
    #¼Ò×å¿Æ¼¼É¾³ý, ¸ÄΪµØÍ¼Ö±½Ó´¦Àí, ÔÝÆÁ±Î
    #PlayerFamilyTech.DelFamilyTechData(familyID)
    
    #ɾ³ý¼Ò×åÐÐΪÊý¾Ý
    PlayerFamilyAction.ClearFamilyAction(familyID)
    #Çå¿Õ±¦¿âÎïÆ·
    PyDataManager.GetFamilyStoreItemManager().DelFamilyStoreItemAll(familyID)
    #ÏÉÃËÁªÈü
    GameWorldFamilyWar.OnDeleteFamily(familyID, familyWarRank)
    #ÏÉÃ˺ì°ü
    PlayerFamilyRedPacket.DelRedPackByFamilyID(familyID)
    SyncFakeFamilyInfo()
    return
#---------------------------------------------------------------------
## ÉèÖüÒ×åÁìÐä
#  @param curFamily µ±Ç°¼Ò×å
#  @param familyMember ¼Ò×å³ÉÔ±
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def SetFamilyLeader(curFamily, familyMember):
    #ÉèÖÃ×峤ÐÅÏ¢ 
    curFamily.SetLeaderID(familyMember.GetPlayerID())
    curFamily.SetLeaderName(familyMember.GetName())
    curFamily.SetLeaderOfficialRank(familyMember.GetOfficialRank())
    #ÉèÖÃ×峤ȨÏÞ
    ChangeFamilyMemberLv(familyMember, IPY_GameServer.fmlLeader)
    GameWorldFamilyWar.OnChangeFamilyLeader(curFamily.GetID(), familyMember.GetPlayerID())
    return
#---------------------------------------------------------------------
##¸ü¸Ä¼Ò×å³ÉÔ±µÈ¼¶.
# @param familyMember ¼Ò×å³ÉÔ±ÀàʵÀý IPY_PlayerFamily
# @param changeFamilyLV ¼Ò×å³ÉÔ±µÈ¼¶ C++ö¾Ùenum TFamilyMemberLV
# @return ·µ»ØÖµÎÞÒâÒå
# @remarks ¸ü¸Ä¼Ò×å³ÉÔ±µÈ¼¶.
def ChangeFamilyMemberLv(familyMember, changeFamilyLV, isJoin=False):
    befFamilyLV = familyMember.GetFamilyLV()
    
    #¸Ä±ä¼Ò×å³ÉÔ±µÈ¼¶
    familyMember.SetFamilyLV(changeFamilyLV)
    #ÉèÖüÒ×å³ÉԱȨÏÞ
    __SetFamilyMemberPurview(familyMember)
       
    # ¼Ç¼¼Ò×åʼþ¼Ç¼ÐÅÏ¢
    tick = GameWorld.GetGameWorld().GetTick()
    changeType = ShareDefine.Def_FamilyMemberChange_Join if isJoin else ShareDefine.Def_FamilyMemberChange_FMLV
    PlayerFamilyAction.AddFamilyActionNote(familyMember.GetName(), familyMember.GetFamilyID(), ShareDefine.Def_ActionType_FamilyEvent,
                                           [ShareDefine.Def_FamilyActionEvent_MemberChange, changeType, changeFamilyLV, befFamilyLV], tick)
    
    if befFamilyLV == changeFamilyLV:
        return
    # ±äΪ·ÇÆÕͨ³ÉÔ±£¬¸üÐÂÄ£ÐÍ×°±¸ÐÅÏ¢
    if befFamilyLV == IPY_GameServer.fmlMember:
        PlayerFamilyAction.UpdFamilyOfficerModelEquip(familyMember.GetFamilyID(), familyMember.GetPlayerID())
        
    # ±äΪÆÕͨ³ÉÔ±£¬É¾³ýÄ£ÐÍ×°±¸ÐÅÏ¢
    elif changeFamilyLV == IPY_GameServer.fmlMember:
        PlayerFamilyAction.DelFamilyOfficerModelEquip(familyMember.GetFamilyID(), familyMember.GetPlayerID())
    return
#---------------------------------------------------------------------
##ÉèÖüÒ×å³ÉԱȨÏÞ
# @param familyMember ¼Ò×å³ÉÔ±ÀàʵÀý IPY_PlayerFamily
# @return ·µ»ØÖµÎÞÒâÒå
# @remarks ÉèÖüÒ×å³ÉԱȨÏÞ
def __SetFamilyMemberPurview(familyMember):
    #ÐÞ¸ÄÉè¼Æ·½Ê½, °´È¨ÏÞ±í¶ÁÈ¡
    return
#---------------------------------------------------------------------
##»ñÈ¡¼Ò×å³ÉÔ±ÊÇ·ñÓжÔÓ¦µÄȨÏÞ
# @param familyMember ¼Ò×å³ÉÔ±ÀàʵÀý IPY_PlayerFamily
# @param powID ȨÏÞID ChConfig.Def_PurviewDictKey_
# @return ²¼¶ûÖµ
# @remarks »ñÈ¡¼Ò×å³ÉÔ±ÊÇ·ñÓжÔÓ¦µÄȨÏÞ
def GetFamilyMemberHasPow(familyMember, powID):
    powList = IpyGameDataPY.GetFuncEvalCfg('FamilyPurview')
    
    if powID >= len(powList):
        return False
    needMemberLV = powList[powID]
    return familyMember.GetFamilyLV() >= needMemberLV
#---------------------------------------------------------------------
##»ñÈ¡Íæ¼ÒÊÇ·ñÓжÔÓ¦µÄ¼Ò×åȨÏÞ
# @param curPlayer Íæ¼ÒʵÀý
# @param powID ȨÏÞID ChConfig.Def_PurviewDictKey_
# @return ²¼¶ûÖµ
# @remarks »ñÈ¡Íæ¼ÒÊÇ·ñÓжÔÓ¦µÄ¼Ò×åȨÏÞ
def GetPlayerHasFamilyPow(curPlayer, powID):
    curMember = GetPlayerFamilyMember(curPlayer)
    
    if curMember == None:
        GameWorld.ErrLog("GetPlayerHasFamilyPow -> ¼Ò×åÎ޴˳ÉÔ±", curPlayer.GetID())
        return False
    
    return GetFamilyMemberHasPow(curMember, powID)
#---------------------------------------------------------------------
## OnWeek´¥·¢
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def OnWeek(curPlayer):
    #OnWeek´¥·¢
    return
#def RefreshState(curPlayer, type, value, tick):
#    curFamily = curPlayer.GetFamily()
#    if curFamily == None:
#        return
#    
#    curMember = curFamily.FindMember(curPlayer.GetPlayerID())
#    if curMember == None:
#        return
#    if type == IPY_GameServer.CDBPlayerRefresh_FamilyHornor:
#        curMember.SetHornor(value)
#        return
#    return
#//////////////////////////////////////////////////////////////
#//05 07 ¼ÆËã¼Ò×åÕ½½±Àø#tagGCalcFamilyWarResult
#tagGCalcFamilyWarResult       *   GettagGCalcFamilyWarResult();
#
#class   IPY_GCalcFamilyWarResult
#{
#public:
#    //½ø¹¥·½ID
#    int      GetFamilyID();
#    //·ÀÊØ·½ID
#    int      GetVSFamilyID();
#    //½ø¹¥·½ÊÇ·ñÓ®ÁË
#    int      GetAttackerWin();
#    //Õ¼ËþÊý
#    int      GetTowerTaken()
#};
## ¼ÆËã¼Ò×åÕ½½±Àø
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def MapServer_FamilyWarCalcResult(index, tick):
    GameWorld.ErrLog('´Ë½Ó¿Ú·ÏÆú')
    return
#---------------------------------------------------------------------
#===============================================================================
# //0F 0C ÖØÃüÃû¼Ò×廨Ӧ#tagCRenameFamilyAnswer
# tagCRenameFamilyAnswer       *   GettagCRenameFamilyAnswer();
# 
# class   IPY_CRenameFamilyAnswer
# {
# public:
# 
#    char *      GetFamilyName();
# };
#===============================================================================
## ÖØÃüÃû¼Ò×廨Ӧ
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def RenameFamilyAnswer(index , tick):
    GameWorld.GetPsycoFunc(__Func_RenameFamilyAnswer)(index , tick)
    return
## ÖØÃüÃû¼Ò×廨Ӧ
#  @param index Íæ¼ÒË÷Òý
#  @param tick µ±Ç°Ê±¼ä
#  @return None
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def __Func_RenameFamilyAnswer(index , tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    
    #ÑéÖ¤·â°üÃû×Ö£¬ÊÇ·ñ¿ÉÒÔ¸ü¸Ä
    pack = IPY_GameServer.IPY_CRenameFamilyAnswer()
    cFamilyName = pack.GetFamilyName()
    RenameFamily(curPlayer, cFamilyName)
    return
def RenameFamily(curPlayer, familyName):
    #C++¹ýÂ˿ոñ
    familyName = GameWorld.GetGameWorld().GetCharTrim(familyName)
    
    #Ö´ÐмÒ×åÖØÃüÃûÂß¼
    result = __DoLogic_RenameFamilyAnswer(curPlayer , familyName)
    
    #֪ͨ¸ÄÃû½á¹û
    curPlayer.Sync_FamilyRenameResult(familyName, result)
    #ʧ°ÜÒ²´«»ØµØÍ¼½â³ý¸ÄÃûËø
    if result != 1:
        curPlayerID = curPlayer.GetPlayerID()
        curPlayerMapID = GameWorld.GetQueryPlayerMapID(curPlayer)
        msgStr = str([curPlayerID, ''])
        GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, curPlayerID, curPlayerMapID, 'FamilyNameRefresh',
                                            msgStr, len(msgStr),
                                                curPlayer.GetRouteServerIndex())
    return
## Ö´ÐÐÖØÃüÃûÂß¼
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param familyName ÖØÃüÃû
#  @return True or 0Òì³£ or 1³É¹¦ 2:δͨ¹ýÔà×Ö·ûÑéÖ¤ 3:¼Ò×åÃû×ÖÖÐÓзǷ¨×Ö·û 4:¼Ò×åÒѾ´æÔÚ
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def __DoLogic_RenameFamilyAnswer(curPlayer , familyName):
    #Åж¨ÊÇ·ñ¿ÉÒÔ¸ü¸Ä¼Ò×åÃû×Ö 
    if not __CheckCanRenameFamilyName(curPlayer):
        return 0
    
    #·â°üÃû×Ö´íÎó£¬ÎÞ·¨¸ÄÃû 0: Òì³£ 1£º³É¹¦, 2:δͨ¹ýÔà×Ö·ûÑéÖ¤ 3:¼Ò×åÃû×ÖÖÐÓзǷ¨×Ö·û 4:¼Ò×åÒѾ´æÔÚ
    checkFamilyName = CheckRenameFamilName(curPlayer , familyName)
    
    #Èç¹ûδ³É¹¦£¬·µ»Ø½á¹û
    if checkFamilyName != 1:
        return checkFamilyName
    
    #ÉÏÃæÒѾÑéÖ¤¹ýÁË£¬¼Ò×å¿Ï¶¨´æÔÚµÄ
    curFamily = curPlayer.GetFamily()
    curFamilyID = curFamily.GetID()
    curPlayerID = curPlayer.GetID()
#    curFamilyTrig = PlayerDBGSEvent.FindDBGSTrig_ByEventID(curFamilyID , PlayerDBGSEvent.Def_Key_RenameFamily)
#    
#    if not curFamilyTrig:
#        #¸Ã¼Ò×åÎÞ¸ÄÃûʼþ , Ìí¼Ó¸ÄÃûʼþ
#        renameTrig = PlayerDBGSEvent.AddDBGSTrig_ByEventID(curFamilyID , PlayerDBGSEvent.Def_Key_RenameFamily)
#        renameTrig.SetIsEvent(True)
#    else:
#        #δ¸ÄÃû¹ý
#        curFamilyTrig.SetIsEvent(True)
        
    #------------¸ÄÃû³É¹¦ÁË
    oldName = curFamily.GetName()
    curFamily.SetName(familyName)
    
    #֪ͨ¼Ò×åË¢ÐÂ
    curFamily.Broadcast_FamilyChange()
    
    playerManager = GameWorld.GetPlayerManager()
    
    #ÏÉÃËÁªÈü
    GameWorldFamilyWar.OnRenameFamily(curFamilyID, familyName)
    
    #֪ͨ¼Ò×åÕ½µØÍ¼£¬Ë¢ÐÂÃû×Ö
    #playerManager.MapServer_QueryPlayer(0, 0, curFamilyID, 
    #                    ShareDefine.Def_FamilyWar_FightMapID, 'FamilyWarRename', 
    #                    '%s'%(familyName), len(familyName))
    
    #֪ͨ¼Ò×åÔÚÏß³ÉÔ±£¬¸üмÒ×åÍ·¶¥Í¼±ê
    memberIDList = []
    for index in range(0 , curFamily.GetCount()):
        curMember = curFamily.GetAt(index)
        curMemberID = curMember.GetPlayerID()
        __OnFamilyNameChange(curMemberID, familyName)
        memberIDList.append(curMemberID)
        player = playerManager.FindPlayerByID(curMemberID)
        #Íæ¼Ò²»ÔÚÏß
        if not player:
            continue
        
        curPlayerMapID = GameWorld.GetQueryPlayerMapID(player)
        
        if not curPlayerMapID:
            continue
        
        msgStr = str([curPlayerID, familyName])
        playerManager.MapServer_QueryPlayer(0, 0, curMemberID, curPlayerMapID, 'FamilyNameRefresh',
                                            msgStr, len(msgStr),
                                                player.GetRouteServerIndex())
    
    PlayerCompensation.SendMailByKey('FamilyNameChange', memberIDList, [], [oldName, familyName])    
    PlayerControl.WorldNotify(0, 'Family_ChangeName', [oldName, familyName])
    return True
## ¼ì²âÊÇ·ñÄܼÒ×å¸ÄÃû£¨È¨ÏÞ£©
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @return None or True
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def __CheckCanRenameFamilyName(curPlayer):
    #--------ÑéÖ¤¼Ò×å¸ÄÃû¿ª¹ØÊÇ·ñ´ò¿ª
#    canRenameFamilyName = ReadChConfig.GetEvalChConfig('CanRenameFamilyName')
#    
#    if not canRenameFamilyName:
#        return
    
    #--------ÑéÖ¤Íæ¼ÒÊÇ·ñÓÐȨÏÞ¸ÄÃû¼Ò×å
    curFamily = curPlayer.GetFamily()
    
    if not curFamily:
        return
    
    curMember = curFamily.FindMember(curPlayer.GetPlayerID())
    
    if not curMember:
        return
    if curMember.GetFamilyLV() != IPY_GameServer.fmlLeader:
        return
    
    #--------ÑéÖ¤¸Ã¼Ò×åÊÇ·ñÒѾ¸ÄÃû¹ý ¿ÉÒÔÎÞÏÞ¸Ä
#    familyTrig = PlayerDBGSEvent.FindDBGSTrig_ByEventID(curFamily.GetID() , PlayerDBGSEvent.Def_Key_RenameFamily)
#    
#    if not familyTrig:
#        return True
#    
#    #ÒѾ¸Ä¹ýÃû×ÖÁË
#    if familyTrig.GetIsEvent():
#        return
    
    return True
#---------------------------------------------------------------------
## ¼ì²âÄÜ·ñ¸ÄÃû
#  @param curPlayer µ±Ç°Íæ¼Ò
#  @param familyName ¼Ò×åÃû
#  @return 1£º³É¹¦, 2:δͨ¹ýÔà×Ö·ûÑéÖ¤ 3:¼Ò×åÃû×ÖÖÐÓзǷ¨×Ö·û 4:¼Ò×åÒѾ´æÔÚ
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def CheckRenameFamilName(curPlayer, familyName):
    #δͨ¹ýÔà»°ÁбíÅж¨
    if DirtyList.IsWordForbidden(familyName):
        return 2
    
    if len(familyName) <= 0 or len(familyName) > ChConfig.Def_CreatFamily_MaxStr:
        return 3
    
    #------------²é¿´ÊÇ·ñÓÐͬÃûµÄ¼Ò×å
    findFamily = GameWorld.GetFamilyManager().FindFamilyByName(familyName)
    
    if findFamily != None :
        
        if findFamily.GetID() == curPlayer.GetFamilyID():
            #ÔÊÐíÐ޸ijÉ×Ô¼º¼Ò×åÔÀ´µÄÃû×Ö
            return 1
        
        else:
            return 4
    
    return 1
#---------------------------------------------------------------------
## ͨ¹ýID·µ»Ø¼Ò×åÃû³Æ
#  @param familyID ¼Ò×åID
#  @return str
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def GetFamilyName_ByID(familyID):
    family = GameWorld.GetFamilyManager().FindFamily(familyID)
        
    if family:
        return family.GetName()
        
    return ''
## ͨ¹ý¼Ò×åID·µ»ØÃËÖ÷Ãû
#  @param familyID ¼Ò×åID
#  @return str
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def GetLeaderName_ByFamilyID(familyID):
    family = GameWorld.GetFamilyManager().FindFamily(familyID)
    if family:
        return family.GetLeaderName()
    return ''
#---------------------------------------------------------------------
## ¼ì²éÍæ¼ÒÊÇ·ñÊÇÖ¸¶¨¼Ò×åµÄÖ¸¶¨È¨ÏÞ
#  @param playerID Íæ¼ÒID
#  @param family ¼Ò×å
#  @param familyLV ¼Ò×åµÈ¼¶
#  @return None or True
#  @remarks º¯ÊýÏêϸ˵Ã÷.
def CheckPlayerFamilyLV(playerID , family , familyLV):
    if not family:
        return
    
    curMember = family.FindMember(playerID)
    
    if not curMember:
        return
    
    if curMember.GetFamilyLV() != familyLV:
        return
    
    return True
def GetPlayerFamilyMemberLVEx(familyID, playerID):
    curFamily = GameWorld.GetFamilyManager().FindFamily(familyID)
    if not curFamily:
        return 0
    
    curMember = curFamily.FindMember(playerID)
    if not curMember:
        return 0
    # IPY_GameServer.fmlMember
    return curMember.GetFamilyLV()
## »ñÈ¡Íæ¼Ò¼Ò×åµÄ³ÉÔ±µÈ¼¶
def GetPlayerFamilyMemberLV(curPlayer):
    family = curPlayer.GetFamily()
    if not family:
        return 0
    
    curMember = family.FindMember(curPlayer.GetPlayerID())
    if not curMember:
        return 0
    
    return curMember.GetFamilyLV()
def GetPlayerJoinFamilyTime(curPlayer):
    #»ñÈ¡Íæ¼Ò¼ÓÈëÏÉÃËʱ¼ä
    curMember = GetPlayerFamilyMember(curPlayer)
    if not curMember:
        return 0
    return GetMemberJoinTime(curMember)
#---------------------------------------------------------------------
##¼Ò×å¹ýÌì
# @param tick ʱ¼ä´Á
# @return ·µ»ØÖµÎÞÒâÒå
# @remarks ¼Ò×å¹ýÌì
def FamilyOnDay(tick):
    #---ÉèÖÃËùÓÐÍæ¼Ò¿ÉÒÔÔٴμÓÈë¼Ò×å---
    GameWorld.GetPlayerManager().ClearForbiddenEnterFamily()
    #---¿Û³ýµØÍ¼ÉÏËùÓмÒ×åµÄά»¤·Ñ---
    familyManager = GameWorld.GetFamilyManager()
    #ɾ³ý¼Ò×åÁбí
    delFamilyList = []
    
    for i in range(0, familyManager.GetCount()):
        family = familyManager.GetAt(i)
            
        familyMoney = family.GetMoney()
        
#        useMoney = GetFamilySetting(family, ChConfig.Def_FamilySetting_SystemLostMoney)
#        
#        #¼Ò×å×ʽð²»×ã, ½âÉ¢
#        if familyMoney < useMoney:
#            family.SetMoney(0)
#            delFamilyList.append(family)
#            continue
        #¶à¾ÃûÈËÉÏÏߣ¬½âÉ¢
        offlineDay = GetLastOnlineMemberOfflineTime(family)
        GameWorld.DebugLog('    ÏÉÃË%s %sÌìûÈËÉÏÏßÁË'%(family.GetID(), offlineDay))
        if offlineDay >= IpyGameDataPY.GetFuncCfg('AutoDelFamily'):
            delFamilyList.append(family)
            continue
        
        #Çå³ý¼Ò×åÐüÉÍÈÎÎñÐÅÏ¢
        PlayerFamilyAction.ClearFamilyAction(family.GetID(), ShareDefine.Def_ActionType_FamilyArrest)
         
        #ɾ³ý3ÌìǰÉêÇë¼ÓÈëµÄÐÅÏ¢
        PlayerFamilyAction.ClearFamilyAction(family.GetID(), ShareDefine.Def_ActionType_FamilyAdd,
                                                   ChConfig.Def_Family_ClearRequestAddNote_Day)
        
        #´Ë´¦²»Í¨ÖªµØÍ¼·þÎñÆ÷¼Ò×å×ʽð±ä¸ü
#        family.SetMoney(familyMoney - useMoney)
#        if useMoney > 0:
#            #°ï»áÈÕ³£Î¬³ÖÏûºÄ{%S1%}ÒøÁ½°ï»á×ʽð
#            PlayerControl.FamilyNotify(family.GetID(), 'jiazu_lhs_272921', [useMoney])
        
        #֪ͨ¿Í»§¶ËË¢ÐÂ
        family.Broadcast_FamilyChange()
        #֪ͨµØÍ¼·þÎñÆ÷Ë¢ÐÂ
        SendPack_MapServer_PlayerFamilyRefresh(family)
        #Õ½ÃËÉý¼¶
        #DoFamilyLvUp(family)
    for delFamily in delFamilyList:
        #¶Ô²»Æð, ÄúµÄ°ï»áÒò×ʽð²»×ã½âÉ¢
        PlayerControl.FamilyNotify(delFamily.GetID(), 'jiazu_hwj35_59724')
        #°ï»á×ʽð²»×ã½âÉ¢
        GameWorld.Log('%s¼Ò×åÒò×ʽð²»×ãά»¤, ½âÉ¢ ' % (delFamily.GetID()))
        DoLogic_DeleteFamily(None, delFamily, tick)
    
    #ÖØÖüÒ×åÏà¹Ø»î¶¯Ã¿ÈÕ¿ªÆô״̬
    __SetFamilyActivityDayStateValue(0)
    return
#---------------------------------------------------------------------
##¼Ò×å¹ýÖÜ
# @param tick ʱ¼ä´Á
# @return ·µ»ØÖµÎÞÒâÒå
# @remarks ¼Ò×å¹ýÖÜ
def FamilyOnWeek(tick):
    
    #---¼ÆËãÉÏÖܼÒ×å»îÔ¾¶È---
    familyManager = GameWorld.GetFamilyManager()
    for i in range(0, familyManager.GetCount()):
        family = familyManager.GetAt(i)
        familyID = family.GetID()  # ¼Ò×åID
        
        familyActiveValue = family.GetFamilyActiveValue()  # ÀۼƻîÔ¾Öµ
        family.SetLastWeekFamilyActiveValue(familyActiveValue)  # ÉèÖÃÉÏÖÜ»îÔ¾Öµ
        family.SetFamilyActiveValue(0)
        #Çå³ý¹«¸æ´ÎÊý
        SetFamilyBroadcastCnt(family, 0)
        #Çå³ý±¾ÖÜÈÎÎñÒÑ»ñµÃ×ʽðÊýÁ¿
        SetCurWeekMissionMoney(family, 0)
        for j in xrange(family.GetCount()):
            member = family.GetAt(j)
            #ÔÏÈÊǵØÍ¼Íæ¼ÒÉÏÏߺóÖØÖ㬵¼ÖÂÍæ¼Ò²»ÉÏÏßÖܹ±Ï×ÏÔʾ֮ǰµÄ£¬¹ÌÔÚ´ËÖØÖÃ
            member.SetFamilyActiveValue(0)
        
        
        #֪ͨµØÍ¼·þÎñÆ÷ˢмÒ×åÊôÐÔ
        SendPack_MapServer_PlayerFamilyRefresh(family)
        #oss¼Ç¼ÉÏÖܼÒ×åÐÅÏ¢
        GameWorld.Log("familyActiveValue = %s" % familyActiveValue)
        DataRecordPack.DR_FamilyActiveValueByOnWeek(familyID, family.GetName(), familyActiveValue)
        
        #Çå³ý¼Ò×åboss¸±±¾ÐÅÏ¢
        PlayerFamilyBoss.FamilyBossFBOnWeek(familyID)
        
    return
def FamilyOnHour():
    familyManager = GameWorld.GetFamilyManager()
    for i in xrange(familyManager.GetCount()):
        family = familyManager.GetAt(i)
        #×Ô¶¯´«Î»
        __AutoChangeLeader(family)
        
        __AutoChangeFamilyJobLV(family)
    return
def __AutoChangeFamilyJobLV(family):
    ##¿ª·þ2ÌìÄÚд´½¨µÄÏÉÃË£¬ÏµÍ³×Ô¶¯ÎªÏÉÃ˰²ÅÅÁ½Î»¸±ÃËÖ÷
    familyID = family.GetID()
    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay)
    if openServerDay >= IpyGameDataPY.GetFuncCfg('FairyFMZ'):
        #GameWorld.DebugLog('×Ô¶¯ÎªÏÉÃ˰²ÅÅÁ½Î»¸±ÃËÖ÷ ¿ª·þÌ쳬¹ý familyID=%s'%familyID)
        return
    
    if familyID in PyGameData.g_forbidAutoViceleaderFamily:
        #GameWorld.DebugLog('×Ô¶¯ÎªÏÉÃ˰²ÅÅÁ½Î»¸±ÃËÖ÷ ±»½ûÖ¹ familyID=%s'%familyID)
        return
    createTime = family.GetCreateTime()
    pastHour = GameWorld.GetPastHour(createTime)
    if pastHour < IpyGameDataPY.GetFuncCfg('FairyFMZ', 2):
        #GameWorld.DebugLog('×Ô¶¯ÎªÏÉÃ˰²ÅÅÁ½Î»¸±ÃËÖ÷ ½¨ÃË䳬¹ýXСʱ familyID=%s,pastHour=%s'%(familyID, pastHour))
        return
    if (pastHour - IpyGameDataPY.GetFuncCfg('FairyFMZ', 2)) % IpyGameDataPY.GetFuncCfg('FairyFMZ', 3) != 0:
        GameWorld.DebugLog('×Ô¶¯ÎªÏÉÃ˰²ÅÅÁ½Î»¸±ÃËÖ÷ ¼ä¸ôûµ½ familyID=%s,pastHour=%s'%(familyID, pastHour))
        return
    
    tofmlv = IPY_GameServer.fmlViceLeader
    viceLeaderCnt = 0 #¸±ÃËÖ÷ÊýÁ¿
    changeMemberList = []
    for i in xrange(family.GetCount()):
        familyMember = family.GetAt(i)
        if familyMember.GetFamilyLV() == tofmlv:
            viceLeaderCnt += 1
            continue
        if familyMember.GetFamilyLV() < tofmlv:
            changeMemberList.append(familyMember)
        
    maxCnt = GetFamilySetting(family, ChConfig.Def_FamilyPowLvChangeFamilySettingDict[tofmlv])
    #GameWorld.DebugLog('×Ô¶¯ÎªÏÉÃ˰²ÅÅÁ½Î»¸±ÃËÖ÷ familyID=%s,viceLeaderCnt=%s,changeMemberList=%s'%(familyID, viceLeaderCnt, changeMemberList))
    if viceLeaderCnt >= maxCnt or not changeMemberList:
        return
    
    if familyID not in PyGameData.g_autoViceleaderDict:
        PyGameData.g_autoViceleaderDict[familyID] = []
        
    changeMemberList.sort(cmp=CmpAutoMemberSort)
    for i, member in enumerate(changeMemberList):
        if viceLeaderCnt + i >= maxCnt:
            break
        ChangeFamilyMemberLv(member, tofmlv)
        playerID = member.GetPlayerID()
        if playerID not in PyGameData.g_autoViceleaderDict[familyID]:
            PyGameData.g_autoViceleaderDict[familyID].append(playerID)
        GameWorld.Log('×Ô¶¯ÎªÏÉÃ˰²ÅŸ±ÃËÖ÷ familyID=%s,playerID=%s'%(familyID, playerID))
        
    return
def CmpAutoMemberSort(member1, member2):
    ## ÅÅÐò¹æÔò: µÈ¼¶>Õ½Á¦>ÈëÃËÏȺó
    ret = -cmp(member1.GetLV(), member2.GetLV())
    if ret == 0:
        ret = -cmp(GetMemberFightPower(member1), GetMemberFightPower(member2))
        if ret == 0:
            return cmp(GetMemberJoinTime(member1), GetMemberJoinTime(member2))
    return ret
#---------------------------------------------------------------------
##֪ͨµØÍ¼·þÎñÆ÷, Íæ¼Ò¼Ò×åÊôÐÔË¢ÐÂ
# @param curFamily ¼Ò×åʵÀý
# @return ·µ»ØÖµÎÞÒâÒå
# @remarks IPY_MFamilyRefresh
def SendPack_MapServer_PlayerFamilyRefresh(curFamily):
#===============================================================================
#    µ±¼Ò×åÒÔÏÂȨÏÞ±ä¸üʱҪ֪ͨµØÍ¼·þÎñÆ÷ IPY_MFamilyRefresh
#    GetFamilyLV
#    GetFamilyName
#    GetFamilyMemberLV
#    GetFamilyMoney
#    GetLastWeekFamilyActiveValue
#===============================================================================
    #֪ͨËùÓÐÔÚÏßÍæ¼Ò, ¼Ò×åµÈ¼¶Ë¢ÐÂ
    for i in range(0, curFamily.GetCount()):
        curMember = curFamily.GetAt(i)
        curPlayer = curMember.GetPlayer()
        
        if curPlayer == None:
            #²»ÔÚÏß
            continue
        
        curPlayer.MapServer_FamilyRefresh()
        
    return
#---------------------------------------------------------------------
## »ñÈ¡¼Ò×åÅäÖÃÐÅÏ¢
#  @param curFamily: ¼Ò×åʵÀý
#  @param param: ÅäÖñíË÷Òý
#  @return
def GetFamilySetting(curFamily, index):
    if index not in ChConfig.FamilySettingDict:
        return 0
    familyLv = curFamily.GetLV()  # ¼Ò×åµÈ¼¶
    curFamilyLvSetting = IpyGameDataPY.GetIpyGameData('Family', familyLv)
    #familySetting = ReadChConfig.GetEvalChConfig("FamilySetting")
    
    
    #curFamilyLvSetting = familySetting.get(familyLv, [])
    if not curFamilyLvSetting:
        GameWorld.ErrLog("key = %s not in tagFamily.txt" % familyLv)
        return 0
    keyStr = ChConfig.FamilySettingDict[index]
    return getattr(curFamilyLvSetting, keyStr)
#===============================================================================
# //A4 01  ²é¿´¼Ò×åµÚNÒ³#tagCGViewFamilyPage
# 
# struct    tagCGViewFamilyPage
# {
#    tagHead        Head;
#    WORD        PageIndex;        //²éѯҳÊý
#    BYTE        ShowCount;        //ÿҳÏÔʾÊýÁ¿
#    BYTE        SortRulex;        //ÅÅÐò¹æÔò
#    BYTE        ViewType;        //²é¿´ÀàÐÍ
# };
#===============================================================================
## ²é¿´ËùÓмÒ×åµÚNÒ³(py×Ô¶¨Òå·â°ü)
#  @param index: Íæ¼ÒË÷Òý
#  @param clientData: ¿Í»§¶Ë·â°ü½á¹¹Ìå
#  @param tick: ʱ¼ä´Á
#  @return None
def PyViewFamilyPage(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    
    viewPage = clientData.PageIndex  # ²éѯҳÊý
    showCnt = clientData.ShowCount   # ÿҳÏÔʾÊýÁ¿
#===================================================================================================
#    sortRule = clientData.SortRulex  # ÅÅÐò¹æÔò
#    viewType = clientData.ViewType   # ²é¿´ÀàÐÍ
#    if viewType not in [ShareDefine.TViewFamilyType_FamilyWar, ShareDefine.TViewFamilyType_AddFamily]:
#        return
# 
#    curPlayer.SetViewFamilyState(viewType)
#===================================================================================================
    #Ö´ÐÐÂß¼
    Sync_AllFamilyInfo(curPlayer, viewPage, showCnt)
    return
## ²éѯÊÇ·ñ»¹ÔÚÉêÇëµÄ°ï»áÉóºËÁбíÖÐ
## @param curPlayer:Íæ¼ÒʵÀý
#  @param familyList:ÉêÇëµÄ¼Ò×åÁбí
#  @return: ²éѯ½á¹û[¼Ò×åID, ÊÇ·ñÔڸüÒ×åµÄÉóºËÁбíÖÐ]  
def QueryRequestIsFamily(curPlayer, familyList):
    allFamilyActionManager = GameWorld.GetFamilyActionManager()  
    
    resultList = []
    for familyID in familyList:
        familyAction = allFamilyActionManager.GetFamilyAction(familyID, ShareDefine.Def_ActionType_FamilyAdd)
        
        isExist = False  # ÊÇ·ñÔÚÉóºËÁбíÖÐ
        for index in range(0, familyAction.Count()):
            familyActionData = familyAction.At(index)
            playerID = familyActionData.GetValue1()  # ID
            
            if curPlayer.GetID() != playerID:
                continue
            
            isExist = True
            
        resultList.append([familyID, isExist])
    
    return resultList
#---------------------------------------------------------------------
## »ñµÃ°ïÖ÷ÏÂÏßÁ˶à¾Ã
#  @param familyID:¼Ò×åid
#  @return: ÏÂÏß³ÖÐøÊ±¼ä
def GetLeaderOfflineTime(curFamily):   
    if curFamily == None:
        return 0
    leaderID = curFamily.GetLeaderID()
    curMember = curFamily.FindMember(leaderID)    
    if curMember == None:
        GameWorld.Log("GetLeaderOfflineTime->FindMember, None;%s" % leaderID)
        return 0
    offLineTimeNum = curMember.GetExattr2()
    if not offLineTimeNum:
        return 0
    offLineTime = GameWorld.ChangeTimeNumToStr(offLineTimeNum)
    return GameWorld.GetPastHour(offLineTime)
def GetLastOnlineMemberOfflineTime(family):
    '''»ñȡսÃ˶à¾ÃûÈËÉÏÏßÁË'''
    offLineTime = 0
    for i in range(0, family.GetCount()):
        member = family.GetAt(i) 
        offLineTimeNum = member.GetExattr2()
        if not offLineTimeNum:
            #ÓÐÈËÔÚÏßÖ±½Ó·µ»Ø
            return 0
        if not offLineTime:
            offLineTime = offLineTimeNum
        else:
            offLineTime = max(offLineTime, offLineTimeNum)
    if not offLineTime:
        return 0
    offLineTime = GameWorld.ChangeTimeNumToStr(offLineTime)
    return GameWorld.GetPastDay(offLineTime)
def __AutoChangeLeader(curFamily):
    '''×Ô¶¯´«Î»'''
    # »ñµÃ°ïÖ÷ÏÂÏßÁ˶à¾Ã(Сʱ)
    leaderOffLineTime = GetLeaderOfflineTime(curFamily)
    GameWorld.DebugLog('°ïÖ÷ÏÂÏßÁË%sСʱ'%leaderOffLineTime, curFamily.GetID())
    if leaderOffLineTime < IpyGameDataPY.GetFuncCfg('AutoChangeLeader'):
        return
    
    toMember = None #×îÖÕ´«Î»ÈË
    toMember1 = None #48СʱÄÚÓÐÉÏÏßµÄ×î¸ß¹±Ï׳ÉÔ±
    toMember2 = None #×î¸ß¹±Ï׳ÉÔ±
    for i in range(0, curFamily.GetCount()):
        member = curFamily.GetAt(i)
        if member.GetFamilyLV() == IPY_GameServer.fmlLeader:
            continue
        if member.GetFamilyLV() == IPY_GameServer.fmlViceLeader: #¸±ÃËÖ÷
            toMember = member
            break
        if not toMember2:
            toMember2 = member
        elif toMember2.GetExattr1() < member.GetExattr1():
            toMember2 = member
        offLineHour = GameWorld.GetPastHour(GameWorld.ChangeTimeNumToStr(member.GetExattr2())) if member.GetExattr2() else 0
        #GameWorld.DebugLog('memberID=%s ÀëÏß%sСʱ£¬ÀúÊ·¹±Ï×¶È%s'%(member.GetPlayerID(), offLineHour, member.GetExattr1()))
        if offLineHour < 48:
            if not toMember1:
                toMember1 = member
            elif toMember1.GetExattr1() < member.GetExattr1():
                toMember1 = member
    
    toMember = toMember or toMember1 or toMember2
    if not toMember:
        return
    GameWorld.DebugLog('ÏÉÃËfamilyID=%s,leaderID=%s´«Î»¸øtoMember=%s'%(curFamily.GetID(), curFamily.GetLeaderID(), toMember.GetPlayerID()))
    #´«Î»
    #°Ñ×峤½µÎªÆÕͨ³ÉÔ±
    leaderID = curFamily.GetLeaderID()
    leaderMember = curFamily.FindMember(leaderID)
    ChangeFamilyMemberLv(leaderMember, IPY_GameServer.fmlMember)
    NotifyAllFamilyMemberMsg(curFamily, 0, "XW_JZ_AppointFamily", [curFamily.GetLeaderName(), IPY_GameServer.fmlMember])
    
    #ÉèÖÃÄ¿±êÍæ¼ÒÊôÐÔ, °ÑÄ¿±êÌáʾΪ×峤
    SetFamilyLeader(curFamily, toMember)
    
    #֪ͨ¼Ò×å³ÉÔ±ÐÅÏ¢
    NotifyAllFamilyMemberMsg(curFamily, None, "XW_JZ_AppointFamily", [toMember.GetName(), IPY_GameServer.fmlLeader])
   
    
    familyID = curFamily.GetID()
    familyName = curFamily.GetName()
    DataRecordPack.DR_ImpeachChangeFamilyJob(familyID, familyName, toMember.GetPlayerID(),
                                             toMember.GetName(), toMember.GetFamilyLV())
    
    DataRecordPack.DR_ImpeachChangeFamilyJob(familyID, familyName, leaderMember.GetPlayerID(),
                                             leaderMember.GetName(), leaderMember.GetFamilyLV())
   
    leaderPlayer = toMember.GetPlayer()
    if leaderPlayer:
        leaderPlayer.MapServer_FamilyRefresh()
    return
#----°ïÖ÷µ¯ÛÀ-----------------------------------------------------------------
## °ïÖ÷ÔÚÏßÇé¿ö֪ͨ
#  @param curPlayer:Íæ¼ÒʵÀý
#  @return: None
def LeaderImpeachOnLogin(curPlayer):
    
    curFamily = curPlayer.GetFamily()
    if curFamily == None:
        return
    
    # »ñµÃµ¯ÛÀÊý¾ÝÐÅÏ¢
    familyId = curFamily.GetID()
    notePlayerID, noteTime = GetLeaderImpeachData(familyId)
    
    # °ïÖ÷ÉÏÏß
    if curPlayer.GetID() == curFamily.GetLeaderID():
        
        # ûÓе¯ÛÀ¼Ç¼
        if notePlayerID <= 0:
            return
        
        # Çå³ýµ¯ÛÀ¼Ç¼
        ClearFamilyImpeach(curFamily, notePlayerID, noteTime)
               
        curMember = curFamily.FindMember(notePlayerID)
        if curMember == None:
            return
        
        # Ìáʾµ¯ÛÀÎÞЧ
        NotifyAllFamilyMemberMsg(curFamily, curPlayer, "jiazu_xyj_202580",
                                  [curFamily.GetLeaderName(), curMember.GetName()])
        return
    
    # °ïÖ÷µ¯ÛÀʱ¼ä
    impeachTime = ReadChConfig.GetEvalChConfig('FamilyLeaderImpeach')
    
    # »ñµÃ°ïÖ÷ÏÂÏßÁ˶à¾Ã(Сʱ)
    leaderOffLineTime = GetLeaderOfflineTime(curFamily)
    
    # СÓÚÌáʾʱ¼ä£¬²»´¦Àí
    if leaderOffLineTime <= impeachTime[ImpeachNoteTime]:
        return
    
    # »¹²»Äܵ¯ÛÀ£¬µ«¿ÉÒÔ¸øÓèÌáÐÑ
    if leaderOffLineTime <= impeachTime[CanImpeachTime]:
        # ÌáʾÀëÏßÌìÊý
        PlayerControl.NotifyCode(curPlayer, 'jiazu_xyj_0', [int(leaderOffLineTime / 24)])
        return
    
    curMember = curFamily.FindMember(notePlayerID)
    if curMember:
        playerName = curMember.GetName()
        #ÓÐÈËʹÓõ¯ÛÀ·ûÌáʾ
        PlayerControl.NotifyCode(curPlayer, 'jiazu_xyj_861048', [playerName, playerName])
    else:
        # ´ïµ½µ¯ÛÀʱ¼ä£¬¸øÌáʾ
        PlayerControl.NotifyCode(curPlayer, 'jiazu_xyj_31379')
    
    # ֪ͨËùÓмÒ×å³ÉÔ±µ¯ÛÀÐÅÏ¢
    SendClientImpeachMag(curPlayer, curFamily)
    return
#---------------------------------------------------------------------
## ʹÓõ¯ÛÀ·û
#  @param curPlayer:Íæ¼ÒʵÀý
#  @return: None
def PlayerExecLeaderImpeach(curPlayer, tick):
    curFamily = curPlayer.GetFamily()
    if curFamily == None:
        return
    # °ïÖ÷µ¯ÛÀÌáʾʱ¼ä£¬¿ÉÒÔʵÐе¯ÛÀʱ¼ä
    impeachTime = ReadChConfig.GetEvalChConfig('FamilyLeaderImpeach')
    
    # »¹²»Äܵ¯ÛÀ£¬µ«¿ÉÒÔ¸øÓèÌáÐÑ
    if GetLeaderOfflineTime(curFamily) <= impeachTime[CanImpeachTime]:
        PlayerControl.NotifyCode(curPlayer, 'jiazu_xyj_161795')
        return
    
    familyId = curFamily.GetID()
    playerId = curPlayer.GetID()
    
    # »ñµÃµ¯ÛÀÊý¾ÝÐÅÏ¢
    notePlayerID, noteTime = GetLeaderImpeachData(familyId)
    
    if notePlayerID == playerId:
        PlayerControl.NotifyCode(curPlayer, 'jiazu_xyj_161795')
        return
            
    # ¼Ç¼µ¯ÛÀÐÅÏ¢
    PlayerFamilyAction.AddFamilyActionNote(curFamily.GetName(), familyId,
                                           ShareDefine.Def_ActionType_LeaderImpeachTime,
                                            [playerId], tick)
    # ֪ͨmap¿Û³ýÎïÆ·
    curPlayer.MapServer_QueryPlayerResult(0, 0, 'DelFamilyImpeachItem', '', 0)    
    # °ï»áÌáʾ
    playerName = curPlayer.GetName()
    NotifyAllFamilyMemberMsg(curFamily, curPlayer, "jiazu_xyj_861048", [playerName, playerName])
    # ֪ͨËùÓмÒ×å³ÉÔ±µ¯ÛÀÐÅÏ¢
    notePlayerID, noteTime = GetLeaderImpeachData(familyId)
    SendClientAllMemberImpeachMag(curFamily, notePlayerID, noteTime)
    return
#---------------------------------------------------------------------
## »ñµÃµ¯ÛÀÊý¾ÝÐÅÏ¢
#  @param familyId:Íæ¼Òid
#  @return: None
def GetLeaderImpeachData(familyId):
    allFamilyActionManager = GameWorld.GetFamilyActionManager()  
    familyAction = allFamilyActionManager.GetFamilyAction(familyId, ShareDefine.Def_ActionType_LeaderImpeachTime)
    
    # ÊÇ ×Ô¼ºµÄµ¯ÛÀ¼Ç¼£¬
    if familyAction.Count() > 0:
        familyActionData = familyAction.At(0)
        return familyActionData.GetValue1(), int(familyActionData.GetTime())
    
    return 0, 0
#---------------------------------------------------------------------
## °ïÖ÷µ¯ÛÀʱÖÓµ÷ÓÃ
#  @param tick
#  @return: None
def OnLeaderImpeachTick(tick):
    
    if not GameWorld.SetWorldDictKey(ChConfig.TYPE_LeaderImpeachTick, tick):
        #¼ä¸ôδµ½
        return
    
    # °ïÖ÷µ¯ÛÀÌáʾʱ¼ä£¬¿ÉÒÔʵÐе¯ÛÀʱ¼ä, µ¯ÛÀÐè³ÖÐøÊ±¼ä
    impeachTime = ReadChConfig.GetEvalChConfig('FamilyLeaderImpeach')
    
    for i in range(0, GameWorld.GetFamilyManager().GetCount()):
        family = GameWorld.GetFamilyManager().GetAt(i)
        
        # »ñµÃµ¯ÛÀÊý¾ÝÐÅÏ¢family
        notePlayerID, noteTime = GetLeaderImpeachData(family.GetID())
        if notePlayerID <= 0:
            continue
    
        familyID = family.GetID()
        curMember = family.FindMember(notePlayerID)
        if curMember == None:
            # Çå³ýµ¯ÛÀ¼Ç¼
            ClearFamilyImpeach(family, notePlayerID, noteTime)
            return
        
        # ʱ¼äδµ½
        offLineTime = GameWorld.ChangeTimeNumToStr(noteTime)
        if GameWorld.GetPastSeconds(str(offLineTime)) < impeachTime[ImpeachLastTime]:
            continue
                
        leaderID = family.GetLeaderID()
        memLeader = family.FindMember(leaderID)
        
        if memLeader == None:
            GameWorld.ErrLog('OnLeaderImpeachTick: Can not find family leader')
            return
                
        # µÈ¼¶´íÎó
        createFamily_MinLV = IpyGameDataPY.GetFuncCfg('CreateFamilyMinLV')
        if curMember.GetLV() < createFamily_MinLV or leaderID == notePlayerID:
            # Çå³ýµ¯ÛÀ¼Ç¼
            ClearFamilyImpeach(family, notePlayerID, noteTime)
            return
        
        leaderName = memLeader.GetName()
        #NotifyAllFamilyMemberMsg(family, 0, "XW_JZ_LeaveFamily", [leaderName])
        
        #ɾ³ýÍæ¼Ò
        #family.DeleteMember(leaderID)  
        # ¼Ç¼µ¯ÛÀÍ˳öÐÅÏ¢
        PlayerFamilyAction.AddFamilyActionNote(leaderName, familyID, ShareDefine.Def_ActionType_FamilyEvent,
                                               [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_Impeach], tick)
        #__DoPlayerLeaveFamilyByID(family, leaderID)
        #tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(leaderID)
        
        #ÈôÍæ¼ÒÔÚÏß, ÉèÖÃÕâ¸öÍæ¼ÒµÄÊôÐÔ
        #PlayerForceLeaveFamily(tagPlayer, tick)
        
        ChangeFamilyMemberLv(memLeader, IPY_GameServer.fmlMember) # Ô°ïÖ÷±äΪÆÕͨ³ÉÔ±
        NotifyAllFamilyMemberMsg(family, 0, "XW_JZ_AppointFamily", [leaderName, IPY_GameServer.fmlMember])
        
        #ImpeachNotifyInfoDict = ReadChConfig.GetEvalChConfig('ImpeachNotifyInfo')
        #title = ImpeachNotifyInfoDict.get('title', '')
        #content = ImpeachNotifyInfoDict.get('content', '')
        #ÔÀ´°ïÖ÷²»ÔÚ£¬·¢Óʼþ֪ͨ±»È¡´ú
        #PlayerMail.GSystemMail(leaderID , title , content%curMember.GetName() , tick)
        
        familyName = family.GetName()
        DataRecordPack.DR_ImpeachLeaveFamily(familyID, familyName, leaderID, leaderName)
        
        #ÉèÖÃÄ¿±êÍæ¼ÒÊôÐÔ, °ÑÄ¿±êÌáʾΪ×峤
        SetFamilyLeader(family, curMember)
        
        #oss¼Ç¼×Ô¼ºÖ°Î»±ä¸ü
        curFamilyLV = curMember.GetFamilyLV()
        notePlayerName = curMember.GetName()
        DataRecordPack.DR_ImpeachChangeFamilyJob(familyID, familyName, curMember.GetPlayerID(),
                                                 notePlayerName, curFamilyLV)
        #֪ͨ¼Ò×å³ÉÔ±ÐÅÏ¢,¹ã²¥        
        NotifyAllFamilyMemberMsg(family, 0, "XW_JZ_AppointFamily", [notePlayerName, curFamilyLV])
        PlayerControl.WorldNotify(0, 'jiazu_xyj_272921', [notePlayerName, familyName])
                
        player = GameWorld.GetPlayerManager().FindPlayerByID(notePlayerID) 
        if player != None:
            #֪ͨµØÍ¼·þÎñÆ÷¼Ò×åµÈ¼¶¸Ä±ä
            player.MapServer_FamilyRefresh()
            
            #Èç¹û²»¸æËß, ¿Í»§¶ËµÃ²»µ½¼Ò×åË¢ÐÂ, µ¼Ö²»´ò¿ª¼Ò×å½çÃæµÄʱºò, ²»ÄÜÖ±½Óµã»÷Í·ÏñÕÐÈË
            if GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanCall):
                player.Sync_FamilyInfo()
        
        family.Broadcast_FamilyChange() 
        # Çå³ýµ¯ÛÀ¼Ç¼
        ClearFamilyImpeach(family, notePlayerID, noteTime)
        continue
    
    return
#---------------------------------------------------------------------
## ֪ͨËùÓмÒ×å³ÉÔ±µ¯ÛÀÐÅÏ¢
#  @param curFamily µ±Ç°¼Ò×å
#  @param notePlayerID ʹÓõ¯ÛÀµÄÈË
#  @param noteTime µ¯ÛÀ¿ªÊ¼Ê±¼ä
#  @return None
def SendClientAllMemberImpeachMag(curFamily, notePlayerID, noteTime):
    
    if notePlayerID > 0:
        # °ïÖ÷µ¯ÛÀʱ¼ä
        impeachTime = ReadChConfig.GetEvalChConfig('FamilyLeaderImpeach')
        
        # ʱ¼äδµ½
        offLineTime = GameWorld.ChangeTimeNumToStr(noteTime)
        noteTime = impeachTime[ImpeachLastTime] - GameWorld.GetPastSeconds(offLineTime) 
    
    #֪ͨËùÓмÒ×å³ÉÔ±, Õâ¸öÈ˼ÓÈëÁ˼Ò×å
    for i in range(0, curFamily.GetCount()):
        notifyMember = curFamily.GetAt(i)
        
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(notifyMember.GetPlayerID())        
        if curPlayer == None:
            continue
        # µ¯ÛÀÐÅÏ¢·â°ü
        SendPackClientImpeachMsg(curPlayer, notePlayerID, noteTime)
    return
#---------------------------------------------------------------------
## ֪ͨËùÓмÒ×å³ÉÔ±µ¯ÛÀÐÅÏ¢
#  @param curPlayer 
#  @return None
def SendClientImpeachMag(curPlayer, family):
   
    # »ñµÃµ¯ÛÀÊý¾ÝÐÅÏ¢family
    notePlayerID, noteTime = GetLeaderImpeachData(family.GetID())
    if notePlayerID <= 0:
        return
    # °ïÖ÷µ¯ÛÀʱ¼ä
    impeachTime = ReadChConfig.GetEvalChConfig('FamilyLeaderImpeach')
    
    # ʱ¼äδµ½
    offLineTime = GameWorld.ChangeTimeNumToStr(noteTime)
    noteTime = impeachTime[ImpeachLastTime] - GameWorld.GetPastSeconds(offLineTime) 
    if noteTime <= 0:
        return
    
    # µ¯ÛÀÐÅÏ¢·â°ü
    SendPackClientImpeachMsg(curPlayer, notePlayerID, noteTime)
    return
#---------------------------------------------------------------------
## µ¯ÛÀÐÅÏ¢·â°ü
#  @param curPlayer µ±Ç°
#  @param notePlayerID ʹÓõ¯ÛÀµÄÈË
#  @param noteTime µ¯ÛÀ¿ªÊ¼Ê±¼ä
#  @return None
def SendPackClientImpeachMsg(curPlayer, notePlayerID, noteTime):
#    packData = ChPyNetSendPack.tagFamilyImpeachData()
#    packData.Clear()
#
#    packData.PlayerID = notePlayerID
#    packData.StartTime = noteTime
#    NetPackCommon.SendFakePack(curPlayer, packData)
    return
## ɾ³ýµ¯ÛÀÐÅÏ¢
#  @param curFamily µ±Ç°¼Ò×å
#  @param notePlayerID ʹÓõ¯ÛÀµÄÈË
#  @param noteTime µ¯ÛÀ¿ªÊ¼Ê±¼ä
#  @return None
def ClearFamilyImpeach(curFamily, notePlayerID, noteTime):
    # Óе¯ÛÀ¼Ç¼£¬ÒªÇå³ý
    familyID = curFamily.GetID()
    PlayerFamilyAction.ClearFamilyAction(familyID, ShareDefine.Def_ActionType_LeaderImpeachTime)
          
    # ֪ͨËùÓмÒ×å³ÉÔ±µ¯ÛÀÐÅÏ¢
    SendClientAllMemberImpeachMag(curFamily, 0, 0)
    return
    
#===============================================================================
# //A4 02  ²é¿´ÉêÇëÈë»áµÄÍæ¼Ò #tagCGViewFamilyRequestInfo
# 
# struct    tagCGViewFamilyRequestInfo
# {
#    tagHead        Head;
# };
#===============================================================================
## ²é¿´ÉêÇë°ï»áµÄ³ÉÔ±ÐÅÏ¢
#  @param index Íæ¼ÒË÷Òý
#  @param clientData ·â°üÊý¾Ý½á¹¹Ìå
#  @param tick ʱ¼ä´Á
#  @return None
def ViewFamilyRequestInfo(index, clientPack, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    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
#{
#    tagHead        Head;    
#    BYTE        Type;  #0 ĬÈÏÐèÒªÉóºË,1 ×Ô¶¯Í¬ÒâÉêÇë,2 ¾Ü¾øÉêÇë
#};    
#===============================================================================
## Çл»¼Ò×åÊÕÈËÉóºË·½Ê½
#  @param index Íæ¼ÒË÷Òý
#  @param clientData ·â°üÊý¾Ý½á¹¹Ìå
#  @param tick ʱ¼ä´Á
#  @return None
def ChangeFamilyAcceptJoinType(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    familyId = curPlayer.GetFamilyID()
    if familyId <= 0:
        return
    curFamily = curPlayer.GetFamily()
    if curFamily == None:
        return
    curPlayerID = curPlayer.GetPlayerID()
    curMember = curFamily.FindMember(curPlayerID)
    if curMember == None:
        return
    if not GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanCall):
        return
#    if curFamily.GetLeaderID() != curPlayer.GetID():
#        #Ö»ÓмÒ×峤²ÅÓÐȨÏ޸ıäÊÕÈË·½Ê½
#        return
    #
    if curFamily.GetAcceptJoin() == clientData.Type:
        return
    if clientData.Type > ShareDefine.FamilyAcceptJoin_Refuse:
        return
    curFamily.SetAcceptJoin(clientData.Type)
    #Í¨ÖªÍæ¼Ò¼Ò×åÐÅÏ¢
    curPlayer.Sync_FamilyInfo()
    #֪ͨ¼Ò×å³ÉÔ± ¼Ò×åÐÅÏ¢¸Ä±ä
    curFamily.Broadcast_FamilyChange()
    return
## µØÍ¼·þÎñÆ÷Ôö¼ÓÕ½ÃËÏà¹ØÐÅÏ¢Öµ
#  @param curPlayer Íæ¼ÒʵÀý
#  @param infoDict ÐÅÏ¢×Öµä
#  @return 
def MapServer_PyAddFamilyInfoValue(curPlayer, infoDict):
    
    if not curPlayer:
        GameWorld.ErrLog('MapServer_PyAddFamilyInfoValue Player = None')
        return
    curPlayerID = curPlayer.GetPlayerID()
    curFamily = curPlayer.GetFamily()
    
    if curFamily == None:
        GameWorld.Log("MapServer_PyAddFamilyInfoValue ->Íæ¼ÒûÓмÒ×å", curPlayerID)
        return
    
    curMember = curFamily.FindMember(curPlayerID)
    
    if curMember == None:
        GameWorld.Log("MapServer_PyAddFamilyInfoValue ->Î޴˳ÉÔ±", curPlayerID)
        return
    
    if not infoDict:
        GameWorld.Log("MapServer_PyAddFamilyInfoValue ->ÎÞ¸üÐÂÐÅÏ¢!", curPlayerID)
        return
    
    GameWorld.DebugLog("MapServer_PyAddFamilyInfoValue ->infoDict=%s" % str(infoDict), curPlayerID)
    
    isMapServerRefresh = False 
    #Õ½ÃËÉý¼¶
    #DoFamilyLvUp(curFamily)
    
    # ֪ͨ¿Í»§¶Ë
    curFamily.Broadcast_FamilyChange()
    
    # µØÍ¼Ë¢ÐÂ
    if isMapServerRefresh:
        SendPack_MapServer_PlayerFamilyRefresh(curFamily)
    return
def __SetFamilyActivityDayStateValue(updValue):
    ''' ÉèÖÃÕ½Ã˻½ñÌ쿪Æô״ֵ̬ '''
    PlayerDBGSEvent.SetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_FamilyActivityDayState, updValue)
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyActivityDayState, updValue)
    return
def SetFamilyActivityDayOpen(activityType):
    ''' ÉèÖÃÕ½Ã˶ÔÓ¦»î¶¯½ñÈÕ¿ªÆô¹ý '''
    fadState = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_FamilyActivityDayState)
    updState = fadState | pow(2, activityType)
    __SetFamilyActivityDayStateValue(updState)
    return
def GetFamilyLeaderLV(familyID):
    ''' »ñȡսÃËÃËÖ÷µÈ¼¶ '''
    family = GameWorld.GetFamilyManager().FindFamily(familyID)
    if not family:
        return 0
    leaderLV = 0
    leaderID = family.GetLeaderID()
    for i in range(0, family.GetCount()):
        member = family.GetAt(i)
        if member.GetPlayerID() == leaderID:
            leaderLV = member.GetLV()
            break
    return leaderLV
def AddFamilyIDToFightPowerChangeList(familyID):
    if familyID not in PyGameData.g_fightPowerChangeFamilyIDList:
        PyGameData.g_fightPowerChangeFamilyIDList.append(familyID)
        GameWorld.DebugLog("ÏÉÃËÕ½Á¦±ä¸ü´ý´¦ÀíÁбí: fightPowerChangeFamilyIDList=%s" % PyGameData.g_fightPowerChangeFamilyIDList)
    return
def UpdFamilyTotalFightPower():
    ## ¸üÐÂÏÉÃË×ÜÕ½Á¦
    if not PyGameData.g_fightPowerChangeFamilyIDList:
        #GameWorld.DebugLog("²»ÐèÒª¸üÐÂÏÉÃË×ÜÕ½Á¦!")
        return
        
    GameWorld.DebugLog("¸üÐÂÏÉÃË×ÜÕ½Á¦ fightPowerChangeFamilyIDList=%s" % PyGameData.g_fightPowerChangeFamilyIDList)
    familyManager = GameWorld.GetFamilyManager()
    for familyID in PyGameData.g_fightPowerChangeFamilyIDList:    
        family = familyManager.FindFamily(familyID)
        if not family:
            continue
        
        totalFightPower = 0
        for i in xrange(family.GetCount()):
            member = family.GetAt(i)
            totalFightPower += GetMemberFightPower(member)
        SetFamilyTotalFightPower(family, totalFightPower)
        GameWorld.DebugLog("    familyID=%s,totalFightPower=%s" % (familyID, totalFightPower))
        
    PyGameData.g_fightPowerChangeFamilyIDList = []
    
    DoFamilySort(False) # ´Ë´¦±ØÐëΪFalse
    return True
def GetSortFamilyIDList(): return PyGameData.g_sortFamilyIDList
def GetFamilyIDRank(familyID):
    '''»ñÈ¡ÏÉÃ˵ÄÅÅÃû£¬ ×¢ÒâÓëÁªÈüÅÅÃûÇø·Ö
    ÿ¸öÏÉÃËÒ»¶¨ÓÐÅÅÃû£¬µ«ÊDz»Ò»¶¨ÓÐÁªÈüÅÅÃû£¬ÁªÈüÅÅÃûÖ»ÊǾö¶¨ÏÉÃË×îÖÕÅÅÃûµÄÒ»¸ö±È½ÏÒòËØ
    '''
    if familyID not in PyGameData.g_sortFamilyIDList:
        return len(PyGameData.g_sortFamilyIDList) + 1
    return PyGameData.g_sortFamilyIDList.index(familyID) + 1
def DoFamilySort(isUpdTotalFightPower=True):
    ''' ÏÉÃËÅÅÐò£¬ ÅÅÐò¹æÔò: ÁªÈüÆÀ¼¶ > ×ÜÕ½Á¦ > µÈ¼¶ > ´´½¨Ê±¼ä
    ¶¨Ê±5·ÖÖÓÅÅÐòÒ»´Î
    ÏÉÃËÁªÈü·Ö×éǰ¼°Ã¿ÖܽáÊøºóÇ¿ÖÆÅÅÒ»´Î
    '''
    GameWorld.DebugLog("ÏÉÃËÅÅÐò, ÅÅÐò¹æÔò: ÁªÈüÆÀ¼¶ > ×ÜÕ½Á¦ > µÈ¼¶ > ´´½¨Ê±¼ä")
    if isUpdTotalFightPower:
        UpdFamilyTotalFightPower()
        
    familyList = []
    familyManager = GameWorld.GetFamilyManager()
    for i in xrange(familyManager.GetCount()):
        family = familyManager.GetAt(i)
        familyList.append(family)
    familyList.sort(cmp=CmpFamilySort)
    
    PyGameData.g_sortFamilyIDList = []
    for i, family in enumerate(familyList, 1):
        GameWorld.DebugLog("    i=%s,warRank=%s,fightPower=%s,LV=%s,CreateTime=%s,familyID=%s" 
                           % (i, GetFamilyWarRank(family), GetFamilyTotalFightPower(family), family.GetLV(), family.GetCreateTime(), family.GetID()))
        PyGameData.g_sortFamilyIDList.append(family.GetID())
    GameWorld.DebugLog("    sortFamilyIDList=%s" % PyGameData.g_sortFamilyIDList)
    return
def CmpFamilySort(family1, family2):
    ## ÅÅÐò¹æÔò: ÁªÈüÆÀ¼¶ > ×ÜÕ½Á¦ > µÈ¼¶ > ´´½¨Ê±¼ä
    familyWarRankCmpValue1 = GetFamilyWarRank(family1)
    familyWarRankCmpValue2 = GetFamilyWarRank(family2)
    
    # Á½¸ö¶¼ÓÐÃû´Î£¬Ãû´ÎֵСµÄÅÅǰ
    if familyWarRankCmpValue1 and familyWarRankCmpValue2:
        ret = cmp(familyWarRankCmpValue1, familyWarRankCmpValue2)
        if ret != 0:
            return ret
    # ÆäÖÐÒ»¸öÓÐÃû´Î£¬ÓÐÃû´ÎµÄÅÅǰ
    elif familyWarRankCmpValue1 or familyWarRankCmpValue2:
        return cmp(familyWarRankCmpValue2, familyWarRankCmpValue1) # µ¹Ðò
    
    # Õ½Á¦µ¹Ðò
    ret = cmp(GetFamilyTotalFightPower(family2), GetFamilyTotalFightPower(family1))
    if ret != 0:
        return ret
    
    # µÈ¼¶µ¹Ðò
    ret = cmp(family2.GetLV(), family1.GetLV())
    if ret != 0:
        return ret
    
    # ´´½¨Ê±¼äÕýÐò
    ret = cmp(family1.GetCreateTime(), family2.GetCreateTime())
    if ret != 0:
        return ret
    
    return 0
#// A4 11 Ò»¼üÉêÇëÈëÃË #tagCGOneKeyJoinFamily
#
#struct    tagCGOneKeyJoinFamily
#{
#    tagHead        Head;
#};
def QuicklyJoinFamily(index, clientData, tick):
    #Ò»¼üÉêÇëÈëÃË
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if curPlayer.GetFamilyID():
        return
    actionType = ShareDefine.Def_ActionType_FamilyAdd
    requestPlayerName = curPlayer.GetName()
    playerLV = curPlayer.GetLV()
    #Íæ¼ÒId, µÈ¼¶,Ö°Òµ,Õ½¶·Á¦
    actionDataList = [curPlayer.GetID(), playerLV, curPlayer.GetJob(), curPlayer.GetFightPower()]
    allFamilyActionManager = GameWorld.GetFamilyActionManager()
    familyManager = GameWorld.GetFamilyManager()
    indexList = range(familyManager.GetCount())
    random.shuffle(indexList) #´òÂÒ˳Ðò
    joinFamilyID = 0
    for i in indexList:
        family = familyManager.GetAt(i)
        if not family:
            continue
        familyID = family.GetID()
        
        #¼Ò×åÉóºËÉèÖþܾøÍæ¼Ò¼ÓÈë
        curAcceptJoinType = family.GetAcceptJoin()
        if curAcceptJoinType == ShareDefine.FamilyAcceptJoin_Refuse:
            continue
        if curAcceptJoinType == ShareDefine.FamilyAcceptJoin_Agree:
            maxMemberCnt = GetFamilySetting(family, ChConfig.Def_FamilySetting_MaxMemberCnt)
            if family.GetCount() < maxMemberCnt and playerLV >= ChConfig.Def_Family_JionMinLV:
                #Ö±½Ó¼ÓÈË
                DoPlayerJionFamily(family, curPlayer, IPY_GameServer.fmlMember)
                #֪ͨËùÓмÒ×å³ÉÔ±, Õâ¸öÈ˼ÓÈëÁ˼Ò×å
                NotifyAllFamilyMemberMsg(family, curPlayer, "XW_JZ_EnterFamily", [requestPlayerName])
                PlayerControl.NotifyCode(curPlayer, 'XW_JZ_EnterFamilyInfo', [family.GetName()])
                #֪ͨ¿Í»§¶Ë¼Ò×åÐÅÏ¢¸Ä±ä
                family.Broadcast_FamilyChange()
                return
            continue
        
        if not joinFamilyID:
            familyAction = allFamilyActionManager.GetFamilyAction(familyID, actionType)
            familyActionCnt = familyAction.Count()
            hasApply = False
            for index in range(0, familyActionCnt):
                familyActionData = familyAction.At(index)
                name = familyActionData.GetName()
                if name == requestPlayerName:
                    hasApply = True
                    break
            if hasApply:
                continue
            joinFamilyID = familyID
            
    if joinFamilyID:
        joinfamily = familyManager.FindFamily(joinFamilyID)
        result = PlayerFamilyAction.AddFamilyActionNote(requestPlayerName, joinFamilyID, actionType, actionDataList, tick, False)
        if result and joinfamily:
            sendMsg = str([joinFamilyID]) # ¸æËßMapÍæ¼ÒÉêÇë¼ÓÈë¼Ò×å³É¹¦
            curPlayer.MapServer_QueryPlayerResult(0, 0, 'FamilyAdd', sendMsg, len(sendMsg))
            #jiazu_pan_500807:ÉêÇëÈë°ï³É¹¦£¡ÇëµÈ´ý°ï»á¹ÜÀíÈËÔ±ÉóÅú£¡ 
            #PlayerControl.NotifyCode(curPlayer, "jiazu_pan_500807")
            PlayerFamilyAction.NotifyFamilyRequestInfo(joinfamily)
        
    PlayerControl.NotifyCode(curPlayer, "jiazu_pan_500807")
    return