From 70c43a79d99c93fc5fe8976006ca1a8a1570a0f5 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 25 十月 2021 12:07:52 +0800
Subject: [PATCH] 9302 【BT5】【主干】【后端】GameServer启动慢后续优化处理

---
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py |   80 ++++++++++++++++++++++++++++++----------
 1 files changed, 60 insertions(+), 20 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
index 8e5fdd4..a316f70 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -36,7 +36,6 @@
 import ShareDefine
 import CrossBoss
 
-import random
 #---------------------------------------------------------------------
 
 ## 跨服地图动态分配的功能线路,如果有人数上限的,则同分区同地图玩法的可能同时存在多个相同功能线路的数据
@@ -62,6 +61,7 @@
         self.openState = IPY_PlayerDefine.fbosClosed
         self.fbPlayerDict = {} # 副本中的玩家信息 {playerID:serverGroupID, ...}
         self.waitPlayerDict = {} # 等待进入的玩家信息 {playerID:[serverGroupID, tick], ...}
+        self.offlinePlayerDict = {} # 掉线的玩家信息,非主动退出的 {playerID:serverGroupID, ...}
         return
     
     def OnRequestEnterCrossCopyMap(self, playerID, serverGroupID, tick, copyMapPlayerMax):
@@ -133,7 +133,8 @@
         return
     zoneID = zoneIpyData.GetZoneID()
     
-    copyMapPlayerMax = 0 # 0为不限制人数,默认不限制
+    dynamicLineMaxPlayerCountDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 2)
+    copyMapPlayerMax = dynamicLineMaxPlayerCountDict.get(mapID, 0) # 0为不限制人数,默认不限制
     if mapID == ChConfig.Def_FBMapID_CrossDemonKing:
         bossID = msgData["BossID"]
         if not CrossBoss.GetCrossBossIsAliveOrCanReborn(zoneID, bossID):
@@ -141,7 +142,7 @@
             return
         
     elif mapID in [ChConfig.Def_FBMapID_CrossGrasslandLing, ChConfig.Def_FBMapID_CrossGrasslandXian]:
-        copyMapPlayerMax = 10
+        pass
         
     else:
         return
@@ -163,20 +164,11 @@
     
     playerIDList, dataMapID, mapID, copyMapID, funcLineID = msgData
     
-    dynamicLineMapDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 1)
-    if dataMapID not in dynamicLineMapDict:
-        return
-    mapPosInfo = dynamicLineMapDict[dataMapID][0]
-    posX, posY = mapPosInfo[:2]
-    dist = mapPosInfo[2] if len(mapPosInfo) > 2 else 0
-    if dist > 0:
-        posX, posY = random.randint(posX - dist, posX + dist), random.randint(posY - dist, posY + dist)
-        
     for playerID in playerIDList:
         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
         if not curPlayer:
             continue
-        CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, mapID, dataMapID, copyMapID, posX, posY, lineID=funcLineID)
+        CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, mapID, dataMapID, copyMapID, lineID=funcLineID)
         
     return
 
@@ -225,9 +217,7 @@
             return realMapID, copyMapID, openState
         
     dynamicLineMapDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 1)
-    if mapID not in dynamicLineMapDict:
-        return
-    dynamicMapIDList = dynamicLineMapDict[mapID][1]
+    dynamicMapIDList = dynamicLineMapDict.get(mapID, [mapID])
     
     openMapID, openCopyMapID = 0, 0
     for realMapID in dynamicMapIDList:
@@ -358,10 +348,22 @@
                 break
     
     key = (mapID, copyMapID)
-    PyGameData.g_crossDynamicLineCopyMapInfo.pop(key, {})
-    
+    copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo.pop(key, None)
+    if not copyMapObj:
+        return
     #GameWorld.DebugLog("    PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo)
     #GameWorld.DebugLog("    PyGameData.g_crossDynamicLineCopyMapInfo=%s" % PyGameData.g_crossDynamicLineCopyMapInfo)
+    
+    playerCount = 0
+    zoneID = copyMapObj.zoneID
+    funcLineID = copyMapObj.funcLineID
+    playerCountInfo = [playerCount]
+    SyncClientServerCrossFBFuncLinePlayerCount(zoneID, mapID, funcLineID, playerCountInfo)
+    
+    #如果虚拟分线关闭时,有掉线的玩家,则通知子服重置这些玩家的跨服状态
+    for playerID, serverGroupID in copyMapObj.offlinePlayerDict.items():
+        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_ExitCrossServer, playerID, [serverGroupID])
+        
     return
 
 def OnCrossDynamicMapReset(msgList):
@@ -397,12 +399,34 @@
     playerID = curPlayer.GetPlayerID()
     serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)
     copyMapObj.waitPlayerDict.pop(playerID, None)
+    copyMapObj.offlinePlayerDict.pop(playerID, None)
     copyMapObj.fbPlayerDict[playerID] = serverGroupID
     
     #GameWorld.DebugLog("玩家登录动态分配的跨服地图: GetMapID=%s,GetRealMapID=%s,GetFBID()=%s,serverGroupID=%s" 
     #                   % (curPlayer.GetMapID(), mapID, copyMapID, serverGroupID), playerID)
     #GameWorld.DebugLog("    副本中的玩家ID: %s" % copyMapObj.fbPlayerDict)
     #GameWorld.DebugLog("    等待中的玩家ID: %s" % copyMapObj.waitPlayerDict)
+    #GameWorld.DebugLog("    离线中的玩家ID: %s" % copyMapObj.offlinePlayerDict)
+    
+    playerCount = len(copyMapObj.fbPlayerDict) # 等待进入的暂时不算
+    zoneID = copyMapObj.zoneID
+    funcLineID = copyMapObj.funcLineID
+    playerCountInfo = [playerCount]
+    SyncClientServerCrossFBFuncLinePlayerCount(zoneID, mapID, funcLineID, playerCountInfo)
+    return
+
+def SyncClientServerCrossFBFuncLinePlayerCount(zoneID, mapID, funcLineID, playerCountInfo):
+    ## 同步子服跨服副本功能线路人数
+    ## 注意: 此人数不是一个精确人数值,只是一个大概人数值,不用很精确,暂时只玩家进入时同步人数信息,玩家退出暂不处理 
+    mapID = GetRecordMapID(mapID)
+    if mapID not in ChConfig.Def_NeedCountFBFuncLinePlayerCrossMap:
+        return
+    zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByZoneID(mapID, zoneID)
+    if not zoneIpyData:
+        return
+    serverGroupIDList = zoneIpyData.GetServerGroupIDList()
+    playerCountInfo = [mapID, funcLineID, playerCountInfo]
+    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_FBPlayerCount, playerCountInfo, serverGroupIDList)
     return
 
 def OnPlayerDisconnectCrossServer(curPlayer):
@@ -418,10 +442,26 @@
     copyMapObj.waitPlayerDict.pop(playerID, None)
     copyMapObj.fbPlayerDict.pop(playerID, None)
     
-    #GameWorld.DebugLog("玩家退出动态分配的跨服地图: GetMapID=%s,GetRealMapID=%s,GetFBID()=%s" 
-    #                   % (curPlayer.GetMapID(), mapID, copyMapID), playerID)
+    crossMapID = PlayerControl.GetCrossMapID(curPlayer)
+    # 不是主动退出的
+    if crossMapID:
+        copyMapObj.offlinePlayerDict[playerID] = PlayerControl.GetPlayerServerGroupID(curPlayer)
+    
+    #GameWorld.DebugLog("玩家退出动态分配的跨服地图: GetMapID=%s,GetRealMapID=%s,GetFBID()=%s,crossMapID=%s" 
+    #                   % (curPlayer.GetMapID(), mapID, copyMapID, crossMapID), playerID)
     #GameWorld.DebugLog("    副本中的玩家ID: %s" % copyMapObj.fbPlayerDict)
     #GameWorld.DebugLog("    等待中的玩家ID: %s" % copyMapObj.waitPlayerDict)
+    #GameWorld.DebugLog("    离线中的玩家ID: %s" % copyMapObj.offlinePlayerDict)
+    return
+
+def CrossServerMsg_FBPlayerCount(msgData):
+    ## 收到跨服服务器同步的副本功能线路人数信息
+    
+    mapID, funcLineID, playerCountInfo = msgData
+    if mapID not in PyGameData.g_crossFBFuncLinePlayerCountInfo:
+        PyGameData.g_crossFBFuncLinePlayerCountInfo[mapID] = {}
+    fbLinePlayerInfoDict = PyGameData.g_crossFBFuncLinePlayerCountInfo[mapID]
+    fbLinePlayerInfoDict[funcLineID] = playerCountInfo
     return
 
 ##--------------------------------------------------------------------------------------------------

--
Gitblit v1.8.0