ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
@@ -15,9 +15,12 @@
#"""Version = 2019-12-06 21:00"""
#-------------------------------------------------------------------------------
import PlayerFriend
import PyDataManager
import IpyGameDataPY
import NetPackCommon
import PyGameDataStruct
import PlayerFBHelpBattle
import ChPyNetSendPack
import PlayerControl
import PlayerFamily
@@ -39,6 +42,8 @@
def OnPlayerLogin(curPlayer, isTJ=False):
    ## 玩家上线
    # @param isTJ: 是否脱机上线
    SyncCanGetAssistThanksGiftCount(curPlayer)
    
    familyID = curPlayer.GetFamilyID()
    playerID = curPlayer.GetPlayerID()
@@ -157,6 +162,39 @@
    setattr(dbData, "AssistPlayerIDList", []) # 协助中的玩家ID列表
    return
def OnInitAssistThanksData(thanksMgr, dbData):
    ## 初始化协助感谢数据额外处理
    setattr(dbData, "AssistPlayerDict", {})
    if dbData.AssistPlayer and dbData.AssistPlayer.startswith("{") and dbData.AssistPlayer.endswith("}"):
        dbData.AssistPlayerDict = eval(dbData.AssistPlayer)
    thanksMgr.allAssistThanksList.append(dbData)
    # 未感谢的
    if not dbData.ThanksState:
        playerID = dbData.PlayerID
        if playerID not in thanksMgr.playerThanksDict:
            thanksMgr.playerThanksDict[playerID] = []
        playerThanksList = thanksMgr.playerThanksDict[playerID]
        playerThanksList.append(dbData)
    for assistPlayerID, assistPlayerInfo in dbData.AssistPlayerDict.items():
        if "IsGet" in assistPlayerInfo:
            # 已经接受感谢奖励的不再处理
            continue
        if assistPlayerID not in thanksMgr.assistPlayerThanksDict:
            thanksMgr.assistPlayerThanksDict[assistPlayerID] = []
        assistPlayerThanksList = thanksMgr.assistPlayerThanksDict[assistPlayerID]
        assistPlayerThanksList.append(dbData)
    return
def OnSaveAssistThanksData(dbData):
    ## 协助感谢保存数据额外处理
    dbData.AssistPlayer = str(dbData.AssistPlayerDict)
    dbData.AssistPlayerLen = len(dbData.AssistPlayer)
    return
#// B0 12 开始协助Boss #tagCGStartAssistBoss
#
#struct    tagCGStartAssistBoss
@@ -184,21 +222,24 @@
        GameWorld.DebugLog("非同盟玩家不能协助!")
        return
    
    playerMapID = curPlayer.GetMapID()
    mapID = assistObj.MapID
    lineID = assistObj.LineID
    gameMap = GameWorld.GetMap(mapID)
    if not gameMap:
    playerMap = GameWorld.GetMap(playerMapID)
    if not playerMap:
        return
    if gameMap.GetMapFBType() != ChConfig.fbtNull:
        playerMapID = curPlayer.GetMapID()
        playerLineID = PlayerControl.GetFBFuncLineID(curPlayer)
    if playerMap.GetMapFBType() != ChConfig.fbtNull:
        playerLineID = curPlayer.GetFBID()
        if playerMapID != mapID or playerLineID != lineID:
            #副本中无法协助
            PlayerControl.NotifyCode(curPlayer, "AssistFBLimit")
            return
        
    # 设定协助必须离开队伍
    if gameMap.GetMapFBType() != ChConfig.fbtTeam:
    tagMap = GameWorld.GetMap(mapID)
    if not tagMap:
        return
    if tagMap.GetMapFBType() != ChConfig.fbtTeam:
        curTeam = curPlayer.GetTeam()
        if curTeam:
            PlayerTeam.DoPlayerLeaveTeam(curPlayer, curTeam, tick)
@@ -277,7 +318,8 @@
    
    tagPlayerName = tagPlayer.GetName()
    tagTeamID = tagPlayer.GetTeamID()
    assistData = [mapID, "Start", assistGUID, assistPlayerID, assistPlayerName, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID]
    isFriend = PlayerFriend.IsFriend(assistPlayerID, tagPlayerID)
    assistData = [mapID, "Start", assistGUID, assistPlayerID, assistPlayerName, isFriend, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID]
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_AssistBoss, assistData)
    return
@@ -322,17 +364,16 @@
    
    # 取消boss协助发布
    elif queryType == "OnCancelBossRequestAssist":
        mapID, lineID, npcID, objID, reason, cancelPlayerIDList = queryData
        mapID, lineID, npcID, objID, reason = queryData
        assistMgr = PyDataManager.GetPlayerAssistPyManager()
        for cancelPlayerID in cancelPlayerIDList:
            if cancelPlayerID in assistMgr.playerNoSaveDBAssistDict:
                playerAssistList = assistMgr.playerNoSaveDBAssistDict[cancelPlayerID]
                for assistObj in playerAssistList:
                    if assistObj.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID:
                        OnCancelPlayerRequestAssist(assistObj, reason, False)
                        break
        if playerID in assistMgr.playerNoSaveDBAssistDict:
            playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
            for assistObj in playerAssistList:
                if assistObj.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID:
                    OnCancelPlayerRequestAssist(assistObj, reason, False)
                    break
        return
    # 取消协助Boss
    elif queryType == "OnCancelBossAssist":
        mapID, lineID, npcID, objID, reason = queryData
@@ -341,6 +382,11 @@
            assistObj = assistMgr.playerAssistingDict[playerID]
            if assistObj.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID:
                OnCancelPlayerAssist(curPlayer, playerID, assistObj, reason, False)
        return
    # boss协助结束
    elif queryType == "OnBossAssistOver":
        __DoBossAssistOver(queryData)
        return
    
    ## -------------------------------------------------------------------------------------------
@@ -358,13 +404,13 @@
    #QueryPlayerResult_PlayerAssist(curPlayer, queryType, queryData, result)
    return
#def QueryPlayerResult_PlayerAssist(curPlayer, queryType, queryData, result=[]):
#    if not curPlayer:
#        return
#    resultMsg = str([queryType, queryData, result])
#    curPlayer.MapServer_QueryPlayerResult(0, 0, "PlayerAssist", resultMsg, len(resultMsg))
#    GameWorld.DebugLog("协助信息发送 MapServer: playerID=%s,queryType=%s,queryData=%s" % (curPlayer.GetPlayerID(), queryType, queryData))
#    return
def QueryPlayerResult_PlayerAssist(curPlayer, queryType, queryData, result=[]):
    if not curPlayer:
        return
    resultMsg = str([queryType, queryData, result])
    curPlayer.MapServer_QueryPlayerResult(0, 0, "PlayerAssist", resultMsg, len(resultMsg))
    GameWorld.DebugLog("协助信息发送 MapServer: playerID=%s,queryType=%s,queryData=%s" % (curPlayer.GetPlayerID(), queryType, queryData))
    return
def __DoRequestAssistBoss(curPlayer, queryData):
    ## 请求协助Boss
@@ -619,6 +665,61 @@
    
    return
def __DoBossAssistOver(queryData):
    ## boss协助结束,一般是boss被击杀 或 被系统
    mapID, lineID, npcID, objID, noAssistPlayerIDList, assistAwardItemID, assistAwardResult = queryData
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    for noAssistPlayerID in noAssistPlayerIDList:
        if noAssistPlayerID not in assistMgr.playerNoSaveDBAssistDict:
            continue
        playerAssistList = assistMgr.playerNoSaveDBAssistDict[noAssistPlayerID]
        for assistObj in playerAssistList:
            if assistObj.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID:
                OnCancelPlayerRequestAssist(assistObj, "BossAssistOver", False)
                break
    if not assistAwardResult:
        return
    # 新增感谢数据
    playerMgr = GameWorld.GetPlayerManager()
    for playerID, assistPlayerDict in assistAwardResult.items():
        curPlayer = playerMgr.FindPlayerByID(playerID)
        if not curPlayer:
            continue
        AddNewAssistThanks(curPlayer, assistAwardItemID, mapID, lineID, assistPlayerDict, npcID)
    return
def AddNewAssistThanks(curPlayer, itemID, mapID, lineID, assistPlayerDict, npcID=0, exData=""):
    ## 添加协助感谢数据
    playerID = curPlayer.GetPlayerID()
    newThanks = PyGameDataStruct.tagDBAssistThanks()
    newThanks.GUID = str(uuid.uuid1())
    newThanks.ItemID = itemID
    newThanks.FamilyID = curPlayer.GetFamilyID()
    newThanks.PlayerID = playerID
    newThanks.PlayerName = curPlayer.GetName()
    newThanks.Job = curPlayer.GetJob()
    newThanks.LV = curPlayer.GetLV()
    newThanks.RealmLV = curPlayer.GetOfficialRank()
    newThanks.MapID = mapID
    newThanks.LineID = lineID
    newThanks.NPCID = npcID
    newThanks.ExData = exData
    newThanks.ExDataLen = len(exData)
    newThanks.DailyDateStr = GameWorld.GetDailyDateStr()
    newThanks.TimeStr = GameWorld.GetCurrentDataTimeStr()
    newThanks.AssistPlayer = str(assistPlayerDict)
    newThanks.AssistPlayerLen = len(newThanks.AssistPlayer)
    assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager()
    OnInitAssistThanksData(assistThanksMgr, newThanks)
    GameWorld.DebugLog("增加协助感谢: itemID=%s,mapID=%s,lineID=%s,npcID=%s,exData=%s" % (itemID, mapID, lineID, npcID, exData), playerID)
    return
#// B0 14 使用协助感谢礼盒 #tagCGUseAssistThanksGift
#
#struct    tagCGUseAssistThanksGift
@@ -626,27 +727,188 @@
#{
#    tagHead        Head;
#    DWORD        ItemID;
#    char        GiftGUID[40];    //预览时GUID不发,确认使用时需发送预览返回的GUID
#    BYTE        IsPreview;    //是否预览,非预览即确认使用
#};
def OnUseAssistThanksGift(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    itemID = clientData.ItemID
    giftGUID = clientData.GiftGUID
    isPreview = clientData.IsPreview
    playerID = curPlayer.GetPlayerID()
    assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager()
    if playerID not in assistThanksMgr.playerThanksDict:
        GameWorld.ErrLog("玩家没有可使用的协助感谢礼盒!", playerID)
        return
    useThanks = None
    playerThanksList = assistThanksMgr.playerThanksDict[playerID]
    for thanks in playerThanksList:
        if itemID == thanks.ItemID:
            useThanks = thanks
            break
    if not useThanks:
        GameWorld.ErrLog("玩家没有该协助感谢礼盒!itemID=%s" % (itemID), playerID)
        return
    GameWorld.DebugLog("玩家使用协助感谢礼盒!itemID=%s,isPreview=%s" % (itemID, isPreview), playerID)
    # 预览
    if isPreview:
        previewPack = ChPyNetSendPack.tagGCUseAssistThanksGiftPreview()
        previewPack.ItemID = useThanks.ItemID
        previewPack.MapID = useThanks.MapID
        previewPack.LineID = useThanks.LineID
        previewPack.NPCID = useThanks.NPCID
        previewPack.ExData = useThanks.ExData
        previewPack.ExDataLen = useThanks.ExDataLen
        previewPack.AssistPlayerList = []
        for assistPlayerID, assistPlayerInfoDict in useThanks.AssistPlayerDict.items():
            if "PlayerName" not in assistPlayerInfoDict:
                continue
            assistPlayerInfo = ChPyNetSendPack.tagGCAssistPlayerInfo()
            assistPlayerInfo.PlayerID = assistPlayerID
            assistPlayerInfo.PlayerName = assistPlayerInfoDict["PlayerName"]
            assistPlayerInfo.Job = assistPlayerInfoDict["Job"]
            assistPlayerInfo.LV = assistPlayerInfoDict["LV"]
            assistPlayerInfo.RealmLV = assistPlayerInfoDict["RealmLV"]
            previewPack.AssistPlayerList.append(assistPlayerInfo)
        previewPack.AssistPlayerCount = len(previewPack.AssistPlayerList)
        NetPackCommon.SendFakePack(curPlayer, previewPack)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("AssistThanksGift", itemID)
    if not ipyData:
        return
    useThanks.ThanksState = 1 # 设置为已感谢
    playerThanksList.remove(useThanks) # 移除已感谢
    queryData = [itemID]
    QueryPlayerResult_PlayerAssist(curPlayer, "UseAssistThanksGift", queryData)
    # 通知协助玩家可接收的感谢个数
    playerMgr = GameWorld.GetPlayerManager()
    for assistPlayerID in useThanks.AssistPlayerDict.keys():
        assistPlayer = playerMgr.FindPlayerByID(assistPlayerID)
        if assistPlayer:
            SyncCanGetAssistThanksGiftCount(assistPlayer)
    return
#// B0 15 领取协助感谢礼物 #tagCGGetAssistThanksGift
#// B0 15 接收协助感谢礼物 #tagCGGetAssistThanksGift
#
#struct    tagCGGetAssistThanksGift
#
#{
#    tagHead        Head;
#    char        GiftGUID[40];    //礼盒GUID
#    BYTE        IsPreview;    //是否预览,非预览即确认领取,无额外奖励确认时也需要回复领取包代表已读
#};
def OnGetAssistThanksGift(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    giftGUID = clientData.GiftGUID
    isPreview = clientData.IsPreview
    playerID = curPlayer.GetPlayerID()
    assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager()
    if playerID not in assistThanksMgr.assistPlayerThanksDict:
        GameWorld.ErrLog("玩家没有可接收感谢的协助感谢礼盒!", playerID)
        return
    assistPlayerThanksList = assistThanksMgr.assistPlayerThanksDict[playerID]
    getThanks = None
    for thanks in assistPlayerThanksList:
        if thanks.ThanksState:
            getThanks = thanks
            break
    if not getThanks:
        GameWorld.ErrLog("找不到玩家可接收感谢的协助感谢礼盒!", playerID)
        return
    itemID = getThanks.ItemID
    ipyData = IpyGameDataPY.GetIpyGameData("AssistThanksGift", itemID)
    if not ipyData:
        return
    if playerID not in getThanks.AssistPlayerDict:
        return
    assistPlayerInfoDict = getThanks.AssistPlayerDict[playerID]
    todayGiftCount = assistPlayerInfoDict.get("TodayGiftCount", 0) # 该礼盒当日已领取额外奖励次数
    isExtraAward = 1 if todayGiftCount < ipyData.GetAssistAwardCount() else 0
    GameWorld.DebugLog("接收协助感谢礼物: itemID=%s,isPreview=%s,isExtraAward=%s,DailyDateStr=%s"
                       % (itemID, isPreview, isExtraAward, getThanks.DailyDateStr), playerID)
    # 预览
    if isPreview:
        previewPack = ChPyNetSendPack.tagGCGetAssistThanksGiftPreview()
        previewPack.ItemID = getThanks.ItemID
        previewPack.PlayerID = getThanks.PlayerID
        previewPack.PlayerName = getThanks.PlayerName
        previewPack.Job = getThanks.Job
        previewPack.LV = getThanks.LV
        previewPack.RealmLV = getThanks.RealmLV
        previewPack.MapID = getThanks.MapID
        previewPack.LineID = getThanks.LineID
        previewPack.NPCID = getThanks.NPCID
        previewPack.ExData = getThanks.ExData
        previewPack.ExDataLen = len(getThanks.ExData)
        previewPack.TimeStr = getThanks.TimeStr
        previewPack.ExtraAward = isExtraAward
        NetPackCommon.SendFakePack(curPlayer, previewPack)
        return
    assistPlayerInfoDict["IsGet"] = 1
    isAllGet = True
    for playerDict in getThanks.AssistPlayerDict.values():
        if "IsGet" not in playerDict:
            isAllGet = False
            break
    # 所有人都接收感谢了,删除该协助感谢数据
    if isAllGet:
        GameWorld.DebugLog("    所有人都感谢了,移除该协助感谢!", playerID)
        if getThanks in assistThanksMgr.allAssistThanksList:
            assistThanksMgr.allAssistThanksList.remove(getThanks)
    assistPlayerThanksList.remove(getThanks) # 移除
    updateTodayGiftCount = todayGiftCount + 1
    # 更新当天该礼盒ID已领取次数
    for thanks in assistPlayerThanksList:
        if getThanks.DailyDateStr != thanks.DailyDateStr or getThanks.ItemID != thanks.ItemID:
            continue
        if playerID not in thanks.AssistPlayerDict:
            continue
        assistPlayerInfoDict = thanks.AssistPlayerDict[playerID]
        assistPlayerInfoDict["TodayGiftCount"] = updateTodayGiftCount
    SyncCanGetAssistThanksGiftCount(curPlayer, True)
    isCurDailyDate = getThanks.DailyDateStr == GameWorld.GetDailyDateStr()
    # 如果是镜像协助的,更新今日接收感谢礼盒次数
    if isCurDailyDate:
        if IpyGameDataPY.GetIpyGameDataNotLog("FBHelpBattle", getThanks.MapID, getThanks.LineID):
            PlayerFBHelpBattle.UpdateGetThanksGiftCountDict(curPlayer, itemID, updateTodayGiftCount)
    # 通知地图
    queryData = [itemID, isExtraAward, isCurDailyDate, updateTodayGiftCount]
    QueryPlayerResult_PlayerAssist(curPlayer, "GetAssistThanksGift", queryData)
    return
def SyncCanGetAssistThanksGiftCount(curPlayer, isForce=False):
    ## 通知可接收协助感谢礼物个数
    playerID = curPlayer.GetPlayerID()
    assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager()
    if playerID not in assistThanksMgr.assistPlayerThanksDict:
        return
    assistPlayerThanksList = assistThanksMgr.assistPlayerThanksDict[playerID]
    canGetCount = 0
    for thanks in assistPlayerThanksList:
        if thanks.ThanksState:
            canGetCount += 1
    if not canGetCount and not isForce:
        return
    countPack = ChPyNetSendPack.tagGCCanGetAssistThanksGiftCount()
    countPack.CanGetCount = canGetCount
    NetPackCommon.SendFakePack(curPlayer, countPack)
    return
def SyncFamilyAssist(curPlayer):
    ## 同步当前仙盟所有协助请求信息
    familyID = curPlayer.GetFamilyID()