From 523feffb040e7e6436c6715ba2e851f053868150 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 02 八月 2022 14:35:10 +0800
Subject: [PATCH] 9387 【主干】【越南】【bt7】【后端】支持跨服协助(登录通知今日协助活跃令;优化仙盟协助、跨服协助共存逻辑)

---
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py |  293 ++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 173 insertions(+), 120 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
index 011f3d4..384e068 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
@@ -31,6 +31,7 @@
 import ChConfig
 
 import uuid
+import time
 
 # 协助类型
 (
@@ -95,91 +96,93 @@
                            % (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
 
@@ -190,8 +193,8 @@
     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]:
             if assistObj.FamilyID:
                 OnCancelPlayerRequestAssist(assistObj, "LeaveFamily", True)
@@ -212,9 +215,9 @@
     playerID = curPlayer.GetPlayerID()
     
     assistMgr = PyDataManager.GetPlayerAssistPyManager()
-    if playerID not in assistMgr.playerNoSaveDBAssistDict:
+    if playerID not in assistMgr.playerAssistDict:
         return
-    playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
+    playerAssistList = assistMgr.playerAssistDict[playerID]
     
     for assistObj in playerAssistList[::-1]:
         gameMap = GameWorld.GetMap(assistObj.MapID)
@@ -228,6 +231,7 @@
     setattr(dbData, "IsSaveDB", isSaveDB) # 是否保存数据库,离线可协助的需要存库,如挖矿类
     setattr(dbData, "ObjID", 0) # NPC实例ID
     setattr(dbData, "ServerGroupID", serverGroupID)
+    setattr(dbData, "OffLineTime", 0) # 发布玩家离线时间戳
     
     assistType = AssistType_Unknown
     if dbData.NPCID:
@@ -524,9 +528,24 @@
     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)
@@ -556,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)
@@ -632,8 +651,8 @@
     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
@@ -682,8 +701,8 @@
     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
@@ -703,19 +722,8 @@
         return
     
     # 通知本服玩家
-    funcLimitLV = PlayerControl.GetFuncLimitLV(ShareDefine.GameFuncID_PenglaiBoss)
-    clientPack = GetAssistInfoListPack([reqAssistObj])
-    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)
-        
+    SyncServerAssist([reqAssistObj])
+            
     # 广播请求
     PlayerControl.WorldNotify(0, "AssistBossRequest%s" % notifyNum, [curPlayer.GetName(), mapID, npcLV, npcID])
     return
@@ -751,6 +759,11 @@
         CrossServerMsg_BossAssistOver(queryType, queryData)
         return
     
+    # 重置玩家协助
+    if queryType == "ResetPlayerAssist":
+        CrossServerMsg_ResetPlayerAssist(queryType, queryData)
+        return
+    
     return
 
 def ClientServerMsg_CrossAssist(serverGroupID, msgData, tick):
@@ -779,8 +792,8 @@
     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
@@ -837,18 +850,12 @@
     
     #assistMgr = PyDataManager.GetPlayerAssistPyManager()
     assistMgr.allAssistDict[assistGUID] = assistObj
-    if familyID:
-        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
@@ -906,13 +913,8 @@
         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)
             
@@ -956,29 +958,28 @@
         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.playerNoSaveDBAssistDict:
-        playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
+    if playerID in assistMgr.playerAssistDict:
+        playerAssistList = assistMgr.playerAssistDict[playerID]
         if assistObj in playerAssistList:
             playerAssistList.remove(assistObj)
             
-    # 通知本服玩家
-    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)
-        
+    # 取消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):
@@ -1066,15 +1067,29 @@
     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)
@@ -1142,9 +1157,9 @@
     ## 副本协助结束
     mapID, lineID, noAssistPlayerID, assistAwardItemID, assistPlayerDict = queryData
     assistMgr = PyDataManager.GetPlayerAssistPyManager()
-    if noAssistPlayerID not in assistMgr.playerNoSaveDBAssistDict:
+    if noAssistPlayerID not in assistMgr.playerAssistDict:
         return
-    playerAssistList = assistMgr.playerNoSaveDBAssistDict[noAssistPlayerID]
+    playerAssistList = assistMgr.playerAssistDict[noAssistPlayerID]
     for assistObj in playerAssistList:
         if assistObj.MapID == mapID and assistObj.LineID == lineID:
             OnCancelPlayerRequestAssist(assistObj, "FBAssistOver", False)
@@ -1393,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))
@@ -1406,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
+
+

--
Gitblit v1.8.0