hxp
2024-06-20 61bae8814450e86b1851cb892086b7081a675ff1
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActBossTrial.py
@@ -21,27 +21,41 @@
import PlayerBillboard
import IpyGameDataPY
import GameWorld
BillboardType = ShareDefine.Def_BT_BossTrialSubmit
import CrossRealmMsg
import CrossActionControl
import CrossBillboard
import PlayerFamily
import PyDataManager
def OnActStart(actNum):
    ## 活动开启
    PlayerBillboard.ClearBillboardByIndex(BillboardType)
    PlayerBillboard.ClearBillboardByIndex(ShareDefine.Def_BT_BossTrialSubmit)
    PlayerBillboard.ClearBillboardByIndex(ShareDefine.Def_BT_BossTrialSubmitFamily)
    familyActionMgr = GameWorld.GetFamilyActionManager()
    familyManager = GameWorld.GetFamilyManager()
    for i in range(0, familyManager.GetCount()):
        family = familyManager.GetAt(i)
        familyID = family.GetID()
        familyActionMgr.DelFamilyAction(familyID, ShareDefine.Def_ActionType_BossTrialSubmit)
    return
def OnActEnd(actNum, ipyData, dayIndex):
    ## 活动结束
    OnGiveFamilyOrderAwawrd(actNum, ipyData, dayIndex)
    cfgID = ipyData.GetCfgID() if ipyData else 0
    # 发放排行奖励
    GameWorld.Log("=== boss历练活动结束!发放榜单奖励! === actNum=%s,cfgID=%s,dayIndex=%s" % (actNum, cfgID, dayIndex))
    GameWorld.Log("=== boss历练活动结束!发放本服个人榜单奖励! === actNum=%s,cfgID=%s,dayIndex=%s" % (actNum, cfgID, dayIndex))
    if not cfgID:
        return
    BillboardType = ShareDefine.Def_BT_BossTrialSubmit
    billBoard = GameWorld.GetBillboard().FindBillboard(BillboardType)
    if not billBoard:
        return
    mailKey = ipyData.GetMailKey()
    templateID = GameWorld.GetTemplateID(ipyData, cfgID, dayIndex)
    if not templateID:
        GameWorld.Log("本次活动没有个人榜奖励!")
        return
    tempIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", templateID)
    if not tempIpyDataList:
@@ -68,13 +82,457 @@
        name2 = billBoardData.GetName2()
        cmpValue = billBoardData.GetCmpValue()
        
        GameWorld.Log("    发放boss历练榜单奖励: rank=%s,playerID=%s,cmpValue=%s,awardItemList=%s, %s"
        GameWorld.Log("    发放boss历练个人榜单奖励: rank=%s,playerID=%s,cmpValue=%s,awardItemList=%s, %s"
                      % (rank, playerID, cmpValue, awardItemList, name2))
        
        PlayerCompensation.SendMailByKey(mailKey, [playerID], awardItemList, [rank])
        PlayerCompensation.SendMailByKey("BossTrialMail10", [playerID], awardItemList, [rank])
        
    DataRecordPack.DR_BillboardData(BillboardType, "BossTrial", {"actNum":actNum, "cfgID":cfgID, "dayIndex":dayIndex, "templateID":templateID})
    PlayerBillboard.CopyBillboard(ShareDefine.Def_BT_BossTrialSubmitBak, BillboardType)
    PlayerBillboard.ClearBillboardByIndex(BillboardType)
    GameWorld.Log("=================================================================================")
    return
def OnGiveFamilyOrderAwawrd(actNum, ipyData, dayIndex):
    cfgID = ipyData.GetCfgID() if ipyData else 0
    # 发放排行奖励
    GameWorld.Log("=== boss历练活动结束!发放本服仙盟榜单奖励! === actNum=%s,cfgID=%s,dayIndex=%s" % (actNum, cfgID, dayIndex))
    if not cfgID:
        return
    BillboardType = ShareDefine.Def_BT_BossTrialSubmitFamily
    billBoard = GameWorld.GetBillboard().FindBillboard(BillboardType)
    if not billBoard:
        return
    templateIDList = ipyData.GetFamilyTemplateIDList()
    templateID = templateIDList[-1] if dayIndex >= len(templateIDList) else templateIDList[dayIndex]
    if not templateID:
        GameWorld.Log("本次活动没有仙盟榜奖励!")
        return
    tempIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", templateID)
    if not tempIpyDataList:
        return
    rankAwardDict = {}
    for tempIpyData in tempIpyDataList:
        rankAwardDict[tempIpyData.GetRank()] = [tempIpyData.GetAwardItemList(), tempIpyData.GetMemAwardItemList()]
    GameWorld.Log("    templateID=%s,rankAwardDict=%s" % (templateID, rankAwardDict))
    billBoard.Sort()
    familyManager = GameWorld.GetFamilyManager()
    for index in xrange(billBoard.GetCount()):
        billBoardData = billBoard.At(index)
        if not billBoardData:
            continue
        familyRank = index + 1
        awardInfo = GameWorld.GetOrderValueByDict(rankAwardDict, familyRank, False)
        if not awardInfo:
            break
        leaderAwardItemList, memAwardItemList = awardInfo
        familyID = billBoardData.GetID()
        cmpValue = billBoardData.GetCmpValue()
        family = familyManager.FindFamily(familyID)
        if not family:
            continue
        familyActionData = GetFamilyBossTrialSubmitActionData(familyID, False)
        if not familyActionData:
            continue
        awardState = GetFamilyAwardState(familyActionData)
        awardIndex = 0 # 本服奖励状态索引
        if awardState&pow(2, awardIndex):
            GameWorld.ErrLog("该仙盟本服榜奖励已发放! familyID=%s" % familyID)
            continue
        updAwardState = awardState|pow(2, awardIndex)
        SetFamilyAwardState(familyActionData, updAwardState)
        memSubCountDict = GetFamilyMemSubCountDict(familyActionData)
        leaderID = family.GetLeaderID()
        awardMemIDList = []
        for index in xrange(family.GetCount()):
            member = family.GetAt(index)
            memPlayerID = member.GetPlayerID()
            if memPlayerID == leaderID:
                continue
            awardMemIDList.append(memPlayerID)
        paramList = [familyRank]
        if not leaderAwardItemList:
            awardMemIDList.append(leaderID)
        else:
            PlayerCompensation.SendMailByKey("BossTrialFamilyLeader", [leaderID], leaderAwardItemList, paramList)
        PlayerCompensation.SendMailByKey("BossTrialFamilyMember", awardMemIDList, memAwardItemList, paramList)
        GameWorld.Log("发放boss历练活动仙盟榜单奖励本服: familyID=%s,名次=%s,总提交个数=%s,updAwardState=%s,awardMemIDList=%s,memSubCountDict=%s"
                      % (familyID, familyRank, cmpValue, updAwardState, awardMemIDList, memSubCountDict))
    DataRecordPack.DR_BillboardData(BillboardType, "BossTrial", {"actNum":actNum, "cfgID":cfgID, "dayIndex":dayIndex, "templateID":templateID})
    PlayerBillboard.CopyBillboard(ShareDefine.Def_BT_BossTrialSubmitFamilyBak, BillboardType)
    PlayerBillboard.ClearBillboardByIndex(BillboardType)
    GameWorld.Log("=================================================================================")
    return
def MapServer_BossTrial(curPlayer, msgList):
    mapID = curPlayer.GetRealMapID()
    playerID = curPlayer.GetPlayerID()
    GameWorld.DebugLog("MapServer_BossTrial mapID=%s,msgList=%s" % (mapID, msgList), playerID)
    if not msgList:
        return
    msgType, dataMsg = msgList
    ret = None
    if msgType == "BossTrialSubmit":
        ret = __OnBossTrialSubmit(curPlayer, dataMsg)
    if ret == None:
        return
    return msgList + (ret if isinstance(ret, list) else [ret])
def __OnBossTrialSubmit(curPlayer, dataMsg):
    ## 地图提交boss凭证
    playerID = curPlayer.GetPlayerID()
    accID = curPlayer.GetAccID()
    playerName = curPlayer.GetName()
    job = curPlayer.GetJob()
    realmLV = curPlayer.GetOfficialRank()
    familyID = curPlayer.GetFamilyID()
    submitCount, updSubmitCount = dataMsg
    curFamily, familySubmitTotal = __DoBossTrialSubmitFamilyAction(curPlayer, submitCount)
    familyBillInfo = {}
    #更新本服仙盟提交榜单
    if familyID and curFamily and familySubmitTotal:
        familyBillInfo = PlayerFamily.GetFamilyBillboardInfo(curFamily)
        familyBillInfo["familySubmitTotal"] = familySubmitTotal
        PlayerBillboard.UpdateFamilyBillboard(ShareDefine.Def_BT_BossTrialSubmitFamily, familyBillInfo, familySubmitTotal)
    #同步跨服
    playerInfo = {"playerID":playerID, "playerName":playerName, "accID":accID, "job":job, "realmLV":realmLV,
                  "playerSubmitTotal":updSubmitCount}
    SyncBossTrialSubmitToCrossServer(curPlayer, playerInfo, familyBillInfo)
    return
def __DoBossTrialSubmitFamilyAction(curPlayer, submitCount):
    ## 执行提交凭证到仙盟Action数据
    curFamily = None
    familySubmitTotal = 0
    playerID = curPlayer.GetPlayerID()
    familyID = curPlayer.GetFamilyID()
    if not familyID:
        return curFamily, familySubmitTotal
    familyManager = GameWorld.GetFamilyManager()
    curFamily = familyManager.FindFamily(familyID)
    if not curFamily:
        return curFamily, familySubmitTotal
    familyActionData = GetFamilyBossTrialSubmitActionData(familyID, True)
    familySubmitTotal = GetFamilySubmitTotal(familyActionData) + submitCount
    SetFamilySubmitTotal(familyActionData, familySubmitTotal)
    memSubCountDict = GetFamilyMemSubCountDict(familyActionData)
    memSubCountDict[playerID] = memSubCountDict.get(playerID, 0) + submitCount
    SetFamilyMemSubCountDict(familyActionData, memSubCountDict)
    return curFamily, familySubmitTotal
def GetFamilyBossTrialSubmitActionData(familyID, isAdd=False):
    ## 获取仙盟boss凭证提交
    familyActionObj = None
    actionType = ShareDefine.Def_ActionType_BossTrialSubmit
    familyAction = GameWorld.GetFamilyActionManager().GetFamilyAction(familyID, actionType)
    if not familyAction.Count():
        if isAdd:
            familyActionObj = familyAction.AddAction()
            familyActionObj.SetFamilyId(familyID)
            familyActionObj.SetActionType(actionType)
    else:
        familyActionObj = familyAction.At(0)
    return familyActionObj
def GetFamilySubmitTotalByID(familyID):
    ## 获取仙盟提交的凭证总数
    familyActionData = GetFamilyBossTrialSubmitActionData(familyID, False)
    if not familyActionData:
        return 0
    return GetFamilySubmitTotal(familyActionData)
def GetFamilySubmitTotal(familyActionData): return familyActionData.GetValue1()
def SetFamilySubmitTotal(familyActionData, submitTotal): familyActionData.SetValue1(submitTotal)
def GetFamilyAwardState(familyActionData): return familyActionData.GetValue2()
def SetFamilyAwardState(familyActionData, state): return familyActionData.SetValue2(state)
def GetFamilyMemSubCountDict(familyActionData):
    memSubCountDict = {}
    useData = familyActionData.GetUseData()
    if useData:
        try:
            memSubCountDict = eval(useData)
        except:
            memSubCountDict = {}
    return memSubCountDict
def SetFamilyMemSubCountDict(familyActionData, memSubCountDict):
    useData = str(memSubCountDict).replace(" ", "")
    familyActionData.SetUseData(useData, len(useData))
    return
def SyncBossTrialSubmitToCrossServer(curPlayer, playerInfo, familyInfo):
    ## 同步boss凭证提交总数到跨服服务器
    actInfo = CrossActionControl.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_BossTrial)
    if not actInfo.get(ShareDefine.ActKey_State):
        return
    cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
    ipyDataDict = actInfo.get(ShareDefine.ActKey_IpyDataInfo, {})
    if not ipyDataDict:
        return
    zoneID = ipyDataDict.get("ZoneID")
    if not cfgID or not zoneID:
        return
    dataMsg = {"cfgID":cfgID, "zoneID":zoneID, "playerInfo":playerInfo, "familyInfo":familyInfo}
    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BossTrialSubmit, dataMsg)
    return
def CrossServerMsg_CrossBossTrialFamilyAward(msgData):
    ## 收到跨服通知  - 结算跨服仙盟榜奖励
    cfgID = msgData["cfgID"]
    zoneID = msgData["zoneID"]
    templateID = msgData["templateID"]
    awardFamilyList = msgData["awardFamilyList"]
    GameWorld.Log("收到跨服同步的结算boss历练活动跨服仙盟榜奖励: cfgID=%s,zoneID=%s,templateID=%s" % (cfgID, zoneID, templateID))
    familyManager = GameWorld.GetFamilyManager()
    for familyInfo in awardFamilyList:
        familyID, familyRank, familySubmitTotal, leaderAwardItemList, memAwardItemList = familyInfo
        family = familyManager.FindFamily(familyID)
        if not family:
            GameWorld.DebugLog("非本服仙盟或已解散! familyID=%s" % familyID)
            continue
        familyActionData = GetFamilyBossTrialSubmitActionData(familyID, False)
        if not familyActionData:
            continue
        awardState = GetFamilyAwardState(familyActionData)
        awardIndex = 1 #跨服奖励状态索引
        if awardState&pow(2, awardIndex):
            GameWorld.ErrLog("该仙盟跨服榜奖励已发放! familyID=%s" % familyID)
            continue
        updAwardState = awardState|pow(2, awardIndex)
        SetFamilyAwardState(familyActionData, updAwardState)
        memSubCountDict = GetFamilyMemSubCountDict(familyActionData)
        leaderID = family.GetLeaderID()
        awardMemIDList = []
        for index in xrange(family.GetCount()):
            member = family.GetAt(index)
            memPlayerID = member.GetPlayerID()
            if memPlayerID == leaderID:
                continue
            awardMemIDList.append(memPlayerID)
        paramList = [familyRank]
        if not leaderAwardItemList:
            awardMemIDList.append(leaderID)
        else:
            PlayerCompensation.SendMailByKey("BossTrialCrossFamilyLeader", [leaderID], leaderAwardItemList, paramList)
        PlayerCompensation.SendMailByKey("BossTrialCrossFamilyMember", awardMemIDList, memAwardItemList, paramList)
        GameWorld.Log("发放boss历练活动仙盟榜单奖励跨服: familyID=%s,名次=%s,总提交个数=%s,updAwardState=%s,awardMemIDList=%s,memSubCountDict=%s"
                      % (familyID, familyRank, familySubmitTotal, updAwardState, awardMemIDList, memSubCountDict))
    return
##------------------------------------------ 跨服boss历练活动 ---------------------------------------
def ClientServerMsg_BossTrialSubmit(serverGroupID, msgData):
    ## 收到子服 - 提交boss凭证
    cfgID = msgData["cfgID"]
    zoneID = msgData["zoneID"]
    playerInfo = msgData["playerInfo"]
    familyInfo = msgData["familyInfo"]
    actInfo = CrossActionControl.GetCrossActInfoByCfgID(ShareDefine.CrossActName_BossTrial, cfgID, zoneID)
    if not actInfo or not actInfo[ShareDefine.ActKey_State]:
        GameWorld.ErrLog("跨服boss历练非活动中,无法提交! cfgID=%s, zoneID=%s" % (cfgID, zoneID))
        return
    if not actInfo[ShareDefine.ActKey_StateJoin]:
        GameWorld.ErrLog("跨服boss历练非可参与状态,无法提交! cfgID=%s, zoneID=%s" % (cfgID, zoneID))
        return
    ipyData = IpyGameDataPY.GetIpyGameData("CrossActBossTrial", cfgID)
    if not ipyData:
        return
    personlLimit, familyLimit = ipyData.GetRankLimitList()
    playerID = playerInfo["playerID"]
    playerName = playerInfo["playerName"]
    job = playerInfo["job"]
    accID = playerInfo["accID"]
    realmLV = playerInfo["realmLV"]
    playerSubmitTotal = playerInfo["playerSubmitTotal"]
    groupValue1 = zoneID
    if playerSubmitTotal >= personlLimit:
        name2, type2, value1, value2 = accID, job, realmLV, 0
        CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BossTrialSubmit, groupValue1, playerID, playerName,
                                         name2, type2, value1, value2, playerSubmitTotal)
    if familyInfo and familyInfo.get("familySubmitTotal", 0) >= familyLimit:
        familySubmitTotal = familyInfo["familySubmitTotal"]
        CrossBillboard.UpdCrossBillboardFamily(ShareDefine.Def_CBT_BossTrialSubmitFamily, groupValue1, familyInfo, familySubmitTotal)
    return
def OnCrossActIDChange(cfgID, state):
    ## 活动ID变更
    # 先结算活动
    zoneID = 0
    ipyData = IpyGameDataPY.GetIpyGameData("CrossActBossTrial", cfgID)
    if ipyData:
        zoneID = ipyData.GetZoneID()
        PersonalTemplateID = ipyData.GetPersonalTemplateID()
        FamilyTemplateID = ipyData.GetFamilyTemplateID()
        if PersonalTemplateID:
            __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID)
        if FamilyTemplateID:
            __GiveCrossOrderAwardFamily(cfgID, zoneID, FamilyTemplateID)
    # 如果有新活动,处理新活动
    if not state:
        return
    if zoneID:
        groupValue1 = zoneID
        billboardMgr = PyDataManager.GetCrossBillboardManager()
        billboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_BossTrialSubmit, groupValue1)
        billboardObj.ClearData() # 新活动重置榜单数据
        billboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_BossTrialSubmitFamily, groupValue1)
        billboardObj.ClearData() # 新活动重置榜单数据
    return
def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID):
    groupValue1 = zoneID
    billboardType = ShareDefine.Def_CBT_BossTrialSubmit
    billboardMgr = PyDataManager.GetCrossBillboardManager()
    billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1)
    billboardDataCount = billboardObj.GetCount()
    if not billboardDataCount:
        GameWorld.Log("跨服Boss凭证个人排行数据为空! billboardType=%s,cfgID=%s,zoneID=%s,templateID=%s" % (billboardType, cfgID, zoneID, templateID))
        return
    # 结算时排序并保存榜单数据流向
    billboardObj.SortData()
    GameWorld.Log("结算跨服Boss凭证个人排行奖励: billboardType=%s,cfgID=%s,zoneID=%s,templateID=%s,billboardDataCount=%s"
                  % (billboardType, cfgID, zoneID, templateID, billboardDataCount))
    orderIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", templateID)
    if not orderIpyDataList:
        return
    rankPre = 0
    billboardIndex = 0
    for ipyData in orderIpyDataList:
        rank = ipyData.GetRank()
        awardItemList = ipyData.GetAwardItemList()
        orderCountTotal = rank - rankPre # 奖励名次数量
        rankPre = rank
        orderCount = 0
        for index in xrange(billboardIndex, billboardDataCount):
            if orderCount >= orderCountTotal:
                break
            billboardData = billboardObj.At(index)
            playerID = billboardData.ID
            name2 = billboardData.Name2
            cmpValue = billboardData.CmpValue
            playerRank = index + 1
            GameWorld.Log("    发放boss历练个人榜单奖励: rank=%s,playerID=%s,cmpValue=%s,awardItemList=%s, %s"
                          % (rank, playerID, cmpValue, awardItemList, name2))
            PlayerCompensation.SendMailByKey("BossTrialCrossPlayer", [playerID], awardItemList, [playerRank], crossMail=True)
            orderCount += 1
            billboardIndex += 1
    # 结算完备份、清除榜单数据
    CrossBillboard.CopyBillboard(billboardType, ShareDefine.Def_CBT_BossTrialSubmitBak)
    billboardObj.ClearData()
    return
def __GiveCrossOrderAwardFamily(cfgID, zoneID, templateID):
    groupValue1 = zoneID
    billboardType = ShareDefine.Def_CBT_BossTrialSubmitFamily
    billboardMgr = PyDataManager.GetCrossBillboardManager()
    billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1)
    billboardDataCount = billboardObj.GetCount()
    if not billboardDataCount:
        GameWorld.Log("跨服Boss凭证仙盟排行数据为空! billboardType=%s,cfgID=%s,zoneID=%s,templateID=%s" % (billboardType, cfgID, zoneID, templateID))
        return
    # 结算时排序并保存榜单数据流向
    billboardObj.SortData()
    GameWorld.Log("结算跨服Boss凭证仙盟排行奖励: billboardType=%s,cfgID=%s,zoneID=%s,templateID=%s,billboardDataCount=%s"
                  % (billboardType, cfgID, zoneID, templateID, billboardDataCount))
    orderIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActBossTrialTemplate", templateID)
    if not orderIpyDataList:
        return
    awardFamilyList = []
    rankPre = 0
    billboardIndex = 0
    for ipyData in orderIpyDataList:
        rank = ipyData.GetRank()
        leaderAwardItemList = ipyData.GetAwardItemList()
        memAwardItemList = ipyData.GetMemAwardItemList()
        orderCountTotal = rank - rankPre # 奖励名次数量
        rankPre = rank
        orderCount = 0
        for index in xrange(billboardIndex, billboardDataCount):
            if orderCount >= orderCountTotal:
                break
            billboardData = billboardObj.At(index)
            familyID = billboardData.ID
            familySubmitTotal = billboardData.CmpValue
            familyRank = index + 1
            GameWorld.Log("    familyID=%s,名次=%s,总提交个数=%s" % (familyID, familyRank, familySubmitTotal))
            awardFamilyList.append([familyID, familyRank, familySubmitTotal, leaderAwardItemList, memAwardItemList])
            orderCount += 1
            billboardIndex += 1
    # 广播子服发放奖励
    sendMsg = {"cfgID":cfgID, "zoneID":zoneID, "templateID":templateID, "awardFamilyList":awardFamilyList}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossBossTrialFamilyAward, sendMsg)
    # 结算完备份、清除榜单数据
    CrossBillboard.CopyBillboard(billboardType, ShareDefine.Def_CBT_BossTrialSubmitFamilyBak)
    billboardObj.ClearData()
    return