ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
@@ -20,6 +20,7 @@
import IpyGameDataPY
import NetPackCommon
import PyGameDataStruct
import PlayerFBHelpBattle
import ChPyNetSendPack
import PlayerControl
import PlayerFamily
@@ -36,6 +37,62 @@
AssistType_Boss, # boss
AssistType_TeamFB, # 组队副本
) = range(3)
def RemoveOutofdateAssistThanks():
    ## 移除过期的未完结感谢数据
    timeoutDate = GameWorld.GetDatetimeByDiffDays(-7)
    assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager()
    maxDoCount = len(assistThanksMgr.allAssistThanksList)
    syncPlayerIDList = []
    removeCountTotal, delNoThanksCount, delUnGetThanksCount = 0, 0, 0
    doCount = 0
    while doCount < maxDoCount and assistThanksMgr.allAssistThanksList:
        doCount += 1
        thanks = assistThanksMgr.allAssistThanksList[0]
        thanksDate = GameWorld.ChangeStrToDatetime(thanks.TimeStr)
        if thanksDate > timeoutDate:
            break
        removeCountTotal += 1
        # 移除过期的感谢数据
        popThanks = assistThanksMgr.allAssistThanksList.pop(0)
        playerID = popThanks.PlayerID
        GUID = popThanks.GUID
        assistPlayerIDList = popThanks.AssistPlayerDict.keys()
        if playerID in assistThanksMgr.playerThanksDict:
            playerThanksList = assistThanksMgr.playerThanksDict[playerID]
            for i, thanks in enumerate(playerThanksList):
                if GUID == thanks.GUID:
                    delNoThanksCount += 1
                    playerThanksList.pop(i)
                    #GameWorld.DebugLog("    移除未感谢的数据: i=%s,GUID=%s,len=%s" % (i, thanks.GUID, len(playerThanksList)))
                    break
        for assistPlayerID in assistPlayerIDList:
            if assistPlayerID not in assistThanksMgr.assistPlayerThanksDict:
                continue
            assistThanksList = assistThanksMgr.assistPlayerThanksDict[assistPlayerID]
            for i, thanks in enumerate(assistThanksList):
                if GUID == thanks.GUID:
                    delUnGetThanksCount += 1
                    assistThanksList.pop(i)
                    #GameWorld.DebugLog("    移除未接受感谢的数据: i=%s,GUID=%s,assistPlayerID=%s,len=%s" % (i, thanks.GUID, assistPlayerID, len(assistThanksList)))
                    if assistPlayerID not in syncPlayerIDList:
                        syncPlayerIDList.append(assistPlayerID)
                    break
    playerMgr = GameWorld.GetPlayerManager()
    for playerID in syncPlayerIDList:
        assistPlayer = playerMgr.FindPlayerByID(playerID)
        if assistPlayer:
            SyncCanGetAssistThanksGiftCount(assistPlayer, isForce=True)
    if removeCountTotal:
        GameWorld.DebugLog("移除过期的未完结感谢数据: doCount=%s,maxDoCount=%s,removeCountTotal=%s,delNoThanksCount=%s,delUnGetThanksCount=%s,remainCount=%s"
                           % (doCount, maxDoCount, removeCountTotal, delNoThanksCount, delUnGetThanksCount, len(assistThanksMgr.allAssistThanksList)))
    return
def OnPlayerLogin(curPlayer, isTJ=False):
@@ -144,6 +201,25 @@
        
    return
def OnPlayerTeamChange(curPlayer):
    ## 玩家队伍变更
    if curPlayer.GetTeamID():
        return
    playerID = curPlayer.GetPlayerID()
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if playerID not in assistMgr.playerNoSaveDBAssistDict:
        return
    playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
    for assistObj in playerAssistList[::-1]:
        gameMap = GameWorld.GetMap(assistObj.MapID)
        if gameMap and gameMap.GetMapFBType() == ChConfig.fbtTeam:
            OnCancelPlayerRequestAssist(assistObj, "LeaveTeam", True)
    return
def OnInitAssistData(dbData, isSaveDB):
    ## 加载协助数据额外处理
    setattr(dbData, "IsSaveDB", isSaveDB) # 是否保存数据库,离线可协助的需要存库,如挖矿类
@@ -176,17 +252,15 @@
        playerThanksList = thanksMgr.playerThanksDict[playerID]
        playerThanksList.append(dbData)
        
    # 已经感谢的
    else:
        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)
    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
@@ -230,7 +304,10 @@
    if not playerMap:
        return
    if playerMap.GetMapFBType() != ChConfig.fbtNull:
        playerLineID = curPlayer.GetFBID()
        if mapID == ChConfig.Def_FBMapID_SealDemon:
            playerLineID = PlayerControl.GetFBFuncLineID(curPlayer)
        else:
            playerLineID = curPlayer.GetFBID()
        if playerMapID != mapID or playerLineID != lineID:
            #副本中无法协助
            PlayerControl.NotifyCode(curPlayer, "AssistFBLimit")
@@ -336,13 +413,6 @@
    NetPackCommon.SendFakePack(assistPlayer, assistPack)
    return
def SetPlayerStartAssistTeamFB(curPlayer, queryData):
    ## 开始协助组队副本 - 玩家进入副本后才真正进入协助状态
    #mapID, lineID, tagPlayerID = queryData
    return
def MapServer_PlayerAssistLogic(curPlayer, msgList, tick):
    ## 地图同步的协助信息逻辑处理
    
@@ -390,6 +460,11 @@
        __DoBossAssistOver(queryData)
        return
    
    # 副本协助结束
    elif queryType == "OnFBAssistOver":
        __DoFBAssistOver(queryData)
        return
    ## -------------------------------------------------------------------------------------------
    
    # 请求协助组队副本
@@ -399,7 +474,18 @@
    
    # 开始协助组队副本
    elif queryType == "OnStartAssistTeamFB":
        SetPlayerStartAssistTeamFB(curPlayer, queryData)
        mapID, lineID, tagPlayerID = queryData
        GameWorld.DebugLog("    开始协助副本: mapID=%s,lineID=%s,tagPlayerID=%s" % (mapID, lineID, tagPlayerID), playerID)
        # 副本协助暂时只处理设置协助目标ID
        PlayerControl.SetAssistTagPlayerID(curPlayer, tagPlayerID)
        return
    # 取消协助组队副本
    elif queryType == "OnCancelAssistTeamFB":
        mapID, lineID, reason = queryData
        GameWorld.DebugLog("    开始协助副本: mapID=%s,lineID=%s,reason=%s" % (mapID, lineID, reason), playerID)
        # 副本协助暂时只处理设置协助目标ID
        PlayerControl.SetAssistTagPlayerID(curPlayer, 0)
        return
    
    #QueryPlayerResult_PlayerAssist(curPlayer, queryType, queryData, result)
@@ -419,12 +505,12 @@
    familyID = curPlayer.GetFamilyID()
    if not familyID:
        return
    mapID, lineID, npcID, objID = queryData
    mapID, lineID, npcID, objID, npcLV = queryData
    
    playerID = curPlayer.GetPlayerID()
    
    assistObj = None
    addNewAssist = True
    reqAssistObj = None
    addNewAssist = False
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if playerID in assistMgr.playerNoSaveDBAssistDict:
        playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
@@ -434,19 +520,28 @@
            if npcID != assistObj.NPCID or lineID != assistObj.LineID or objID != assistObj.ObjID:
                OnCancelPlayerRequestAssist(assistObj, "RequestNewAssistBoss", True)
            else:
                addNewAssist = False
                reqAssistObj = assistObj
            break
        
    if addNewAssist:
        assistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID, objID)
    if not reqAssistObj:
        addNewAssist = True
        reqAssistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID, objID)
        
    if not assistObj:
    if not reqAssistObj:
        return
    
    # 通知本仙盟玩家
    PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([assistObj]))
    PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([reqAssistObj]))
    # 求助信息已发送,请等待盟友支援
    PlayerControl.NotifyCode(curPlayer, "AssistRequestOK")
    # 广播仙盟请求
    requestCount = 1
    if not addNewAssist:
        requestCount = min(curPlayer.GetDictByKey("AssistBossRequestCount") + 1, 999)
    curPlayer.SetDict("AssistBossRequestCount", requestCount)
    notifyNum = (requestCount - 1) % 3
    PlayerControl.FamilyNotify(familyID, "AssistBossRequest%s" % notifyNum, [curPlayer.GetName(), mapID, npcLV, npcID])
    return
def __DoRequestAssistTeamFB(curPlayer, queryData):
@@ -459,7 +554,7 @@
    
    playerID = curPlayer.GetPlayerID()
    
    assistObj = None
    reqAssistObj = None
    addNewAssist = False
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if playerID in assistMgr.playerNoSaveDBAssistDict:
@@ -469,21 +564,28 @@
                continue
            if mapID != assistObj.MapID or lineID != assistObj.LineID:
                OnCancelPlayerRequestAssist(assistObj, "RequestNewAssistTeamFB", True)
                addNewAssist = True
                break
    else:
            else:
                reqAssistObj = assistObj
            break
    if not reqAssistObj:
        addNewAssist = True
        reqAssistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID)
        
    if addNewAssist:
        assistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID)
    if not assistObj:
    if not reqAssistObj:
        return
    
    # 通知本仙盟玩家
    PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([assistObj]))
    PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([reqAssistObj]))
    # 求助信息已发送,请等待盟友支援
    PlayerControl.NotifyCode(curPlayer, "AssistRequestOK")
    # 广播仙盟请求
    requestCount = 1
    if not addNewAssist:
        requestCount = min(curPlayer.GetDictByKey("AssistFBRequestCount") + 1, 999)
    curPlayer.SetDict("AssistFBRequestCount", requestCount)
    notifyNum = (requestCount - 1) % 3
    PlayerControl.FamilyNotify(familyID, "AssistFBRequest%s" % notifyNum, [curPlayer.GetName(), mapID])
    return
def __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID=0, objID=0, exData="", isSaveDB=0):
@@ -532,6 +634,7 @@
    for assistObj in familyAssistList:
        assistInfo = ChPyNetSendPack.tagGCAssistInfo()
        assistInfo.AssistGUID = assistObj.GUID
        assistInfo.PlayerID = assistObj.PlayerID
        assistInfo.PlayerName = assistObj.PlayerName
        assistInfo.Job = assistObj.Job
        assistInfo.LV = assistObj.LV
@@ -587,8 +690,6 @@
        if assistObj in playerAssistList:
            playerAssistList.remove(assistObj)
            
    SyncFamilyClearAssist(familyID, assistGUID)
    # 取消boss协助
    if assistType == AssistType_Boss:
        
@@ -609,6 +710,8 @@
        # 暂不需要处理
        pass
    
    # 放最后
    SyncFamilyClearAssist(familyID, assistGUID)
    return
def OnCancelPlayerAssist(cancelPlayer, cancelPlayerID, assistObj, reason, isGameServer, isNotify=True):
@@ -644,7 +747,14 @@
        assistObj.AssistPlayerIDList.remove(cancelPlayerID)
        
    if cancelPlayer:
        isTagPlayerReason = reason.startswith("RequestPlayerCancel_")
        PlayerControl.SetAssistTagPlayerID(cancelPlayer, 0)
        overPack = ChPyNetSendPack.tagGCAssistOver()
        overPack.IsTagPlayerReason = isTagPlayerReason
        overPack.Reason = reason[len("RequestPlayerCancel_"):] if isTagPlayerReason else reason
        overPack.ReasonLen = len(overPack.Reason)
        overPack.AssistGUID = assistGUID
        NetPackCommon.SendFakePack(cancelPlayer, overPack)
        
    # 取消boss协助
    if assistObj.AssistType == AssistType_Boss:
@@ -679,7 +789,7 @@
                OnCancelPlayerRequestAssist(assistObj, "BossAssistOver", False)
                break
                
    if not assistAwardResult:
    if not assistAwardItemID or not assistAwardResult:
        return
    
    # 新增感谢数据
@@ -688,11 +798,33 @@
        curPlayer = playerMgr.FindPlayerByID(playerID)
        if not curPlayer:
            continue
        __AddAssistThanks(curPlayer, assistAwardItemID, mapID, lineID, assistPlayerDict, npcID)
        AddNewAssistThanks(curPlayer, assistAwardItemID, mapID, lineID, assistPlayerDict, npcID)
        
    return
def __AddAssistThanks(curPlayer, itemID, mapID, lineID, assistPlayerDict, npcID=0, exData=""):
def __DoFBAssistOver(queryData):
    ## 副本协助结束
    mapID, lineID, noAssistPlayerID, assistAwardItemID, assistPlayerDict = queryData
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if noAssistPlayerID not in assistMgr.playerNoSaveDBAssistDict:
        return
    playerAssistList = assistMgr.playerNoSaveDBAssistDict[noAssistPlayerID]
    for assistObj in playerAssistList:
        if assistObj.MapID == mapID and assistObj.LineID == lineID:
            OnCancelPlayerRequestAssist(assistObj, "FBAssistOver", False)
            break
    if not assistAwardItemID or not assistPlayerDict:
        return
    # 新增感谢数据
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(noAssistPlayerID)
    if curPlayer:
        AddNewAssistThanks(curPlayer, assistAwardItemID, mapID, lineID, assistPlayerDict)
    return
def AddNewAssistThanks(curPlayer, itemID, mapID, lineID, assistPlayerDict, npcID=0, exData=""):
    ## 添加协助感谢数据
    
    playerID = curPlayer.GetPlayerID()
@@ -718,7 +850,7 @@
    assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager()
    OnInitAssistThanksData(assistThanksMgr, newThanks)
    
    GameWorld.DebugLog("增加协助感谢: mapID=%s,lineID=%s,npcID=%s,exData=%s" % (mapID, lineID, npcID, exData), playerID)
    GameWorld.DebugLog("增加协助感谢: itemID=%s,mapID=%s,lineID=%s,npcID=%s,exData=%s" % (itemID, mapID, lineID, npcID, exData), playerID)
    return
#// B0 14 使用协助感谢礼盒 #tagCGUseAssistThanksGift
@@ -737,23 +869,29 @@
    
    playerID = curPlayer.GetPlayerID()
    assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager()
    useThanks = None
    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
    else:
        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
        #20210226 优化为找不到协助信息也可以使用,防止地图扣除物品失败导致协助礼盒一直留着而无法使用
        #return
    
    GameWorld.DebugLog("玩家使用协助感谢礼盒!itemID=%s,isPreview=%s" % (itemID, isPreview), playerID)
    # 预览
    if isPreview:
        previewPack = ChPyNetSendPack.tagGCUseAssistThanksGiftPreview()
        if not useThanks:
            previewPack.ItemID = itemID
            previewPack.MapID = 31140 # 暂随意给一个可协助的地图ID
            NetPackCommon.SendFakePack(curPlayer, previewPack)
            return
        previewPack.ItemID = useThanks.ItemID
        previewPack.MapID = useThanks.MapID
        previewPack.LineID = useThanks.LineID
@@ -778,22 +916,21 @@
    ipyData = IpyGameDataPY.GetIpyGameData("AssistThanksGift", itemID)
    if not ipyData:
        return
    useThanks.ThanksState = 1 # 设置为已感谢
    playerThanksList.remove(useThanks) # 移除已感谢
    queryData = [itemID]
    QueryPlayerResult_PlayerAssist(curPlayer, "UseAssistThanksGift", queryData)
    
    # 加入协助玩家接收感谢列表
    if not useThanks:
        return
    useThanks.ThanksState = 1 # 设置为已感谢
    playerThanksList.remove(useThanks) # 移除已感谢
    # 通知协助玩家可接收的感谢个数
    playerMgr = GameWorld.GetPlayerManager()
    for assistPlayerID in useThanks.AssistPlayerDict.keys():
        if assistPlayerID not in assistThanksMgr.assistPlayerThanksDict:
            assistThanksMgr.assistPlayerThanksDict[assistPlayerID] = []
        assistPlayerThanksList = assistThanksMgr.assistPlayerThanksDict[assistPlayerID]
        assistPlayerThanksList.append(useThanks)
        assistPlayer = playerMgr.FindPlayerByID(assistPlayerID)
        if assistPlayer:
            SyncCanGetAssistThanksGiftCount(assistPlayer, len(assistPlayerThanksList))
            SyncCanGetAssistThanksGiftCount(assistPlayer)
    return
#// B0 15 接收协助感谢礼物 #tagCGGetAssistThanksGift
@@ -814,9 +951,14 @@
        GameWorld.ErrLog("玩家没有可接收感谢的协助感谢礼盒!", playerID)
        return
    assistPlayerThanksList = assistThanksMgr.assistPlayerThanksDict[playerID]
    if not assistPlayerThanksList:
    getThanks = None
    for thanks in assistPlayerThanksList:
        if thanks.ThanksState:
            getThanks = thanks
            break
    if not getThanks:
        GameWorld.ErrLog("找不到玩家可接收感谢的协助感谢礼盒!", playerID)
        return
    getThanks = assistPlayerThanksList[0] # 默认接收第一个
    itemID = getThanks.ItemID
    ipyData = IpyGameDataPY.GetIpyGameData("AssistThanksGift", itemID)
    if not ipyData:
@@ -862,7 +1004,7 @@
        if getThanks in assistThanksMgr.allAssistThanksList:
            assistThanksMgr.allAssistThanksList.remove(getThanks)
            
    assistPlayerThanksList.pop(0) # 移除
    assistPlayerThanksList.remove(getThanks) # 移除
    
    updateTodayGiftCount = todayGiftCount + 1
    # 更新当天该礼盒ID已领取次数
@@ -874,25 +1016,36 @@
        assistPlayerInfoDict = thanks.AssistPlayerDict[playerID]
        assistPlayerInfoDict["TodayGiftCount"] = updateTodayGiftCount
        
    SyncCanGetAssistThanksGiftCount(curPlayer, len(assistPlayerThanksList))
    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, canGetCount=None):
def SyncCanGetAssistThanksGiftCount(curPlayer, isForce=False):
    ## 通知可接收协助感谢礼物个数
    if canGetCount == None:
        playerID = curPlayer.GetPlayerID()
        assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager()
        if playerID not in assistThanksMgr.assistPlayerThanksDict:
            return
        assistPlayerThanksList = assistThanksMgr.assistPlayerThanksDict[playerID]
        if not assistPlayerThanksList:
            return
        canGetCount = len(assistPlayerThanksList)
    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)