ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
@@ -22,16 +22,18 @@
import NetPackCommon
import PlayerViewCache
import ChPyNetSendPack
import PlayerFamilyTech
import PlayerFamilyEmblem
import PlayerFamilyZhenfa
#import PlayerFamilyZhenfa
import PlayerFamilyZhenbaoge
import IPY_PlayerDefine
import IpyGameDataPY
import IPY_GameWorld
import ItemControler
import GameFuncComm
import ItemCommon
import DBDataMgr
import DirtyList
import ObjPool
import random
import time
@@ -52,7 +54,10 @@
FamilyChangeType_MemFmlvChange, # 成员职位变更 7
FamilyChangeType_MemLogin, # 成员上线 8
FamilyChangeType_MemLogout, # 成员离线9
) = range(10)
FamilyChangeType_FamilyLVExp, # 仙盟等级经验变更 10
FamilyChangeType_MemContrib, # 成员贡献变更 11
FamilyChangeType_OnDay, # 过天 12
) = range(13)
#仙盟权限
(
@@ -69,16 +74,33 @@
                      IPY_PlayerDefine.fmlViceLeader:"DeputyLeaderMax",
                      }
def FamilyOnDay():
    if GameWorld.IsCrossServer():
        return
    familyManager = DBDataMgr.GetFamilyMgr()
    for i in range(0, familyManager.GetCount()):
        family = familyManager.GetAt(i)
        familyID = family.GetID()
        #珍宝阁
        PlayerFamilyZhenbaoge.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)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyZhenbaogeCut, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FamilyZhenbaogeBuy, 0)
    #PlayerFamilyZhenbaoge.Sync_ZhenbaogeInfo(curPlayer)
    ResetDailyDonateCnt(curPlayer)
    PlayerFamilyZhenbaoge.PlayerOnDay(curPlayer)
    return
def OnPlayerLogin(curPlayer, tick):
@@ -86,11 +108,9 @@
        return
    PlayerLoginRefreshFamily(curPlayer, tick)
    Sync_RequestAddFamilyInfo(curPlayer, False)
    Sync_FamilyDayRewardState(curPlayer)
    PlayerFamilyTech.Sync_PlayerFamilyTechLV(curPlayer)
    __FamilyAffair_CheckReset(curPlayer)
    PlayerFamilyZhenfa.OnPlayerLogin(curPlayer)
    #PlayerFamilyZhenbaoge.Sync_ZhenbaogeInfo(curPlayer)
    SyncDonateCntInfo(curPlayer)
    #PlayerFamilyZhenfa.OnPlayerLogin(curPlayer)
    PlayerFamilyZhenbaoge.OnPlayerLogin(curPlayer)
    return
def OnPlayerLogout(curPlayer):
@@ -113,9 +133,6 @@
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):
@@ -158,6 +175,11 @@
    
    return
def OnMinute():
    #战力刷新在DBFamily.OnMinute
    PlayerFamilyEmblem.CheckExpireEmblem()
    return
#// A6 04 创建家族 #tagCMCreateFamily
#
#struct    tagCMCreateFamily
@@ -165,11 +187,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
@@ -207,6 +231,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)
@@ -215,7 +240,7 @@
    #XW_JZ_EstablishSud <n color="255,255,0">恭喜您,家族建立成功!</n>    25  -   -
    PlayerControl.NotifyCode(curPlayer, "XW_JZ_EstablishSud")
    PlayerControl.WorldNotify(0, "jiazu_liubo_671654", [curPlayer.GetName(), fullFamilyName, newFamilyID])
    #PlayerFamilyZhenbaoge.OnZhenbaogeReset(curFamily)
    PlayerFamilyZhenbaoge.OnZhenbaogeReset(curFamily)
    return
def CheckInputFamilyName(curPlayer, inputName):
@@ -320,7 +345,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
@@ -356,7 +380,6 @@
    playerID = curPlayer.GetPlayerID()
    refreshFmLV = 0
    refreshFamilyLV = 0
    refreshEmblemID = 0
    refreshFamilyName = ""
    if refreshFamilyID:
        familyMgr = DBDataMgr.GetFamilyMgr()
@@ -364,7 +387,6 @@
        if curFamily:
            refreshFamilyLV = curFamily.GetLV()
            refreshFamilyName = curFamily.GetName()
            refreshEmblemID = curFamily.GetEmblemID()
            member = curFamily.FindMember(playerID)
            if member:
                refreshFmLV = member.GetFmLV()
@@ -382,9 +404,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)
        
@@ -398,7 +417,6 @@
        #触发家族升级事件, 在SetFamilyLV之后,任务可以取等级判定
        if isLVUP:
            pass
            #EventShell.EventResponse_OnFamilyLVUp(curPlayer)
        
    if lastFamilyID != 0 and curPlayer.GetFamilyID() == 0:
        #玩家离开家族
@@ -408,7 +426,6 @@
        #刚进家族并为族长,触发建家族事件
        if curPlayer.GetFamilyMemberLV() == IPY_GameWorld.fmlLeader:
            pass
            #EventShell.EventResponse_OnCreateFamily(curPlayer)
            
        #进入家族触发事件
        __OnEnterFamily(curPlayer, tick)
@@ -422,13 +439,6 @@
    familyMgr = DBDataMgr.GetFamilyMgr()
    familyMgr.DelPlayerReqJoinFamilyIDAll(curPlayer.GetPlayerID())
    Sync_RequestAddFamilyInfo(curPlayer)
    #EventShell.EventResponse_OnFamily(curPlayer)
    __FamilyAffair_CheckReset(curPlayer)
    PlayerFamilyTech.Sync_PlayerFamilyTechLV(curPlayer)
    #GameLogic_FamilyWar.DoCheckChampionFamilyTitle(curPlayer)
    #GameLogic_FamilyBoss.OnEnterFamily(curPlayer)
    #PlayerFamilyRedPacket.CreatCacheRedPacktet(curPlayer)
    #PlayerFamilyZhenfa.OnEnterFamily(curPlayer)
    return
def __OnLeaveFamily(curPlayer, tick):
@@ -441,8 +451,6 @@
    curPlayer.SetFamilyLV(0)
    PlayerControl.SetLeaveFamilyTimeEx(curPlayer, int(time.time()))
    
    #触发玩家离开家族的任务
    #EventShell.EventResponse_OnLeaveFamily(curPlayer)
    FBLogic.OnLeaveFamily(curPlayer, tick)
    return
@@ -479,6 +487,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()
@@ -502,7 +511,9 @@
        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)
@@ -936,11 +947,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
@@ -1304,8 +1317,11 @@
        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.FamilyID = family.GetID()
        familyView.FamilyName = family.GetName()
@@ -1319,6 +1335,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()
@@ -1338,240 +1355,235 @@
#    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)
    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
## ------------------------------------------------------------------------------------------------
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
#// A6 17 查询家族行为信息 #tagCMQueryFamilyAction
#
#struct     tagCMFamilyAffairOP
#struct    tagCMQueryFamilyAction
#{
#    tagHead        Head;
#    BYTE        OPType;    // 操作类型:1-刷新事务;2-开始事务;3-领取事务奖励;
#    WORD        AffairID;    // 事务ID,可选
#    BYTE        ActionType;        // 行为类型
#    DWORD        FamilyID;         // 家族ID,发0默认自己家族
#};
def OnFamilyAffairOP(index, clientData, tick):
def OnQueryFamilyAction(index, cliendData, 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):
    ## 刷新事务
    if not curPlayer:
        return
    
    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])
    actionType = cliendData.ActionType
    familyID = cliendData.FamilyID
    if not familyID:
        familyID = curPlayer.GetFamilyID()
        
    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)
    SendFamilyActionInfo(curPlayer, familyID, actionType)
    return
def SendFamilyActionInfo(curPlayer, familyID, actionType):
    ## 发送家族行为
    # @param curPlayer: 为None时通知该仙盟所有成员
    
    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)
    familyAction = DBDataMgr.GetFamilyActionMgr().GetFamilyAction(familyID, actionType)
    clientPack = ChPyNetSendPack.tagMCFamilyActionInfo()
    clientPack.FamilyID = familyID
    clientPack.ActionType = actionType
    clientPack.FamilyActionList = []
    for index in xrange(familyAction.Count()):
        familyActionData = familyAction.At(index)
        
    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)
        actionData = ChPyNetSendPack.tagMCFamilyAction()
        actionData.Time = familyActionData.GetTime()
        actionData.Name = familyActionData.GetName()
        actionData.NameLen = len(actionData.Name)
        actionData.Value1 = familyActionData.GetValue1()
        actionData.Value2 = familyActionData.GetValue2()
        actionData.Value3 = familyActionData.GetValue3()
        actionData.Value4 = familyActionData.GetValue4()
        actionData.Value5 = familyActionData.GetValue5()
        actionData.Value6 = familyActionData.GetValue6()
        actionData.UseData = familyActionData.GetUserData()
        actionData.UseDataLen = len(actionData.UseData)
        clientPack.FamilyActionList.append(actionData)
        
    SyncFamilyAffairInfo(curPlayer)
    clientPack.Count = len(clientPack.FamilyActionList)
    if curPlayer:
        NetPackCommon.SendFakePack(curPlayer, clientPack)
        return
    Broadcast_FamilyPack(familyID, clientPack)
    return
def __FamilyAffair_Start(curPlayer, affairID):
    ## 开始事务
    playerID = curPlayer.GetPlayerID()
    star, state = __GetAffairInfo(curPlayer, affairID)
    if not star:
def SendFamilyAction(actionDataList, curPlayer=None):
    ## 同步指定仙盟action
    # @param actionDataList: 支持列表或指定actionData
    # @param curPlayer: 为None时通知该仙盟所有成员
    if not isinstance(actionDataList, list):
        actionDataList = [actionDataList]
    if not actionDataList:
        return
    if state != AffairState_None:
        GameWorld.DebugLog("仙盟事务已经进行中或已完成,无法开始: affairID=%s,star=%s,state=%s" % (affairID, star, state), playerID)
    familyActionData = actionDataList[0]
    familyID = familyActionData.GetFamilyID()
    actionType = familyActionData.GetActionType()
    clientPack = ChPyNetSendPack.tagMCFamilyActionInfo()
    clientPack.FamilyID = familyID
    clientPack.ActionType = actionType
    clientPack.FamilyActionList = []
    for familyActionData in actionDataList:
        actionData = ChPyNetSendPack.tagMCFamilyAction()
        actionData.Time = familyActionData.GetTime()
        actionData.Name = familyActionData.GetName()
        actionData.NameLen = len(actionData.Name)
        actionData.Value1 = familyActionData.GetValue1()
        actionData.Value2 = familyActionData.GetValue2()
        actionData.Value3 = familyActionData.GetValue3()
        actionData.Value4 = familyActionData.GetValue4()
        actionData.Value5 = familyActionData.GetValue5()
        actionData.Value6 = familyActionData.GetValue6()
        actionData.UseData = familyActionData.GetUserData()
        actionData.UseDataLen = len(actionData.UseData)
        clientPack.FamilyActionList.append(actionData)
    clientPack.Count = len(clientPack.FamilyActionList)
    if curPlayer:
        NetPackCommon.SendFakePack(curPlayer, clientPack)
        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)
    Broadcast_FamilyPack(familyID, clientPack)
    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 = 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