ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
@@ -22,17 +22,17 @@
import NetPackCommon
import PlayerViewCache
import ChPyNetSendPack
import PlayerFamilyTech
import PlayerFamilyEmblem
import PlayerFamilyZhenfa
import PlayerFamilyZhenbaoge
import PlayerFamilyTaofa
import IPY_PlayerDefine
import IpyGameDataPY
import IPY_GameWorld
import ItemControler
import GameFuncComm
import ItemCommon
import DBDataMgr
import DirtyList
import ObjPool
import random
import time
@@ -53,7 +53,10 @@
FamilyChangeType_MemFmlvChange, # 成员职位变更 7
FamilyChangeType_MemLogin, # 成员上线 8
FamilyChangeType_MemLogout, # 成员离线9
) = range(10)
FamilyChangeType_FamilyLVExp, # 仙盟等级经验变更 10
FamilyChangeType_MemContrib, # 成员贡献变更 11
FamilyChangeType_OnDay, # 过天 12
) = range(13)
#仙盟权限
(
@@ -77,19 +80,27 @@
    familyManager = DBDataMgr.GetFamilyMgr()
    for i in range(0, familyManager.GetCount()):
        family = familyManager.GetAt(i)
        #珍宝阁
        familyID = family.GetID()
        PlayerFamilyZhenbaoge.OnDay(family)
        PlayerFamilyTaofa.OnDay(family)
        for index in xrange(family.GetCount()):
            member = family.GetAt(index)
            # 重置成员日信息
            member.SetContribDay(0)
            member.SetDonateCntDay(0)
        Broadcast_FamilyChange(familyID, FamilyChangeType_OnDay)
        
    return
def PlayerOnDay(curPlayer):
    if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Family):
        return
    #每日福利奖励
    Sync_FamilyDayRewardState(curPlayer)
    __FamilyAffair_Refresh(curPlayer, True)
    ResetDailyDonateCnt(curPlayer)
    PlayerFamilyZhenbaoge.PlayerOnDay(curPlayer)
    PlayerFamilyTaofa.PlayerOnDay(curPlayer)
    return
def OnPlayerLogin(curPlayer, tick):
@@ -97,11 +108,9 @@
        return
    PlayerLoginRefreshFamily(curPlayer, tick)
    Sync_RequestAddFamilyInfo(curPlayer, False)
    Sync_FamilyDayRewardState(curPlayer)
    PlayerFamilyTech.Sync_PlayerFamilyTechLV(curPlayer)
    __FamilyAffair_CheckReset(curPlayer)
    PlayerFamilyZhenfa.OnPlayerLogin(curPlayer)
    SyncDonateCntInfo(curPlayer)
    PlayerFamilyZhenbaoge.OnPlayerLogin(curPlayer)
    PlayerFamilyTaofa.OnPlayerLogin(curPlayer)
    return
def OnPlayerLogout(curPlayer):
@@ -118,15 +127,12 @@
        return
    curMember.SetOffTime(int(time.time()))
    #XW_JZ_LeaguerLeaveline  <n color="0,190,255">{%S1%}</n><n color="255,255,0">下线了!</n>    25  -   -
    NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaguerLeaveline", [curPlayer.GetPlayerName()])
    #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaguerLeaveline", [curPlayer.GetPlayerName()])
    Broadcast_FamilyChange(familyID, FamilyChangeType_MemLogout, excludeIDList=[playerID])
    return
def OnWeekEx(curPlayer):
    #重置
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyActivityAwardRecord, 0)
    for actionid in ShareDefine.FamilyActiveIDList:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyActivityFinishCnt%actionid, 0)
    return
def PlayerLoginRefreshFamily(curPlayer, tick):
@@ -150,13 +156,14 @@
    curMember.SetOffTime(0) # 在线0,脱机1,>1离线时间
    curMember.RefreshMember(curPlayer)
    Sync_FamilyInfo(curPlayer)
    SendFamilyActionInfo(curPlayer, familyID, ShareDefine.Def_ActionType_FamilyData)
    
    #通知招人
    if GetFamilyMemberHasPow(curMember, FamilyPowerID_Call):
        NetPackCommon.SendFakePack(curPlayer, GetPack_FamilyReqJoinInfo(familyID))
            
    #XW_JZ_LeaguerOnline <n color="0,190,255">{%S1%}</n><n color="255,255,0">上线了!</n>    25  -   -
    NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaguerOnline", [curPlayer.GetName()], [playerID])
    #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaguerOnline", [curPlayer.GetName()], [playerID])
    Broadcast_FamilyChange(familyID, FamilyChangeType_MemLogin, excludeIDList=[playerID])
    
    # 盟主上线处理
@@ -169,6 +176,34 @@
    
    return
def OnMinute():
    #战力刷新在DBFamily.OnMinute
    PlayerFamilyEmblem.CheckExpireEmblem()
    return
def RefreshFamilyMember(curPlayer):
    ## 玩家成员相关属性变更时同步更新家族成员信息
    familyID = curPlayer.GetFamilyID()
    if not familyID:
        return
    familyMgr = DBDataMgr.GetFamilyMgr()
    family = familyMgr.FindFamily(familyID)
    if not family:
        return
    playerID = curPlayer.GetPlayerID()
    member = family.FindMember(playerID)
    if not member:
        return
    member.RefreshMember(curPlayer)
    return
def GetRenameTime(dataAction): return dataAction.GetValue1()
def SetRenameTime(dataAction, setTime): dataAction.SetValue1(setTime)
def GetFamilyDataAction(familyID):
    ## 家族额外数据存储的行为数据,可以视为Family公共数据的一个扩展
    action = DBDataMgr.GetFamilyActionMgr().GetFamilyAction(familyID, ShareDefine.Def_ActionType_FamilyData)
    return action.GetOneAction(True)
#// A6 04 创建家族 #tagCMCreateFamily
#
#struct    tagCMCreateFamily
@@ -176,11 +211,13 @@
#    tagHead        Head;
#    char        Name[33];
#    WORD        EmblemID; //选择徽章ID,解锁仙盟等级为1级的均为可选ID
#    char        EmblemWord[3];    //徽章文字
#};
def OnCreateFamily(index, clientPack, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    inputName = clientPack.Name
    emblemID = clientPack.EmblemID
    emblemWord = clientPack.EmblemWord
    
    if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Family):
        return
@@ -218,6 +255,7 @@
        emblemID = random.choice(emblemIDList) # 从默认徽章中随机选择一个
    GameWorld.Log("创建仙盟: familyID=%s,playerID=%s,emblemID=%s" % (newFamilyID, playerID, emblemID))
    curFamily.SetEmblemID(emblemID)
    curFamily.SetEmblemWord(emblemWord)
    
    #-设置家族成员属性
    DoPlayerJionFamily(curFamily, playerID, curPlayer, IPY_PlayerDefine.fmlLeader)
@@ -242,17 +280,17 @@
    
    if DirtyList.IsWordForbidden(familyName):
        #XW_JZ_Family_NameNoLegality 对不起,家族名称中含有非法字符
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_Family_NameNoLegality")
        PlayerControl.NotifyCode(curPlayer, "NameSensitive")
        return
    
    if len(familyName) <= 0 or len(familyName) > Def_CreatFamily_MaxStr:
        PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_980181", [Def_CreatFamily_MaxStr / 2, Def_CreatFamily_MaxStr])
        PlayerControl.NotifyCode(curPlayer, "NameLenLimit", [Def_CreatFamily_MaxStr / 3, Def_CreatFamily_MaxStr])
        return
    
    familyMgr = DBDataMgr.GetFamilyMgr()
    if familyMgr.FindFamilyByName(fullFamilyName):
        #XW_JZ_EstablishErr_Name    <n color="255,255,0">对不起,您输入的家族名已存在,建立家族失败!</n> 25  -   -
        PlayerControl.NotifyCode(curPlayer, "XW_JZ_EstablishErr_Name")
        PlayerControl.NotifyCode(curPlayer, "NameExists")
        return
    
    return fullFamilyName
@@ -280,7 +318,7 @@
    maxLen = IpyGameDataPY.GetFuncCfg("FamilyNameFormat", 2)
    if len(fullName) > maxLen:
        GameWorld.ErrLog("仙盟全名 familyName=%s,全名=%s len=%s > %s, check FamilyNameFormat.txt" % (familyName, fullName, len(fullName), maxLen))
        PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_980181", [maxLen / 2, maxLen])
        PlayerControl.NotifyCode(curPlayer, "NameLenLimit", [maxLen / 3, maxLen])
        return ""
    
    return fullName
@@ -320,7 +358,7 @@
        if broadcastFamilyChange:
            Broadcast_FamilyChange(familyID, FamilyChangeType_MemJoin, excludeIDList=[playerID])
        #通知所有家族成员, 这个人加入了家族
        NotifyAllFamilyMemberMsg(familyID, "XW_JZ_EnterFamily", [member.GetPlayerName()], excludeIDList=[playerID])
        #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_EnterFamily", [member.GetPlayerName()], excludeIDList=[playerID])
        if jionPlayer:
            PlayerControl.NotifyCode(jionPlayer, 'XW_JZ_EnterFamilyInfo', [family.GetName()])
            
@@ -331,7 +369,6 @@
    
    #玩家缓存
    #PlayerViewCache.OnPlayerFamilyChange(jionPlayer.GetPlayerID(), curFamily.GetID(), curFamily.GetName())
    #PlayerTeam.OnTeamMemFamilyRefresh(jionPlayer, curFamily.GetID())
    #SetMemberFightPower(familyMember, PlayerControl.GetFightPower(jionPlayer))
    #GetFamilyMgr().AddFamilyIDToFightPowerChangeList(curFamily.GetID(), jionPlayer.GetPlayerID())
    return
@@ -358,16 +395,16 @@
            setFunc(value)
    return True
def MapServer_FamilyRefresh(curPlayer, refreshFamilyID):
def MapServer_FamilyRefresh(curPlayer, refreshFamilyID, isVoluntarily=0):
    ''' 相当于GameServer调用 curPlayer.MapServer_FamilyRefresh()
    @param familyID: 玩家更新的familyID
    @param isVoluntarily: 是否自愿离开的,仅离开刷新时有效
    '''
    
    tick = GameWorld.GetGameWorld().GetTick()
    playerID = curPlayer.GetPlayerID()
    refreshFmLV = 0
    refreshFamilyLV = 0
    refreshEmblemID = 0
    refreshFamilyName = ""
    if refreshFamilyID:
        familyMgr = DBDataMgr.GetFamilyMgr()
@@ -375,7 +412,6 @@
        if curFamily:
            refreshFamilyLV = curFamily.GetLV()
            refreshFamilyName = curFamily.GetName()
            refreshEmblemID = curFamily.GetEmblemID()
            member = curFamily.FindMember(playerID)
            if member:
                refreshFmLV = member.GetFmLV()
@@ -393,9 +429,6 @@
        curPlayer.SetFamilyName(refreshFamilyName)
        curPlayer.Notify_FamilyNameRefresh() #//04 36    周围玩家家族名刷新#tagPlayerFamilyNameRefresh
        
    if PlayerControl.GetFamilyEmblemID(curPlayer) != refreshEmblemID:
        PlayerControl.SetFamilyEmblemID(curPlayer, refreshEmblemID)
    if lastFmLV != refreshFmLV:
        PlayerControl.SetFamilyMemberLV(curPlayer, refreshFmLV)
        
@@ -412,7 +445,7 @@
        
    if lastFamilyID != 0 and curPlayer.GetFamilyID() == 0:
        #玩家离开家族
        __OnLeaveFamily(curPlayer, tick)
        __OnLeaveFamily(curPlayer, isVoluntarily, tick)
        
    elif lastFamilyID == 0 and curPlayer.GetFamilyID() != 0:
        #刚进家族并为族长,触发建家族事件
@@ -431,15 +464,10 @@
    familyMgr = DBDataMgr.GetFamilyMgr()
    familyMgr.DelPlayerReqJoinFamilyIDAll(curPlayer.GetPlayerID())
    Sync_RequestAddFamilyInfo(curPlayer)
    __FamilyAffair_CheckReset(curPlayer)
    PlayerFamilyTech.Sync_PlayerFamilyTechLV(curPlayer)
    #GameLogic_FamilyWar.DoCheckChampionFamilyTitle(curPlayer)
    #GameLogic_FamilyBoss.OnEnterFamily(curPlayer)
    #PlayerFamilyRedPacket.CreatCacheRedPacktet(curPlayer)
    #PlayerFamilyZhenfa.OnEnterFamily(curPlayer)
    PlayerFamilyTaofa.OnPlayerEnterFamily(curPlayer)
    return
def __OnLeaveFamily(curPlayer, tick):
def __OnLeaveFamily(curPlayer, isVoluntarily, tick):
    ## 退出家族触发事件
    #---清空家族相关信息---
    curPlayer.SetPerExp(0)
@@ -448,7 +476,31 @@
    curPlayer.SetLastWeekFamilyActiveValue(0)
    curPlayer.SetFamilyLV(0)
    PlayerControl.SetLeaveFamilyTimeEx(curPlayer, int(time.time()))
    leaveCnt, kickedCnt, _ = PlayerControl.GetLeaveFamilyInfo(curPlayer)
    GameWorld.DebugLog("__OnLeaveFamily: isVoluntarily=%s,leaveCnt=%s,kickedCnt=%s" % (isVoluntarily, leaveCnt, kickedCnt))
    delMoneyType, delMoneyPer = IpyGameDataPY.GetFuncCfg("FamilyLeave", 3), 0
    if isVoluntarily:
        delMoneyPerList = IpyGameDataPY.GetFuncEvalCfg("FamilyLeave", 4)
        if delMoneyPerList:
            delMoneyPer = delMoneyPerList[leaveCnt] if len(delMoneyPerList) > leaveCnt else delMoneyPerList[-1]
        leaveCnt += 1
        GameWorld.DebugLog("    增加主动离开次数: leaveCnt=%s" % (leaveCnt))
    else:
        delMoneyPerList = IpyGameDataPY.GetFuncEvalCfg("FamilyLeave", 5)
        if delMoneyPerList:
            delMoneyPer = delMoneyPerList[kickedCnt] if len(delMoneyPerList) > kickedCnt else delMoneyPerList[-1]
        kickedCnt += 1
        GameWorld.DebugLog("    增加被踢离开次数: kickedCnt=%s" % (kickedCnt))
    PlayerControl.SetLeaveFamilyInfo(curPlayer, leaveCnt, kickedCnt, isVoluntarily)
    if delMoneyType and delMoneyPer:
        nowMoney = PlayerControl.GetMoney(curPlayer, delMoneyType)
        delMoney = int(nowMoney * delMoneyPer / 100.0)
        GameWorld.DebugLog("    扣除货币: delMoneyType=%s,delMoneyPer=%s,nowMoney=%s,delMoney=%s" % (delMoneyType, delMoneyPer, nowMoney, delMoney))
        PlayerControl.PayMoney(curPlayer, delMoneyType, delMoney, "LeaveFamily")
    PlayerFamilyTaofa.OnPlayerLeaveFamily(curPlayer)
    FBLogic.OnLeaveFamily(curPlayer, tick)
    return
@@ -485,6 +537,7 @@
    clientPack.JoinLVMin = curFamily.GetJoinLVMin()
    clientPack.ServerID = curFamily.GetServerID()
    clientPack.EmblemID = curFamily.GetEmblemID()
    clientPack.EmblemWord = curFamily.GetEmblemWord()
    clientPack.FightPower = curFamily.GetFightPower()
    clientPack.FightPowerEx = curFamily.GetFightPowerEx()
    clientPack.Broadcast = curFamily.GetBroadcast()
@@ -503,12 +556,15 @@
        memInfo.RealmLV = member.GetRealmLV()
        memInfo.Face = member.GetFace()
        memInfo.FacePic = member.GetFacePic()
        memInfo.TitleID = member.GetTitleID()
        memInfo.FightPower = member.GetFightPower()
        memInfo.FightPowerEx = member.GetFightPowerEx()
        memInfo.FmLV = member.GetFmLV()
        memInfo.ServerID = member.GetServerID()
        memInfo.ContribTotal = member.GetContribTotal()
        memInfo.ContribWeek = member.GetContribWeek()
        memInfo.ContribDay = member.GetContribDay()
        memInfo.DonateCntTotal = member.GetDonateCntTotal()
        memInfo.DonateCntDay = member.GetDonateCntDay()
        memInfo.OffTime = member.GetOffTime()
        clientPack.MemberList.append(memInfo)
    clientPack.MemberCount = len(clientPack.MemberList)
@@ -616,12 +672,43 @@
        
    return
def CheckInJoinCD(curPlayer):
    ## 检查是否加入仙盟CD中
    leaveFamilyTime = PlayerControl.GetLeaveFamilyTimeEx(curPlayer)
    if not leaveFamilyTime:
        return False
    leaveCnt, kickedCnt, lastVoluntarily = PlayerControl.GetLeaveFamilyInfo(curPlayer)
    joinCDMinute = 0
    if lastVoluntarily:
        if leaveCnt <= 0:
            return False
        joinCDMinuteList = IpyGameDataPY.GetFuncEvalCfg("FamilyLeave", 1)
        if joinCDMinuteList:
            joinCDMinute = joinCDMinuteList[leaveCnt - 1] if len(joinCDMinuteList) >= leaveCnt else joinCDMinuteList[-1]
    else:
        if kickedCnt <= 0:
            return False
        joinCDMinuteList = IpyGameDataPY.GetFuncEvalCfg("FamilyLeave", 2)
        if joinCDMinuteList:
            joinCDMinute = joinCDMinuteList[kickedCnt - 1] if len(joinCDMinuteList) >= kickedCnt else joinCDMinuteList[-1]
    if joinCDMinute:
        cdTimes = joinCDMinute * 60
        passTimes = int(time.time()) - leaveFamilyTime
        if passTimes < cdTimes:
            GameWorld.DebugLog("加入仙盟CD中: leaveCnt=%s,kickedCnt=%s,lastVoluntarily=%s,leaveFamilyTime=%s(%s),passTimes=%s < %s"
                   % (leaveCnt, kickedCnt, lastVoluntarily, leaveFamilyTime, GameWorld.ChangeTimeNumToStr(leaveFamilyTime), passTimes, cdTimes))
            return True
    return False
def AutoJoinFamily(curPlayer):
    if curPlayer.GetFamilyID():
        return
    playerID = curPlayer.GetPlayerID()
    playerLV = curPlayer.GetLV()
    GameWorld.DebugLog("玩家一键自动加入家族! playerLV=%s" % playerLV, playerID)
    realmLV = curPlayer.GetOfficialRank()
    GameWorld.DebugLog("玩家一键自动加入家族! realmLV=%s" % realmLV, playerID)
    if CheckInJoinCD(curPlayer):
        return
    
    familyMgr = DBDataMgr.GetFamilyMgr()
    indexList = range(familyMgr.GetCount())
@@ -632,8 +719,8 @@
            continue
        familyID = family.GetID()
        lvMin = family.GetJoinLVMin()
        if lvMin and playerLV < lvMin:
            GameWorld.DebugLog("    等级不足的不处理! familyID=%s,lvMin=%s" % (familyID, lvMin), playerID)
        if lvMin and realmLV < lvMin:
            GameWorld.DebugLog("    官职不足的不处理! familyID=%s,lvMin=%s" % (familyID, lvMin), playerID)
            continue
        if family.GetJoinReview():
            GameWorld.DebugLog("    需要审核的不处理! familyID=%s" % familyID, playerID)
@@ -649,6 +736,7 @@
    
    # 可再扩展自动请求,暂时不处理
    GameWorld.DebugLog("没有可自动进入的仙盟!")
    PlayerControl.NotifyCode(curPlayer, "QuickEnterFamilyFail")
    return
def GetFamilySetting(familyLV, fieldName):
@@ -665,6 +753,8 @@
def RequestJoinTagFamily(curPlayer, familyID):
    ## 申请加入
    if CheckInJoinCD(curPlayer):
        return
    playerID = curPlayer.GetPlayerID()
    if curPlayer.GetFamilyID():
        GameWorld.DebugLog('已经有仙盟不能再申请加入! familyID=%s' % curPlayer.GetFamilyID(), playerID)
@@ -685,8 +775,8 @@
        return
    
    lvMin = tagFamily.GetJoinLVMin()
    if curPlayer.GetLV() < lvMin:
        GameWorld.DebugLog('等级未达到该仙盟加入最低等级限制! lv=%s < %s' % (curPlayer.GetLV(), lvMin), playerID)
    if curPlayer.GetOfficialRank() < lvMin:
        GameWorld.DebugLog('官职未达到该仙盟加入最低限制! realmLV=%s < %s' % (curPlayer.GetOfficialRank(), lvMin), playerID)
        return
    
    # 需要审核,满员后端不限制申请,由前端自行决定是否可申请
@@ -771,6 +861,7 @@
            reqInfo.RealmLV = viewCache.GetRealmLV()
            reqInfo.Face = viewCache.GetFace()
            reqInfo.FacePic = viewCache.GetFacePic()
            reqInfo.TitleID = viewCache.GetTitleID()
            reqInfo.FightPower = viewCache.GetFightPower()
            reqInfo.FightPowerEx = viewCache.GetFightPowerEx()
            reqInfo.ServerID = viewCache.GetServerID()
@@ -882,7 +973,7 @@
def OnChangeFamilyJoin(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    joinReview = clientData.JoinReview
    joinLVMin = clientData.JoinLVMin
    joinLVMin = clientData.JoinLVMin # 官职
    
    playerID = curPlayer.GetPlayerID()
    familyID = curPlayer.GetFamilyID()
@@ -942,11 +1033,13 @@
#{
#    tagHead        Head;
#    BYTE        EmblemID;    // 更换的徽章ID
#    char        EmblemWord[3];    // 徽章文字
#};
def OnChangeFamilyEmblem(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    changeEmblemID = clientData.EmblemID
    PlayerFamilyEmblem.OnChangeFamilyEmblem(curPlayer, changeEmblemID)
    emblemWord = clientData.EmblemWord
    PlayerFamilyEmblem.OnChangeFamilyEmblem(curPlayer, changeEmblemID, emblemWord)
    return
#// A6 25 修改家族成员职位 #tagCMChangeFamilyMemLV
@@ -1132,7 +1225,8 @@
    #XW_JZ_LeaveFamily   <n color="0,190,255">{%S1%}</n><n color="255,255,0">退出了家族!</n>  25  -   -
    NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaveFamily", [curPlayer.GetName()])
    
    MapServer_FamilyRefresh(curPlayer, 0)
    __DoPlayerLeaveFamilyByID(family, playerID, curPlayer)
    MapServer_FamilyRefresh(curPlayer, 0, 1)
    
    if family.GetCount() == 0:
        #玩家离开后, 家族没有人了 , 删除这个家族
@@ -1197,10 +1291,16 @@
    
    #删除玩家
    tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagMemberID)
    __DoPlayerLeaveFamilyByID(family, tagPlayerID, tagPlayer)
    if tagPlayer:
        MapServer_FamilyRefresh(tagPlayer, 0)
        
    Broadcast_FamilyChange(familyID, FamilyChangeType_MemLeave)
    return
def __DoPlayerLeaveFamilyByID(curFamily, leavePlayerID, tagPlayer=None):
    ## 有玩家离开家族处理,主要针对家族层级的,玩家个人的在 __OnLeaveFamily 处理
    PlayerFamilyTaofa.OnFamilyMemberLeave(curFamily, leavePlayerID, tagPlayer)
    return
#// A6 11 家族改名 #tagCMRenameFamily
@@ -1215,7 +1315,7 @@
def UpdateFamilyName(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    newName = clientData.NewName
    itemIndex = clientData.ItemIndex
    #itemIndex = clientData.ItemIndex
    
    playerID = curPlayer.GetPlayerID()
    familyID = curPlayer.GetFamilyID()
@@ -1233,18 +1333,24 @@
        GameWorld.DebugLog("非盟主不可改名!", playerID)
        return
    
    cdHours = IpyGameDataPY.GetFuncCfg("FamilyRename", 2)
    if cdHours:
        cdSeconds = cdHours * 3600
        curTime = int(time.time())
        dataAction = GetFamilyDataAction(familyID)
        lastRenameTime = GetRenameTime(dataAction)
        if lastRenameTime and (curTime - lastRenameTime) < cdSeconds:
            GameWorld.DebugLog("仙盟改名CD中! lastRenameTime=%s,cdHours=%s" % (GameWorld.ChangeTimeNumToStr(lastRenameTime), cdHours))
            return
    familyName = CheckInputFamilyName(curPlayer, newName)
    if not familyName:
        return
    
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    curItem = itemPack.GetAt(itemIndex)
    if not ItemCommon.CheckItemCanUse(curItem) or curItem.GetType() != ChConfig.Def_ItemType_ChangeFamilyName:
        GameWorld.DebugLog("没有仙盟改名道具! itemIndex=%s" % itemIndex, playerID)
    moneyType, moneyValue = IpyGameDataPY.GetFuncEvalCfg("FamilyRename", 1)
    if moneyType and moneyValue and not PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, "FamilyRename"):
        return
    ItemCommon.DelItem(curPlayer, curItem, 1, True, 'UpdateFamilyName')
    
    #oldName = curFamily.GetName()
    family.SetName(familyName)
    
    infoPack = GetPack_FamilyInfo(familyID)
@@ -1257,10 +1363,11 @@
            continue
        Sync_FamilyInfo(player, infoPack)
        player.SetFamilyName(familyName)
        player.Notify_FamilyNameRefresh() #//04 36    周围玩家家族名刷新#tagPlayerFamilyNameRefresh
        #player.Notify_FamilyNameRefresh() #//04 36    周围玩家家族名刷新#tagPlayerFamilyNameRefresh
        
    #PlayerCompensation.SendMailByKey('FamilyNameChange', memberIDList, [], [oldName, familyName])
    #PlayerControl.WorldNotify(0, 'Family_ChangeName', [oldName, familyName])
    if cdHours:
        SetRenameTime(dataAction, curTime)
        SendFamilyActionInfo(None, familyID, ShareDefine.Def_ActionType_FamilyData)
    return
#// A6 20 搜索家族列表 #tagCMViewFamilyPage
@@ -1310,9 +1417,13 @@
        family = familyMgr.GetAt(index)
        if not family:
            continue
        if msg and msg not in family.GetName():
            continue
        if msg:
            if msg in family.GetName() or msg == str(family.GetID()):
                pass
            else:
                continue
        familyView = ChPyNetSendPack.tagMCFamilyView()
        familyView.Rank = index + 1
        familyView.FamilyID = family.GetID()
        familyView.FamilyName = family.GetName()
        familyView.FamilyNameLen = len(familyView.FamilyName)
@@ -1325,6 +1436,7 @@
        familyView.JoinLVMin = family.GetJoinLVMin()
        familyView.ServerID = family.GetServerID()
        familyView.EmblemID = family.GetEmblemID()
        familyView.EmblemWord = family.GetEmblemWord()
        familyView.FightPower = family.GetFightPower()
        familyView.FightPowerEx = family.GetFightPowerEx()
        familyView.MemberCount = family.GetCount()
@@ -1344,20 +1456,138 @@
#    BYTE        DonateType;    // 捐献类型
#};
def OnFamilyMoneyDonate(index, clientData, tick):
    #curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #DonateType = clientData.DonateType
    #playerID = curPlayer.GetPlayerID()
    # 先屏蔽,等功能定了再改
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    donateType = clientData.DonateType
    playerID = curPlayer.GetPlayerID()
    familyID = curPlayer.GetFamilyID()
    if familyID <= 0:
        return
    familyMgr = DBDataMgr.GetFamilyMgr()
    curFamily = familyMgr.FindFamily(familyID)
    if not curFamily:
        return
    curMember = curFamily.FindMember(playerID)
    if not curMember:
        return
    ipyData = IpyGameDataPY.GetIpyGameData("FamilyDonate", donateType)
    if not ipyData:
        return
    dailyCntMax = ipyData.GetDailyCnt()
    donateCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyDonateCnt % donateType)
    if donateCnt >= dailyCntMax:
        GameWorld.DebugLog("今日捐献次数已达上限! donateType=%s,donateCnt=%s >= %s" % (donateType, donateCnt, dailyCntMax), playerID)
        return
    moneyType = ipyData.GetMoneyType()
    moneyValue = ipyData.GetMoneyValue()
    if not moneyType or not moneyValue:
        return
    if not PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, "FamilyMoneyDonate"):
        return
    awardItemList = ipyData.GetAwardItemList()
    donateCnt += 1
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyDonateCnt % donateType, donateCnt)
    SyncDonateCntInfo(curPlayer)
    # 增加成员捐献次数记录
    memDonateCntDay = curMember.GetDonateCntDay() + 1
    memDonateCntTotal = min(curMember.GetDonateCntTotal() + 1, ChConfig.Def_UpperLimit_DWord)
    curMember.SetDonateCntDay(memDonateCntDay)
    curMember.SetDonateCntTotal(memDonateCntTotal)
    GameWorld.DebugLog("家族捐献: donateType=%s,donateCnt=%s,%s,memDonateCntDay=%s,memDonateCntDay=%s"
                       % (donateType, donateCnt, awardItemList, memDonateCntDay, memDonateCntTotal), playerID)
    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["FamilyMoneyDonate", False, {}])
    return
def ResetDailyDonateCnt(curPlayer):
    isReset = False
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetFamilyDonateCount()):
        ipyData = ipyDataMgr.GetFamilyDonateByIndex(index)
        donateType = ipyData.GetDonateType()
        donateCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyDonateCnt % donateType)
        if donateCnt:
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyDonateCnt % donateType, 0)
            isReset = True
    if isReset:
        SyncDonateCntInfo(curPlayer)
    return
#---------------------------------------------------------------------
def AddPlayerFamilyActiveValue(curPlayer, addValue, sendPackGameServer = False, reason = 0, isSysMsg=False):
    # 多个地方用到,先保留,之后删除统一修改
def SyncDonateCntInfo(curPlayer):
    donateCntList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetFamilyDonateCount()):
        ipyData = ipyDataMgr.GetFamilyDonateByIndex(index)
        donateType = ipyData.GetDonateType()
        donateCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyDonateCnt % donateType)
        donateCntList.append(donateCnt)
    if not donateCntList:
        return
    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCDonateCntInfo)
    clientPack.DonateCntList = donateCntList
    clientPack.Count = len(clientPack.DonateCntList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def AddFamilyExp(curPlayer, addExp):
    ## 增加玩家家族经验
    playerID = curPlayer.GetPlayerID()
    familyID = curPlayer.GetFamilyID()
    if familyID <= 0:
        return
    familyMgr = DBDataMgr.GetFamilyMgr()
    curFamily = familyMgr.FindFamily(familyID)
    if not curFamily:
        return
    curLV = curFamily.GetLV()
    curExp = curFamily.GetExp()
    updLV = curLV
    updExp = curExp + addExp
    GameWorld.DebugLog("增加仙盟经验: curLV=%s,curExp=%s,addExp=%s,updExp=%s" % (curLV, curExp, addExp, updExp), playerID)
    ipyData = IpyGameDataPY.GetIpyGameData("Family", curLV)
    lvUPExp = ipyData.GetNeedExp()
    while lvUPExp and updExp >= lvUPExp:
        ipyData = IpyGameDataPY.GetIpyGameDataNotLog("Family", updLV + 1)
        if not ipyData:
            break
        updLV += 1
        updExp -= lvUPExp
        lvUPExp = ipyData.GetNeedExp()
        GameWorld.DebugLog("    仙盟升级: updLV=%s,updExp=%s,lvUPExp=%s" % (updLV, updExp, lvUPExp), playerID)
    curFamily.SetLV(updLV)
    curFamily.SetExp(updExp)
    Sync_FamilyInfo(curPlayer)
    Broadcast_FamilyChange(familyID, FamilyChangeType_FamilyLVExp, excludeIDList=[playerID])
    return True
def SendPack_GameServer_AddFamilyDetail(curPlayer, addFamilyHornor = 0, addFamilyMoney = 0, addFamilyActiveValue = 0, resion=0):
    return
def SendPack_GameServer_AddFamilyDetailEx(curPlayer, addPlayerActiveValue, addFamilyMoney = 0, addFamilyHornor = 0, resion=0):
def AddFamilyContrib(curPlayer, addContribValue):
    ## 增加玩家累计家族贡献
    playerID = curPlayer.GetPlayerID()
    familyID = curPlayer.GetFamilyID()
    if familyID <= 0:
        return
    familyMgr = DBDataMgr.GetFamilyMgr()
    curFamily = familyMgr.FindFamily(familyID)
    if not curFamily:
        return
    curMember = curFamily.FindMember(playerID)
    if not curMember:
        return
    contribDay = curMember.GetContribDay() + addContribValue
    contribTotal = min(curMember.GetContribTotal() + addContribValue, ChConfig.Def_UpperLimit_DWord)
    curMember.SetContribDay(contribDay)
    curMember.SetContribTotal(contribTotal)
    GameWorld.DebugLog("增加成员贡献: familyID=%s,addContribValue=%s,contribDay=%s,contribTotal=%s" % (familyID, addContribValue, contribDay, contribTotal), playerID)
    Sync_FamilyInfo(curPlayer)
    Broadcast_FamilyChange(familyID, FamilyChangeType_MemContrib, excludeIDList=[playerID])
    return
## ------------------------------------------------------------------------------------------------
@@ -1387,7 +1617,8 @@
def SendFamilyActionInfo(curPlayer, familyID, actionType):
    ## 发送家族行为
    # @param curPlayer: 为None时通知该仙盟所有成员
    if not familyID:
        return
    familyAction = DBDataMgr.GetFamilyActionMgr().GetFamilyAction(familyID, actionType)
    
    clientPack = ChPyNetSendPack.tagMCFamilyActionInfo()
@@ -1458,222 +1689,3 @@
    Broadcast_FamilyPack(familyID, clientPack)
    return
def GetFamilyDayAward(curPlayer):
    ##领取仙盟每日奖励 2小时脱机挂时间
    return
def Sync_FamilyDayRewardState(curPlayer):
    clientPack = ChPyNetSendPack.tagMCFamilyDayAward()
    clientPack.GetState = 0
    clientPack.MoneyDonateCount = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyDonateRecord)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def AddFamilyActivity(curPlayer, actionid, addCnt=1):
    return
##--------------------------------------- 仙盟事务 --------------------------------------------------
AffairState_None = 0 # 无
AffairState_Underway = 1 # 进行中
AffairState_Finish = 2 # 已完成
#// A6 13 家族事务操作 #tagCMFamilyAffairOP
#
#struct     tagCMFamilyAffairOP
#{
#    tagHead        Head;
#    BYTE        OPType;    // 操作类型:1-刷新事务;2-开始事务;3-领取事务奖励;
#    WORD        AffairID;    // 事务ID,可选
#};
def OnFamilyAffairOP(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    opType = clientData.OPType
    affairID = clientData.AffairID
    if opType == 1:
        __FamilyAffair_Refresh(curPlayer)
    elif opType == 2:
        __FamilyAffair_Start(curPlayer, affairID)
    elif opType == 3:
        __FamilyAffair_GetAward(curPlayer, affairID)
    return
def __FamilyAffair_CheckReset(curPlayer):
    ## 检查任务重置,登录,进入仙盟触发
    info = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyAffairInfo % 1)
    if not info:
        # 任务1还没分配,默认强制重置
        __FamilyAffair_Refresh(curPlayer, True)
    else:
        SyncFamilyAffairInfo(curPlayer)
    return
def __FamilyAffair_Refresh(curPlayer, isReset=False):
    ## 刷新事务
    playerID = curPlayer.GetPlayerID()
    moneyType, moneyValue = 0, 0
    dayRefreshFreeCount = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyAffairRefreshFree)
    if not isReset:
        freeCountMax = IpyGameDataPY.GetFuncCfg("FamilyAffair", 2)
        if freeCountMax and dayRefreshFreeCount >= freeCountMax:
            moneyType, moneyValue = IpyGameDataPY.GetFuncEvalCfg("FamilyAffair", 3)
            if not PlayerControl.HaveMoney(curPlayer, moneyType, moneyValue):
                return
    sendMailAffairList = []
    refreshAffairIDList = []
    affairCountMax = IpyGameDataPY.GetFuncCfg("FamilyAffair", 1)
    affairStarDict = IpyGameDataPY.GetFuncEvalCfg("FamilyAffair", 4)
    maxStar = 0
    starWeightList = []
    for starStr, starInfo in affairStarDict.items():
        star = int(starStr)
        if star > maxStar:
            maxStar = star
        starWeightList.append([starInfo[0], star])
    for affairID in range(1, affairCountMax + 1):
        star, state = __GetAffairInfo(curPlayer, affairID)
        if isReset:
            # 重置时还在进行中的直接发奖励
            if state == AffairState_Underway:
                sendMailAffairList.append([affairID, star])
            refreshAffairIDList.append(affairID)
        else:
            # 非重置只处理没有状态非最高星的
            if state == AffairState_None and star < maxStar:
                refreshAffairIDList.append(affairID)
    GameWorld.DebugLog("刷新事务: isReset=%s,moneyType=%s,moneyValue=%s,dayRefreshFreeCount=%s"
                       % (isReset, moneyType, moneyValue, dayRefreshFreeCount), playerID)
    GameWorld.DebugLog("    sendMailAffairList=%s" % sendMailAffairList, playerID)
    for mailInfo in sendMailAffairList:
        affairID, star = mailInfo
        if str(star) not in affairStarDict:
            continue
        paramList = [affairID, star]
        addItemList = affairStarDict[str(star)][2]
        PlayerControl.SendMailByKey("FamilyAffairAward", [playerID], addItemList, paramList)
    if isReset:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyAffairRefreshFree, 0)
        for affairID in range(1, affairCountMax + 1):
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyAffairInfo % affairID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyAffairStartTime % affairID, 0)
    else:
        if moneyType and moneyValue:
            PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, "FamilyAffair")
        else:
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyAffairRefreshFree, dayRefreshFreeCount + 1)
    GameWorld.DebugLog("    starWeightList=%s" % starWeightList, playerID)
    GameWorld.DebugLog("    refreshAffairIDList=%s" % refreshAffairIDList, playerID)
    for affairID in refreshAffairIDList:
        star = GameWorld.GetResultByWeightList(starWeightList, 1)
        __SetAffairInfo(curPlayer, affairID, star, AffairState_None)
        GameWorld.DebugLog("    随机事务:affairID=%s,star=%s" % (affairID, star), playerID)
    SyncFamilyAffairInfo(curPlayer)
    return
def __FamilyAffair_Start(curPlayer, affairID):
    ## 开始事务
    playerID = curPlayer.GetPlayerID()
    star, state = __GetAffairInfo(curPlayer, affairID)
    if not star:
        return
    if state != AffairState_None:
        GameWorld.DebugLog("仙盟事务已经进行中或已完成,无法开始: affairID=%s,star=%s,state=%s" % (affairID, star, state), playerID)
        return
    startTime = int(time.time())
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyAffairStartTime % affairID, startTime)
    __SetAffairInfo(curPlayer, affairID, star, AffairState_Underway)
    GameWorld.DebugLog("仙盟事务开始: affairID=%s,star=%s,startTime=%s" % (affairID, star, startTime), playerID)
    SyncFamilyAffairInfo(curPlayer, affairID)
    return
def __FamilyAffair_GetAward(curPlayer, affairID):
    ## 领取事务奖励
    playerID = curPlayer.GetPlayerID()
    curTime = int(time.time())
    affairStarDict = IpyGameDataPY.GetFuncEvalCfg("FamilyAffair", 4)
    star, state = __GetAffairInfo(curPlayer, affairID)
    if state != AffairState_Underway:
        GameWorld.DebugLog("仙盟事务状态非进行中无法领取: affairID=%s,star=%s,state=%s" % (affairID, star, state), playerID)
        SyncFamilyAffairInfo(curPlayer, affairID)
        return
    startTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyAffairStartTime % affairID)
    remainDuration = __GetAffairRemainDuration(curPlayer, affairID, star, curTime, affairStarDict)
    if remainDuration != 0:
        GameWorld.DebugLog("仙盟事务当前剩余时长未完成: affairID=%s,remainDuration=%s,startTime=%s"
                           % (affairID, remainDuration, startTime), playerID)
        SyncFamilyAffairInfo(curPlayer, affairID)
        return
    if str(star) not in affairStarDict:
        return
    addItemList = affairStarDict[str(star)][2]
    if not ItemCommon.GiveAwardItem(curPlayer, addItemList):
        return
    __SetAffairInfo(curPlayer, affairID, star, AffairState_Finish)
    GameWorld.DebugLog("仙盟事务领奖: affairID=%s,star=%s" % (affairID, star), playerID)
    SyncFamilyAffairInfo(curPlayer, affairID)
    return
def __GetAffairInfo(curPlayer, affairID):
    affairInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyAffairInfo % affairID)
    star, state = affairInfo / 10, affairInfo % 10
    return star, state
def __SetAffairInfo(curPlayer, affairID, star, state):
    info = star * 10 + state
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyAffairInfo % affairID, info)
    return
def __GetAffairRemainDuration(curPlayer, affairID, star, curTime, affairStarDict):
    ## -1-未开始;>=0-剩余时长
    startTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyAffairStartTime % affairID)
    if not startTime:
        return -1
    starInfo = affairStarDict.get(str(star), [])
    needDuration = starInfo[1] if len(starInfo) > 1 else 0
    # 可扩展减时长属性
    speedPer = 0#PlayerControl.GetAffairSpeedPer(curPlayer)
    if speedPer:
        needDuration = int(needDuration * max(10000 - speedPer, 0) / 10000.0)
        #GameWorld.DebugLog("事务加速: needDuration=%s,speedPer=%s" % (needDuration, speedPer), curPlayer.GetPlayerID())
    remainDuration = max(needDuration - (curTime - startTime), 0)
    return remainDuration
def SyncFamilyAffairInfo(curPlayer, affairID=None):
    if affairID == None:
        affairIDList = []
        affairCountMax = IpyGameDataPY.GetFuncCfg("FamilyAffair", 1)
        for affairID in range(1, affairCountMax + 1):
            affairIDList.append(affairID)
    else:
        affairIDList = [affairID]
    curTime = int(time.time())
    affairStarDict = IpyGameDataPY.GetFuncEvalCfg("FamilyAffair", 4)
    affairInfoList = []
    for affairID in affairIDList:
        star, state = __GetAffairInfo(curPlayer, affairID)
        remainDuration = __GetAffairRemainDuration(curPlayer, affairID, star, curTime, affairStarDict)
        affairInfo = ChPyNetSendPack.tagMCFamilyAffair()
        affairInfo.AffairID = affairID
        affairInfo.Star = star
        affairInfo.State = state
        affairInfo.RemainDuration = max(0, remainDuration)
        affairInfoList.append(affairInfo)
    if not affairInfoList:
        return
    clientPack = ChPyNetSendPack.tagMCFamilyAffairInfo()
    clientPack.Clear()
    clientPack.RefreshFreeCount = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyAffairRefreshFree)
    clientPack.AffairInfoList = affairInfoList
    clientPack.Count = len(clientPack.AffairInfoList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return