hxp
2024-08-31 44bcd51874e364012946b5f34dd7bb166d86edfb
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
@@ -19,7 +19,9 @@
import PyDataManager
import IpyGameDataPY
import NetPackCommon
import CrossRealmMsg
import PyGameDataStruct
import PlayerFBHelpBattle
import ChPyNetSendPack
import PlayerControl
import PlayerFamily
@@ -29,6 +31,7 @@
import ChConfig
import uuid
import time
# 协助类型
(
@@ -37,91 +40,149 @@
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):
def OnPlayerLoginCrossServer(curPlayer):
    # 跨服登录处理
    playerID = curPlayer.GetPlayerID()
    tagPlayerID = PlayerControl.GetAssistTagPlayerID(curPlayer)
    if tagPlayerID and not GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID):
        serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)
        sendMsg = {"queryType":"ResetPlayerAssist", "queryData":[playerID, tagPlayerID]}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID])
    return
def OnPlayerLogin(curPlayer):
    ## 玩家上线
    # @param isTJ: 是否脱机上线
    
    SyncCanGetAssistThanksGiftCount(curPlayer)
    
    familyID = curPlayer.GetFamilyID()
    playerID = curPlayer.GetPlayerID()
    if not familyID:
        return
    
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if playerID in assistMgr.playerNoSaveDBAssistDict:
        playerNoSaveList = assistMgr.playerNoSaveDBAssistDict[playerID]
    # 将自己发布的重新激活并通知其他玩家
    if playerID in assistMgr.playerAssistDict:
        playerAssistList = assistMgr.playerAssistDict[playerID]
        
        # 非脱机上线
        if not isTJ:
            GameWorld.DebugLog("玩家上线,恢复协助发布到仙盟列表!", playerID)
            if familyID not in assistMgr.familyAssistDict:
                assistMgr.familyAssistDict[familyID] = []
            recoverList = []
            familyAssistList = assistMgr.familyAssistDict[familyID]
            for assistObj in playerNoSaveList:
        serverAssistList, familyAssistList = [], []
        for assistObj in playerAssistList:
            assistObj.OffLineTime = 0 # 设置为非离线
            if not assistObj.FamilyID:
                serverAssistList.append(assistObj)
            elif familyID and familyID == assistObj.FamilyID:
                familyAssistList.append(assistObj)
                recoverList.append(assistObj)
                GameWorld.DebugLog("    恢复: %s" % assistObj.GUID)
                
            if recoverList:
                # 通知本盟其他玩家
                PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack(recoverList), [playerID])
        # 脱机上线
        else:
            GameWorld.DebugLog("玩家脱机上线,强制取消发布的非存库协助!", playerID)
            for assistObj in playerNoSaveList:
                OnCancelPlayerRequestAssist(assistObj, "TJGLogin", True)
    if not isTJ:
        SyncFamilyAssist(curPlayer)
        if familyAssistList:
            PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack(familyAssistList), [playerID])
        if serverAssistList:
            SyncServerAssist(serverAssistList)
    # 全服服务器协助、仙盟协助 通知自己
    syncAssistList = []
    for assistObj in assistMgr.allAssistDict.values():
        if assistObj.OffLineTime:
            continue
        if assistObj.FamilyID and assistObj.FamilyID != familyID:
            continue
        syncAssistList.append(assistObj)
    if syncAssistList:
        NetPackCommon.SendFakePack(curPlayer, GetAssistInfoListPack(syncAssistList))
        
    # 没有协助中的信息
    if playerID in assistMgr.playerAssistingDict:
        assistObj = assistMgr.playerAssistingDict[playerID]
        if not isTJ:
            tagPlayerID = assistObj.PlayerID
            GameWorld.DebugLog("非脱机上线,继续协助!tagPlayerID=%s" % tagPlayerID, playerID)
            PlayerControl.SetAssistTagPlayerID(curPlayer, tagPlayerID)
            assistPack = ChPyNetSendPack.tagGCAssistingInfo()
            assistPack.AssistGUID = assistObj.GUID
            NetPackCommon.SendFakePack(curPlayer, assistPack)
        # 脱机上线
        else:
            OnCancelPlayerAssist(curPlayer, playerID, assistObj, "TJGLogin", True)
        tagPlayerID = assistObj.PlayerID
        GameWorld.DebugLog("非脱机上线,继续协助!tagPlayerID=%s" % tagPlayerID, playerID)
        PlayerControl.SetAssistTagPlayerID(curPlayer, tagPlayerID)
        assistPack = ChPyNetSendPack.tagGCAssistingInfo()
        assistPack.AssistGUID = assistObj.GUID
        NetPackCommon.SendFakePack(curPlayer, assistPack)
    return
def OnLeaveServer(curPlayer):
    ## 玩家离线
    familyID = curPlayer.GetFamilyID()
    if not familyID:
        return
    
    if PlayerControl.GetAssistTagPlayerID(curPlayer):
        PlayerControl.SetAssistTagPlayerID(curPlayer, 0)
        
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if familyID not in assistMgr.familyAssistDict:
        return
    playerID = curPlayer.GetPlayerID()
    if playerID not in assistMgr.playerNoSaveDBAssistDict:
    if playerID not in assistMgr.playerAssistDict:
        #GameWorld.DebugLog("玩家没有发布过协助,离线不处理!", playerID)
        return
    playerNoSaveList = assistMgr.playerNoSaveDBAssistDict[playerID]
    familyAssistList = assistMgr.familyAssistDict[familyID]
    playerAssistList = assistMgr.playerAssistDict[playerID]
    # 暂时移除离线玩家发布的不存库协助信息,不再让其他盟友继续前往协助,已经在协助的不影响
    for assistObj in playerNoSaveList:
        if assistObj not in familyAssistList:
    for assistObj in playerAssistList:
        if assistObj.IsSaveDB:
            continue
        familyAssistList.remove(assistObj)
        SyncFamilyClearAssist(familyID, assistObj.GUID)
        GameWorld.DebugLog("玩家下线,暂时从仙盟协助列表移除玩家发布的协助: %s" % assistObj.GUID)
        assistObj.OffLineTime = int(time.time())
        if not assistObj.FamilyID:
            SyncServerClearAssist(assistObj.GUID)
        elif familyID and familyID == assistObj.FamilyID:
            SyncFamilyClearAssist(familyID, assistObj.GUID)
        GameWorld.DebugLog("玩家下线,暂时从协助列表移除玩家发布的协助: %s" % assistObj.GUID)
        
    return
@@ -132,22 +193,45 @@
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    
    # 玩家发布的
    if leavePlayerID in assistMgr.playerNoSaveDBAssistDict:
        playerAssistList = assistMgr.playerNoSaveDBAssistDict[leavePlayerID]
    if leavePlayerID in assistMgr.playerAssistDict:
        playerAssistList = assistMgr.playerAssistDict[leavePlayerID]
        for assistObj in playerAssistList[::-1]:
            OnCancelPlayerRequestAssist(assistObj, "LeaveFamily", True)
            if assistObj.FamilyID:
                OnCancelPlayerRequestAssist(assistObj, "LeaveFamily", True)
            
    # 玩家协助中的
    if leavePlayerID in assistMgr.playerAssistingDict:
        assistObj = assistMgr.playerAssistingDict[leavePlayerID]
        OnCancelPlayerAssist(leavePlayer, leavePlayerID, assistObj, "LeaveFamily", True)
        if assistObj.FamilyID:
            OnCancelPlayerAssist(leavePlayer, leavePlayerID, assistObj, "LeaveFamily", True)
        
    return
def OnInitAssistData(dbData, isSaveDB):
def OnPlayerTeamChange(curPlayer):
    ## 玩家队伍变更
    if curPlayer.GetTeamID():
        return
    playerID = curPlayer.GetPlayerID()
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if playerID not in assistMgr.playerAssistDict:
        return
    playerAssistList = assistMgr.playerAssistDict[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, serverGroupID=0):
    ## 加载协助数据额外处理
    setattr(dbData, "IsSaveDB", isSaveDB) # 是否保存数据库,离线可协助的需要存库,如挖矿类
    setattr(dbData, "ObjID", 0) # NPC实例ID
    setattr(dbData, "ServerGroupID", serverGroupID)
    setattr(dbData, "OffLineTime", 0) # 发布玩家离线时间戳
    
    assistType = AssistType_Unknown
    if dbData.NPCID:
@@ -176,17 +260,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
@@ -219,25 +301,44 @@
        GameWorld.DebugLog("不能协助自己!")
        return
    
    if assistObj.FamilyID != curPlayer.GetFamilyID():
        GameWorld.DebugLog("非同盟玩家不能协助!")
        return
    isCrossBoss = assistObj.MapID in ChConfig.Def_CrossMapIDList
    if isCrossBoss:
        pass
    else:
        if assistObj.FamilyID != curPlayer.GetFamilyID():
            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:
        if mapID == ChConfig.Def_FBMapID_SealDemon:
            playerLineID = PlayerControl.GetFBFuncLineID(curPlayer)
        else:
            playerLineID = curPlayer.GetFBID()
        if playerMapID != mapID or playerLineID != lineID:
            #副本中无法协助
            PlayerControl.NotifyCode(curPlayer, "AssistFBLimit")
            return
        
    if isCrossBoss:
        tagPlayerID = assistObj.PlayerID
        assistPlayerID = curPlayer.GetPlayerID()
        assistPlayerName = curPlayer.GetName()
        isFriend = PlayerFriend.IsFriend(assistPlayerID, tagPlayerID)
        sendMsg = {"queryType":"StartAssistBoss", "queryData":[assistGUID, assistPlayerID, assistPlayerName, isFriend]}
        CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_CrossAssist, sendMsg)
        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)
@@ -303,7 +404,8 @@
    if playerID not in assistObj.AssistPlayerIDList:
        assistObj.AssistPlayerIDList.append(playerID)
        
    GameWorld.DebugLog("开始协助: tagPlayerID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s" % (tagPlayerID, mapID, lineID, npcID, objID), playerID)
    GameWorld.DebugLog("开始协助: tagPlayerID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s"
                       % (tagPlayerID, mapID, lineID, npcID, objID), playerID)
    
    # 设置协助
    PlayerControl.SetAssistTagPlayerID(curPlayer, tagPlayerID)
@@ -317,13 +419,98 @@
    tagPlayerName = tagPlayer.GetName()
    tagTeamID = tagPlayer.GetTeamID()
    isFriend = PlayerFriend.IsFriend(assistPlayerID, tagPlayerID)
    assistData = [mapID, "Start", assistGUID, assistPlayerID, assistPlayerName, isFriend, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID]
    serverGroupID = GameWorld.GetServerGroupID()
    assistData = [mapID, "Start", assistGUID, assistPlayerID, assistPlayerName, isFriend, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID, serverGroupID]
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_AssistBoss, assistData)
    return
def ClientServerMsg_StartAssistBoss(serverGroupID, queryType, queryData):
    ## 收到子服消息 - 开始协助boss
    ## @return: 是否同步删除GUID
    assistGUID, assistPlayerID, assistPlayerName, isFriend = queryData
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if assistGUID not in assistMgr.allAssistDict:
        GameWorld.Log("不存在该协助!assistGUID=%s" % assistGUID)
        reason, isGameServer = "AssistGUIDNotExist", True
        sendMsg = {"queryType":"CancelPlayerRequestAssist", "queryData":[assistGUID, reason, isGameServer]}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID])
        return
    assistObj = assistMgr.allAssistDict[assistGUID]
    if assistObj.AssistType != AssistType_Boss:
        return
    if assistObj.PlayerID == assistPlayerID:
        GameWorld.DebugLog("不能协助自己!")
        return
    assistPlayer = GameWorld.GetPlayerManager().FindPlayerByID(assistPlayerID)
    # 如果是在跨服服务器
    if assistPlayer:
        playerMapID = assistPlayer.GetMapID()
        mapID = assistObj.MapID
        lineID = assistObj.LineID
        playerMap = GameWorld.GetMap(playerMapID)
        if not playerMap:
            return
        if playerMap.GetMapFBType() != ChConfig.fbtNull:
            playerLineID = assistPlayer.GetFBID()
            if playerMapID != mapID or playerLineID != lineID:
                #副本中无法协助
                PlayerControl.NotifyCode(assistPlayer, "AssistFBLimit")
                return
    tagPlayerID = assistObj.PlayerID
    mapID = assistObj.MapID
    lineID = assistObj.LineID
    npcID = assistObj.NPCID
    objID = assistObj.ObjID
    tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID)
    if not tagPlayer:
        GameWorld.Log("玩家已离线,无法协助!tagPlayerID=%s" % (tagPlayerID))
        OnCancelPlayerRequestAssist(assistObj, "CrossPlayerOffline", True)
        return
    if tagPlayer.GetMapID() != mapID:
        GameWorld.DebugLog("目标玩家已不在请求协助的地图,无法协助!tagPlayerID=%s" % (tagPlayerID))
        return
    # 设置新协助之前需要先取消正在进行中的协助
    if assistPlayerID in assistMgr.playerAssistingDict:
        assistingObj = assistMgr.playerAssistingDict[assistPlayerID]
        if assistGUID != assistingObj.GUID:
            OnCancelPlayerAssist(assistPlayer, assistPlayerID, assistingObj, "StartNewAssistBoss", True)
    assistMgr.playerAssistingDict[assistPlayerID] = assistObj
    if assistPlayerID not in assistObj.AssistPlayerIDList:
        assistObj.AssistPlayerIDList.append(assistPlayerID)
    GameWorld.DebugLog("开始协助: tagPlayerID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s"
                       % (tagPlayerID, mapID, lineID, npcID, objID), assistPlayerID)
    # 设置协助
    if assistPlayer:
        PlayerControl.SetAssistTagPlayerID(assistPlayer, tagPlayerID)
    # 通知目标玩家
    # xxx开始协助你
    PlayerControl.NotifyCode(tagPlayer, "AssistStart", [assistPlayerName])
    tagPlayerName = tagPlayer.GetName()
    tagTeamID = tagPlayer.GetTeamID()
    assistData = [mapID, "Start", assistGUID, assistPlayerID, assistPlayerName, isFriend, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID, serverGroupID]
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_AssistBoss, assistData)
    return
def OnAddAssistBossPlayerOK(queryData):
    ## 添加协助Boss的玩家成功,通知协助玩家可以前往
    assistGUID, assistPlayerID = queryData
    assistGUID, assistPlayerID, tagPlayerID, serverGroupID = queryData
    if GameWorld.IsCrossServer():
        sendMsg = {"queryType":"AddAssistBossPlayerOK", "queryData":[assistGUID, assistPlayerID, tagPlayerID]}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID])
        return
    assistPlayer = GameWorld.GetPlayerManager().FindPlayerByID(assistPlayerID)
    if not assistPlayer:
        return
@@ -333,11 +520,35 @@
    NetPackCommon.SendFakePack(assistPlayer, assistPack)
    return
def SetPlayerStartAssistTeamFB(curPlayer, queryData):
    ## 开始协助组队副本 - 玩家进入副本后才真正进入协助状态
def CrossServerMsg_AddAssistBossPlayerOK(queryType, queryData):
    ## 收到跨服服务器 - 添加协助boss成功
    assistGUID, assistPlayerID, tagPlayerID = queryData
    
    #mapID, lineID, tagPlayerID = queryData
    assistPlayer = GameWorld.GetPlayerManager().FindPlayerByID(assistPlayerID)
    if not assistPlayer:
        return
    
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if assistGUID not in assistMgr.allAssistDict:
        GameWorld.DebugLog("不存在该协助!assistGUID=%s" % assistGUID)
        return
    assistObj = assistMgr.allAssistDict[assistGUID]
    # 设置协助
    PlayerControl.SetAssistTagPlayerID(assistPlayer, tagPlayerID)
    if assistPlayerID in assistMgr.playerAssistingDict:
        assistingObj = assistMgr.playerAssistingDict[assistPlayerID]
        if assistGUID != assistingObj.GUID:
            OnCancelPlayerAssist(assistPlayer, assistPlayerID, assistingObj, "StartNewAssistBoss", True)
    assistMgr.playerAssistingDict[assistPlayerID] = assistObj
    if assistPlayerID not in assistObj.AssistPlayerIDList:
        assistObj.AssistPlayerIDList.append(assistPlayerID)
    assistPack = ChPyNetSendPack.tagGCAssistingInfo()
    assistPack.AssistGUID = assistGUID
    NetPackCommon.SendFakePack(assistPlayer, assistPack)
    return
def MapServer_PlayerAssistLogic(curPlayer, msgList, tick):
@@ -364,8 +575,8 @@
    elif queryType == "OnCancelBossRequestAssist":
        mapID, lineID, npcID, objID, reason = queryData
        assistMgr = PyDataManager.GetPlayerAssistPyManager()
        if playerID in assistMgr.playerNoSaveDBAssistDict:
            playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
        if playerID in assistMgr.playerAssistDict:
            playerAssistList = assistMgr.playerAssistDict[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)
@@ -387,6 +598,11 @@
        __DoBossAssistOver(queryData)
        return
    
    # 副本协助结束
    elif queryType == "OnFBAssistOver":
        __DoFBAssistOver(queryData)
        return
    ## -------------------------------------------------------------------------------------------
    
    # 请求协助组队副本
@@ -396,7 +612,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)
@@ -413,37 +640,143 @@
def __DoRequestAssistBoss(curPlayer, queryData):
    ## 请求协助Boss
    
    isCrossServer = GameWorld.IsCrossServer()
    familyID = curPlayer.GetFamilyID()
    if not familyID:
    if not familyID and not isCrossServer:
        return
    mapID, lineID, npcID, objID = queryData
    mapID, lineID, npcID, objID, npcLV, serverGroupID = queryData
    
    playerID = curPlayer.GetPlayerID()
    
    assistObj = None
    addNewAssist = True
    reqAssistObj = None
    addNewAssist = False
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if playerID in assistMgr.playerNoSaveDBAssistDict:
        playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
    if playerID in assistMgr.playerAssistDict:
        playerAssistList = assistMgr.playerAssistDict[playerID]
        for assistObj in playerAssistList:
            if assistObj.AssistType != AssistType_Boss:
                continue
            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, serverGroupID=serverGroupID)
        
    if not assistObj:
    if not reqAssistObj:
        return
    
    # 通知本仙盟玩家
    PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([assistObj]))
    # 求助信息已发送,请等待盟友支援
    PlayerControl.NotifyCode(curPlayer, "AssistRequestOK")
    requestCount = 1
    if not addNewAssist:
        requestCount = min(curPlayer.GetDictByKey("AssistBossRequestCount") + 1, 999)
    curPlayer.SetDict("AssistBossRequestCount", requestCount)
    notifyNum = (requestCount - 1) % 3
    if isCrossServer:
        GUID = reqAssistObj.GUID
        sendMsg = {"queryType":"RequestAssistBoss", "queryData":[mapID, lineID, npcID, objID, npcLV, playerID, notifyNum, GUID]}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID])
    else:
        # 通知本仙盟玩家
        PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([reqAssistObj]))
        # 广播仙盟请求
        PlayerControl.FamilyNotify(familyID, "AssistBossRequest%s" % notifyNum, [curPlayer.GetName(), mapID, npcLV, npcID])
    return
def CrossServerMsg_RequestAssistBoss(queryType, queryData):
    mapID, lineID, npcID, objID, npcLV, playerID, notifyNum, GUID = queryData
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if not curPlayer:
        return
    reqAssistObj = None
    addNewAssist = False
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if playerID in assistMgr.playerAssistDict:
        playerAssistList = assistMgr.playerAssistDict[playerID]
        for assistObj in playerAssistList:
            if assistObj.AssistType != AssistType_Boss:
                continue
            if npcID != assistObj.NPCID or lineID != assistObj.LineID or objID != assistObj.ObjID:
                OnCancelPlayerRequestAssist(assistObj, "RequestNewAssistBoss", True)
            else:
                reqAssistObj = assistObj
            break
    if not reqAssistObj:
        addNewAssist = True
        reqAssistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID, objID, assistGUID=GUID)
    GameWorld.Log("收到跨服请求协助boss: %s mapID=%s,lineID=%s,npcID=%s,objID=%s,addNewAssist=%s,GUID=%s"
                  % (queryType, mapID, lineID, npcID, objID, addNewAssist, GUID), playerID)
    if not reqAssistObj:
        return
    # 通知本服玩家
    SyncServerAssist([reqAssistObj])
    # 广播请求
    PlayerControl.WorldNotify(0, "AssistBossRequest%s" % notifyNum, [curPlayer.GetName(), mapID, npcLV, npcID])
    return
def CrossServerMsg_CrossAssist(msgData, tick):
    ## 收到跨服服务器消息 - 协助信息
    queryType = msgData["queryType"]
    queryData = msgData["queryData"]
    # 请求协助boss
    if queryType == "RequestAssistBoss":
        CrossServerMsg_RequestAssistBoss(queryType, queryData)
        return
    # 添加协助boss成功
    if queryType == "AddAssistBossPlayerOK":
        CrossServerMsg_AddAssistBossPlayerOK(queryType, queryData)
        return
    # 取消协助请求
    if queryType == "CancelPlayerRequestAssist":
        CrossServerMsg_CancelPlayerRequestAssist(queryType, queryData)
        return
    # 取消协助
    if queryType == "CancelPlayerAssist":
        CrossServerMsg_CancelPlayerAssist(queryType, queryData)
        return
    # boss协助结束
    if queryType == "BossAssistOver":
        CrossServerMsg_BossAssistOver(queryType, queryData)
        return
    # 重置玩家协助
    if queryType == "ResetPlayerAssist":
        CrossServerMsg_ResetPlayerAssist(queryType, queryData)
        return
    return
def ClientServerMsg_CrossAssist(serverGroupID, msgData, tick):
    ## 收到子服服务器消息 - 协助信息
    queryType = msgData["queryType"]
    queryData = msgData["queryData"]
    # 开始协助boss
    if queryType == "StartAssistBoss":
        ClientServerMsg_StartAssistBoss(serverGroupID, queryType, queryData)
        return
    return
def __DoRequestAssistTeamFB(curPlayer, queryData):
@@ -452,41 +785,50 @@
    familyID = curPlayer.GetFamilyID()
    if not familyID:
        return
    mapID, lineID  = queryData
    mapID, lineID = queryData
    
    playerID = curPlayer.GetPlayerID()
    
    assistObj = None
    reqAssistObj = None
    addNewAssist = False
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if playerID in assistMgr.playerNoSaveDBAssistDict:
        playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
    if playerID in assistMgr.playerAssistDict:
        playerAssistList = assistMgr.playerAssistDict[playerID]
        for assistObj in playerAssistList:
            if assistObj.AssistType != AssistType_TeamFB:
                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):
def __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID=0, objID=0, exData="", isSaveDB=0, assistGUID="", serverGroupID=0):
    ## 添加新协助请求
    assistGUID = str(uuid.uuid1())
    familyID = curPlayer.GetFamilyID()
    if not assistGUID:
        assistGUID = str(uuid.uuid1())
    crossAssist = mapID in ChConfig.Def_CrossMapIDList
    familyID = 0 if crossAssist else curPlayer.GetFamilyID()
    playerID = curPlayer.GetPlayerID()
    assistObj = PyGameDataStruct.tagDBAssist()
    assistObj.GUID = assistGUID
@@ -503,22 +845,17 @@
    assistObj.ExDataLen = len(exData)
    
    # 以下是非DB字段属性
    OnInitAssistData(assistObj, isSaveDB)
    OnInitAssistData(assistObj, isSaveDB, serverGroupID)
    assistObj.ObjID = objID
    
    #assistMgr = PyDataManager.GetPlayerAssistPyManager()
    assistMgr.allAssistDict[assistGUID] = assistObj
    if familyID not in assistMgr.familyAssistDict:
        assistMgr.familyAssistDict[familyID] = []
    familyAssistList = assistMgr.familyAssistDict[familyID]
    familyAssistList.append(assistObj)
    
    if not isSaveDB:
        if playerID not in assistMgr.playerNoSaveDBAssistDict:
            assistMgr.playerNoSaveDBAssistDict[playerID] = []
        playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
        playerAssistList.append(assistObj)
    if playerID not in assistMgr.playerAssistDict:
        assistMgr.playerAssistDict[playerID] = []
    playerAssistList = assistMgr.playerAssistDict[playerID]
    playerAssistList.append(assistObj)
    GameWorld.DebugLog("    增加新协助请求: familyID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s,exData=%s,assistGUID=%s" 
                       % (familyID, mapID, lineID, npcID, objID, exData, assistGUID), playerID)
    return assistObj
@@ -529,6 +866,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
@@ -565,27 +903,21 @@
    lineID = assistObj.LineID
    npcID = assistObj.NPCID
    objID = assistObj.ObjID
    serverGroupID = assistObj.ServerGroupID
    
    GameWorld.DebugLog("取消发布的协助请求: mapID=%s,lineID=%s,npcID=%s,objID=%s,reason=%s,isGameServer=%s, %s"
                       % (mapID, lineID, npcID, objID, reason, isGameServer, assistGUID))
    GameWorld.DebugLog("取消发布的协助请求: mapID=%s,lineID=%s,npcID=%s,objID=%s,reason=%s,isGameServer=%s, %s, serverGroupID=%s"
                       % (mapID, lineID, npcID, objID, reason, isGameServer, assistGUID, serverGroupID))
    
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if assistGUID not in assistMgr.allAssistDict:
        return
    assistMgr.allAssistDict.pop(assistGUID)
    
    if familyID in assistMgr.familyAssistDict:
        familyAssistList = assistMgr.familyAssistDict[familyID]
        if assistObj in familyAssistList:
            familyAssistList.remove(assistObj)
    if playerID in assistMgr.playerNoSaveDBAssistDict:
        playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
    if playerID in assistMgr.playerAssistDict:
        playerAssistList = assistMgr.playerAssistDict[playerID]
        if assistObj in playerAssistList:
            playerAssistList.remove(assistObj)
            
    SyncFamilyClearAssist(familyID, assistGUID)
    # 取消boss协助
    if assistType == AssistType_Boss:
        
@@ -606,6 +938,48 @@
        # 暂不需要处理
        pass
    
    # 放最后
    if familyID:
        SyncFamilyClearAssist(familyID, assistGUID)
    if GameWorld.IsCrossServer() and serverGroupID:
        sendMsg = {"queryType":"CancelPlayerRequestAssist", "queryData":[assistGUID, reason, isGameServer]}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID])
    return
def CrossServerMsg_CancelPlayerRequestAssist(queryType, queryData):
    ## 收到跨服服务器 - 取消协助请求
    assistGUID, reason, isGameServer = queryData
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if assistGUID not in assistMgr.allAssistDict:
        return
    assistObj = assistMgr.allAssistDict.pop(assistGUID)
    playerID = assistObj.PlayerID
    assistType = assistObj.AssistType
    GameWorld.Log("收到跨服取消协助boss请求: %s assistGUID=%s,reason=%s,isGameServer=%s" % (queryType, assistGUID, reason, isGameServer), playerID)
    if playerID in assistMgr.playerAssistDict:
        playerAssistList = assistMgr.playerAssistDict[playerID]
        if assistObj in playerAssistList:
            playerAssistList.remove(assistObj)
    # 取消boss协助
    if assistType == AssistType_Boss:
        # 强制取消正在协助中的玩家
        playerMgr = GameWorld.GetPlayerManager()
        for assPlayerID in assistObj.AssistPlayerIDList[::-1]:
            assistObj.AssistPlayerIDList.remove(assPlayerID)
            if assPlayerID in assistMgr.playerAssistingDict:
                assistingObj = assistMgr.playerAssistingDict[assPlayerID]
                if assistingObj.GUID == assistGUID:
                    assPlayer = playerMgr.FindPlayerByID(assPlayerID)
                    OnCancelPlayerAssist(assPlayer, assPlayerID, assistObj, reason, isGameServer, isNotify=False)
    SyncServerClearAssist(assistGUID)
    return
def OnCancelPlayerAssist(cancelPlayer, cancelPlayerID, assistObj, reason, isGameServer, isNotify=True):
@@ -629,6 +1003,7 @@
    lineID = assistObj.LineID
    npcID = assistObj.NPCID
    objID = assistObj.ObjID
    serverGroupID = assistObj.ServerGroupID
    
    GameWorld.DebugLog("取消协助: tagPlayerID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s,reason=%s,isGameServer=%s, %s" 
                       % (tagPlayerID, mapID, lineID, npcID, objID, reason, isGameServer, assistGUID), cancelPlayerID)
@@ -641,7 +1016,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:
@@ -661,22 +1043,69 @@
    elif assistObj.AssistType == AssistType_TeamFB:
        pass
    
    if GameWorld.IsCrossServer() and serverGroupID:
        sendMsg = {"queryType":"CancelPlayerAssist", "queryData":[assistGUID, reason, isGameServer, cancelPlayerID]}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID])
    return
def CrossServerMsg_CancelPlayerAssist(queryType, queryData):
    ## 收到跨服服务器 - 取消玩家协助
    assistGUID, reason, isGameServer, cancelPlayerID = queryData
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if assistGUID not in assistMgr.allAssistDict:
        return
    GameWorld.Log("收到跨服取消玩家协助: %s assistGUID=%s,reason=%s,isGameServer=%s" % (queryType, assistGUID, reason, isGameServer), cancelPlayerID)
    cancelPlayer = GameWorld.GetPlayerManager().FindPlayerByID(cancelPlayerID)
    if not cancelPlayer:
        return
    PlayerControl.SetAssistTagPlayerID(cancelPlayer, 0)
    return
def CrossServerMsg_ResetPlayerAssist(queryType, queryData):
    ## 收到跨服服务器 - 重置玩家协助
    ##
    playerID, tagPlayerID = queryData
    GameWorld.Log("收到跨服重置玩家协助: playerID=%s,tagPlayerID=%s" % (playerID, tagPlayerID), playerID)
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if not curPlayer:
        return
    PlayerControl.SetAssistTagPlayerID(curPlayer, 0)
    return
def __DoBossAssistOver(queryData):
    ## boss协助结束,一般是boss被击杀 或 被系统
    mapID, lineID, npcID, objID, noAssistPlayerIDList, assistAwardItemID, assistAwardResult = queryData
    isCrossServer = GameWorld.IsCrossServer()
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    for noAssistPlayerID in noAssistPlayerIDList:
        if noAssistPlayerID not in assistMgr.playerNoSaveDBAssistDict:
        if noAssistPlayerID not in assistMgr.playerAssistDict:
            continue
        playerAssistList = assistMgr.playerNoSaveDBAssistDict[noAssistPlayerID]
        playerAssistList = assistMgr.playerAssistDict[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:
                # 跨服服务器同步到子服结算奖励
                if isCrossServer and noAssistPlayerID in assistAwardResult:
                    assistPlayerDict = assistAwardResult[noAssistPlayerID]
                    serverGroupID = assistObj.ServerGroupID
                    sendMsg = {"queryType":"BossAssistOver", "queryData":[mapID, lineID, npcID, noAssistPlayerID, assistAwardItemID, assistPlayerDict]}
                    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID])
                break
    if not assistAwardItemID or not assistAwardResult:
        return
    if isCrossServer:
        return
    
    # 新增感谢数据
@@ -685,11 +1114,68 @@
        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 CrossServerMsg_BossAssistOver(queryType, queryData):
    ## 收到跨服服务器 - boss协助结束
    mapID, lineID, npcID, noAssistPlayerID, assistAwardItemID, assistPlayerDict = queryData
    GameWorld.Log("收到跨服boss协助结束: mapID=%s,lineID=%s,npcID=%s,assistAwardItemID=%s,assistPlayerDict=%s"
                  % (mapID, lineID, npcID, assistAwardItemID, assistPlayerDict), noAssistPlayerID)
    # 新增感谢数据
    playerMgr = GameWorld.GetPlayerManager()
    curPlayer = playerMgr.FindPlayerByID(noAssistPlayerID)
    if not curPlayer:
        return
    AddNewAssistThanks(curPlayer, assistAwardItemID, mapID, lineID, assistPlayerDict, npcID)
    # 通知地图玩家给 协助礼盒
    queryData = [assistAwardItemID]
    QueryPlayerResult_PlayerAssist(curPlayer, "CrossNoAssistPlayerAward", queryData)
    # 通知地图玩家给 活跃积分
    for assistPlayerID, assistInfo in assistPlayerDict.items():
        assistPlayer = playerMgr.FindPlayerByID(assistPlayerID)
        if not assistPlayer:
            continue
        if "AssistMoney" not in assistInfo:
            continue
        assistMoney = assistInfo["AssistMoney"]
        isFriend = assistInfo["IsFriend"]
        queryData = [assistMoney, isFriend]
        QueryPlayerResult_PlayerAssist(assistPlayer, "CrossAssistPlayerAward", queryData)
    return
def __DoFBAssistOver(queryData):
    ## 副本协助结束
    mapID, lineID, noAssistPlayerID, assistAwardItemID, assistPlayerDict = queryData
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    if noAssistPlayerID not in assistMgr.playerAssistDict:
        return
    playerAssistList = assistMgr.playerAssistDict[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()
@@ -715,7 +1201,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
@@ -734,23 +1220,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
@@ -775,22 +1267,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
@@ -811,9 +1302,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:
@@ -859,7 +1355,7 @@
        if getThanks in assistThanksMgr.allAssistThanksList:
            assistThanksMgr.allAssistThanksList.remove(getThanks)
            
    assistPlayerThanksList.pop(0) # 移除
    assistPlayerThanksList.remove(getThanks) # 移除
    
    updateTodayGiftCount = todayGiftCount + 1
    # 更新当天该礼盒ID已领取次数
@@ -871,25 +1367,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)
@@ -901,7 +1408,11 @@
    if not familyID:
        return
    assistMgr = PyDataManager.GetPlayerAssistPyManager()
    familyAssistList = assistMgr.familyAssistDict.get(familyID, [])
    familyAssistList = []
    for assistObj in assistMgr.allAssistDict.values():
        if not assistObj.FamilyID or familyID != assistObj.FamilyID or assistObj.OffLineTime:
            continue
        familyAssistList.append(assistObj)
    if not familyAssistList:
        return
    NetPackCommon.SendFakePack(curPlayer, GetAssistInfoListPack(familyAssistList))
@@ -914,3 +1425,37 @@
    PlayerFamily.SendFamilyFakePack(familyID, clearPack)
    return
def SyncServerAssist(assistList):
    # 通知本服玩家协助请求信息
    funcLimitLV = PlayerControl.GetFuncLimitLV(ShareDefine.GameFuncID_PenglaiBoss)
    clientPack = GetAssistInfoListPack(assistList)
    playerManager = GameWorld.GetPlayerManager()
    for i in xrange(playerManager.GetActivePlayerCount()):
        player = playerManager.GetActivePlayerAt(i)
        if player == None:
            continue
        if player.GetLV() < funcLimitLV:
            continue
        if PlayerControl.GetIsTJG(player):
            continue
        NetPackCommon.SendFakePack(player, clientPack)
    return
def SyncServerClearAssist(assistGUID):
    # 通知本服玩家清除协助
    clearPack = ChPyNetSendPack.tagGCClearAssist()
    clearPack.AssistGUID = assistGUID
    funcLimitLV = PlayerControl.GetFuncLimitLV(ShareDefine.GameFuncID_PenglaiBoss)
    playerManager = GameWorld.GetPlayerManager()
    for i in xrange(playerManager.GetActivePlayerCount()):
        player = playerManager.GetActivePlayerAt(i)
        if player == None:
            continue
        if player.GetLV() < funcLimitLV:
            continue
        if PlayerControl.GetIsTJG(player):
            continue
        NetPackCommon.SendFakePack(player, clearPack)
    return