From bc938da93f0118cd5232327aa9382a0adbbf5a8e Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期五, 19 四月 2019 18:07:06 +0800 Subject: [PATCH] 6459 【后端】【2.0】缥缈仙域开发单(跨服副本动态线路分配优化) --- ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py | 166 +++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 105 insertions(+), 61 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py index d4700f4..8e5fdd4 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py @@ -30,6 +30,7 @@ import PlayerTeam import GameWorld import ChConfig +import IPY_PlayerDefine import CrossRealmPlayer import CrossRealmMsg import ShareDefine @@ -42,15 +43,14 @@ class CrossFuncLineInfo(): def __init__(self): - self.mapID = 0 + self.realMapID = 0 self.copyMapID = 0 self.funcLineDataCache = None # 功能线路自定义缓存数据 return - def OnCopyMapClose(self, funcLineDataCache): - self.mapID = 0 + def OnCopyMapClose(self): + self.realMapID = 0 self.copyMapID = 0 - self.funcLineDataCache = funcLineDataCache return ## 跨服地图动态分配的虚拟线路信息 @@ -59,7 +59,7 @@ def __init__(self, zoneID, funcLineID): self.zoneID = zoneID self.funcLineID = funcLineID - self.openState = 0 + self.openState = IPY_PlayerDefine.fbosClosed self.fbPlayerDict = {} # 副本中的玩家信息 {playerID:serverGroupID, ...} self.waitPlayerDict = {} # 等待进入的玩家信息 {playerID:[serverGroupID, tick], ...} return @@ -125,36 +125,36 @@ def ClientServerMsg_EnterFB(serverGroupID, msgData, tick): ## 收到子服请求进入动态分配的跨服副本 playerID = msgData["PlayerID"] - dataMapID = msgData["DataMapID"] + mapID = msgData["MapID"] funcLineID = msgData["FuncLineID"] - zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(dataMapID, serverGroupID) + zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID) if not zoneIpyData: return zoneID = zoneIpyData.GetZoneID() copyMapPlayerMax = 0 # 0为不限制人数,默认不限制 - if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing: + if mapID == ChConfig.Def_FBMapID_CrossDemonKing: bossID = msgData["BossID"] if not CrossBoss.GetCrossBossIsAliveOrCanReborn(zoneID, bossID): GameWorld.DebugLog("当前跨服妖王死亡状态,不可进入! serverGroupID=%s,funcLineID=%s,zoneID=%s,bossID=%s" % (serverGroupID, funcLineID, zoneID, bossID)) return - elif dataMapID in [ChConfig.Def_FBMapID_CrossGrasslandLing, ChConfig.Def_FBMapID_CrossGrasslandXian]: + elif mapID in [ChConfig.Def_FBMapID_CrossGrasslandLing, ChConfig.Def_FBMapID_CrossGrasslandXian]: copyMapPlayerMax = 10 else: return - mapCopyLineInfo = __GetCrossDynamicLineInfo(playerID, serverGroupID, dataMapID, funcLineID, zoneID, copyMapPlayerMax, tick) + mapCopyLineInfo = __GetCrossDynamicLineInfo(playerID, serverGroupID, mapID, funcLineID, zoneID, copyMapPlayerMax, tick) if not mapCopyLineInfo: return - mapID, copyMapID, openState = mapCopyLineInfo - if not openState: + realMapID, copyMapID, openState = mapCopyLineInfo + if openState != IPY_PlayerDefine.fbosOpen: return playerIDList = [playerID] - retInfo = [playerIDList, dataMapID, mapID, copyMapID, funcLineID] + retInfo = [playerIDList, mapID, realMapID, copyMapID, funcLineID] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID]) return @@ -180,15 +180,15 @@ return -def __GetCrossDynamicLineInfo(playerID, serverGroupID, dataMapID, funcLineID, zoneID, copyMapPlayerMax, tick): +def __GetCrossDynamicLineInfo(playerID, serverGroupID, mapID, funcLineID, zoneID, copyMapPlayerMax, tick): '''获取跨服分区对应动态分配的副本地图虚拟线路信息, 由于需要支持多地图分流,所以直接由GameServer管理分配 每个功能线路支持按人数分流,超过最大人数后可开启一条相同功能线路的虚拟线路进行分流,所以同一分区同一地图的功能线路ID可能对应多条虚拟线路 ''' zoneLineKey = (zoneID, funcLineID) - if dataMapID not in PyGameData.g_crossDynamicLineInfo: - PyGameData.g_crossDynamicLineInfo[dataMapID] = {} - zoneLineDict = PyGameData.g_crossDynamicLineInfo[dataMapID] # 跨服动态线路信息 {dataMapID:{(zoneID, funcLineID):[CrossFuncLineInfo, CrossFuncLineInfo, ...], ...}, ...} + if mapID not in PyGameData.g_crossDynamicLineInfo: + PyGameData.g_crossDynamicLineInfo[mapID] = {} + zoneLineDict = PyGameData.g_crossDynamicLineInfo[mapID] # 跨服动态线路信息 {dataMapID:{(zoneID, funcLineID):[CrossFuncLineInfo, CrossFuncLineInfo, ...], ...}, ...} if zoneLineKey not in zoneLineDict: zoneLineDict[zoneLineKey] = [] funcLineObjList = zoneLineDict[zoneLineKey] @@ -196,87 +196,108 @@ newFuncLineNum = None newFuncLineObj = None for index, funcLineObj in enumerate(funcLineObjList, 1): - mapID, copyMapID = funcLineObj.mapID, funcLineObj.copyMapID - if not mapID: - newFuncLineNum, newFuncLineObj = index, funcLineObj - break + realMapID, copyMapID = funcLineObj.realMapID, funcLineObj.copyMapID + if not realMapID: + if not newFuncLineObj: + newFuncLineNum, newFuncLineObj = index, funcLineObj + continue - key = (mapID, copyMapID) + key = (realMapID, copyMapID) if key not in PyGameData.g_crossDynamicLineCopyMapInfo: - GameWorld.ErrLog("已经分配的虚拟线路不存在缓存对应关系里!zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s" - % (zoneID, funcLineID, mapID, copyMapID)) + GameWorld.ErrLog("已经分配的虚拟线路不存在缓存对应关系里!zoneID=%s,funcLineID=%s,realMapID=%s,copyMapID=%s" + % (zoneID, funcLineID, realMapID, copyMapID)) continue copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] openState = copyMapObj.openState + if openState == IPY_PlayerDefine.fbosWaitForClose: + if not copyMapPlayerMax: + PlayerControl.CrossNotifyCode(serverGroupID, playerID, "HazyRegionClose") + return + #GameWorld.DebugLog(" 虚拟线路等待关闭中! index=%s,realMapID=%s,copyMapID=%s" % (index, realMapID, copyMapID)) + continue + canEnter = copyMapObj.OnRequestEnterCrossCopyMap(playerID, serverGroupID, tick, copyMapPlayerMax) if canEnter: - #GameWorld.DebugLog("可进入动态分布的虚拟线路! mapID=%s,copyMapID=%s,openState=%s" % (mapID, copyMapID, openState)) + #GameWorld.DebugLog("可进入动态分布的虚拟线路! realMapID=%s,copyMapID=%s,openState=%s" % (realMapID, copyMapID, openState)) #GameWorld.DebugLog(" 副本中的玩家ID: %s" % copyMapObj.fbPlayerDict) #GameWorld.DebugLog(" 等待中的玩家ID: %s" % copyMapObj.waitPlayerDict) - return mapID, copyMapID, openState + return realMapID, copyMapID, openState dynamicLineMapDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 1) - if dataMapID not in dynamicLineMapDict: + if mapID not in dynamicLineMapDict: return - mapIDList = dynamicLineMapDict[dataMapID][1] + dynamicMapIDList = dynamicLineMapDict[mapID][1] openMapID, openCopyMapID = 0, 0 - for mapID in mapIDList: - maxCopyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(mapID, 0) + for realMapID in dynamicMapIDList: + maxCopyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(realMapID, 0) for copyMapID in xrange(maxCopyMapCount): - if (mapID, copyMapID) not in PyGameData.g_crossDynamicLineCopyMapInfo: - openMapID, openCopyMapID = mapID, copyMapID + if (realMapID, copyMapID) not in PyGameData.g_crossDynamicLineCopyMapInfo: + openMapID, openCopyMapID = realMapID, copyMapID break if openMapID: break if not openMapID: - GameWorld.ErrLog("没有空余的虚拟线路,无法动态开启跨服副本!dataMapID=%s, funcLineID=%s, zoneID=%s, mapIDList=%s" - % (dataMapID, funcLineID, zoneID, mapIDList)) + GameWorld.ErrLog("没有空余的虚拟线路,无法动态开启跨服副本!mapID=%s, funcLineID=%s, zoneID=%s, dynamicMapIDList=%s" + % (mapID, funcLineID, zoneID, dynamicMapIDList)) return if newFuncLineObj == None: newFuncLineObj = CrossFuncLineInfo() funcLineObjList.append(newFuncLineObj) newFuncLineNum = len(funcLineObjList) - mapID, copyMapID = openMapID, openCopyMapID - newFuncLineObj.mapID = mapID + realMapID, copyMapID = openMapID, openCopyMapID + newFuncLineObj.realMapID = realMapID newFuncLineObj.copyMapID = copyMapID funcLineDataCache = newFuncLineObj.funcLineDataCache - key = (mapID, copyMapID) + key = (realMapID, copyMapID) copyMapObj = CrossCopyMapInfo(zoneID, funcLineID) PyGameData.g_crossDynamicLineCopyMapInfo[key] = copyMapObj copyMapObj.waitPlayerDict[playerID] = [serverGroupID, tick] openState = copyMapObj.openState propertyID = int("%d%03d%d" % (zoneID, funcLineID, newFuncLineNum)) - GameWorld.DebugLog("不存在该分区功能线路ID,重新分配: zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s,propertyID=%s" - % (zoneID, funcLineID, mapID, copyMapID, propertyID)) + GameWorld.DebugLog("不存在该分区功能线路ID,重新分配: zoneID=%s,funcLineID=%s,realMapID=%s,copyMapID=%s,propertyID=%s" + % (zoneID, funcLineID, realMapID, copyMapID, propertyID)) # 通知地图开启新的地图虚拟分线 msgInfo = str([copyMapID, propertyID, funcLineDataCache]) - GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, mapID, "OpenFB", msgInfo, len(msgInfo)) - return mapID, copyMapID, openState + GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, realMapID, "OpenFB", msgInfo, len(msgInfo)) + return realMapID, copyMapID, openState def GetCrossDynamicLineZoneID(mapID, realMapID, copyMapID): ## 获取跨服动态分配的虚拟线路对应分区ID zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {}) for key, funcLineObjList in zoneLineDict.items(): for funcLineObj in funcLineObjList: - if funcLineObj.mapID == realMapID and funcLineObj.copyMapID == copyMapID: + if funcLineObj.realMapID == realMapID and funcLineObj.copyMapID == copyMapID: zoneID = key[0] return zoneID return 0 -def OnCrossDynamicLineOpen(mapID, copyMapID): +def OnCrossDynamicLineStateChange(msgList): + realMapID, copyMapID, state = msgList[:3] + + if state == IPY_PlayerDefine.fbosWaitForClose: + funcLineDataCache = msgList[3] + OnCrossDynamicLineWaitForClose(realMapID, copyMapID, funcLineDataCache) + elif state == IPY_PlayerDefine.fbosClosed: + OnCrossDynamicLineClose(realMapID, copyMapID) + elif state == IPY_PlayerDefine.fbosOpen: + OnCrossDynamicLineOpen(realMapID, copyMapID) + + return + +def OnCrossDynamicLineOpen(realMapID, copyMapID): ## 动态分配线路的地图虚拟线路启动成功 - key = (mapID, copyMapID) + key = (realMapID, copyMapID) if key not in PyGameData.g_crossDynamicLineCopyMapInfo: return copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] - copyMapObj.openState = 1 + copyMapObj.openState = IPY_PlayerDefine.fbosOpen funcLineID = copyMapObj.funcLineID # 通知子服等待中的玩家可以进入副本 @@ -288,27 +309,50 @@ playerIDList = serverPlayerIDListDict[serverGroupID] playerIDList.append(playerID) - dataMapID = GetRecordMapID(mapID) - GameWorld.Log("动态分配虚拟线路启动成功,通知子服等待玩家可进入: dataMapID=%s,mapID=%s,copyMapID=%s,serverPlayerIDListDict=%s" - % (dataMapID, mapID, copyMapID, serverPlayerIDListDict)) + mapID = GetRecordMapID(realMapID) + GameWorld.Log("动态分配虚拟线路启动成功,通知子服等待玩家可进入: mapID=%s,realMapID=%s,copyMapID=%s,serverPlayerIDListDict=%s" + % (mapID, realMapID, copyMapID, serverPlayerIDListDict)) for serverGroupID, playerIDList in serverPlayerIDListDict.items(): - retInfo = [playerIDList, dataMapID, mapID, copyMapID, funcLineID] + retInfo = [playerIDList, mapID, realMapID, copyMapID, funcLineID] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID]) #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineCopyMapInfo=%s" % PyGameData.g_crossDynamicLineCopyMapInfo) return -def OnCrossDynamicLineClose(mapID, copyMapID, funcLineDataCache): +def OnCrossDynamicLineWaitForClose(realMapID, copyMapID, funcLineDataCache): ## 动态分配线路的地图虚拟线路关闭 + mapID = GetRecordMapID(realMapID) + GameWorld.Log("动态分配虚拟线路等待关闭 mapID=%s,realMapID=%s,copyMapID=%s,funcLineDataCache=%s" % (mapID, realMapID, copyMapID, funcLineDataCache)) + zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {}) + for key, funcLineObjList in zoneLineDict.items(): + for funcLineObj in funcLineObjList: + if funcLineObj.realMapID == realMapID and funcLineObj.copyMapID == copyMapID: + funcLineObj.funcLineDataCache = funcLineDataCache + zoneID, funcLineID = key + GameWorld.Log(" 分区对应功能线路虚拟分线等待关闭: zoneID=%s,mapID=%s,funcLineID=%s" % (zoneID, mapID, funcLineID)) + break + + key = (realMapID, copyMapID) + if key in PyGameData.g_crossDynamicLineCopyMapInfo: + copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] + copyMapObj.openState = IPY_PlayerDefine.fbosWaitForClose + + #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) + #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineCopyMapInfo=%s" % PyGameData.g_crossDynamicLineCopyMapInfo) + return + +def OnCrossDynamicLineClose(mapID, copyMapID): + ## 动态分配线路的地图虚拟线路关闭 + dataMapID = GetRecordMapID(mapID) GameWorld.Log("动态分配虚拟线路关闭 dataMapID=%s,mapID=%s,copyMapID=%s" % (dataMapID, mapID, copyMapID)) zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(dataMapID, {}) for key, funcLineObjList in zoneLineDict.items(): for funcLineObj in funcLineObjList: - if funcLineObj.mapID == mapID and funcLineObj.copyMapID == copyMapID: - funcLineObj.OnCopyMapClose(funcLineDataCache) + if funcLineObj.realMapID == mapID and funcLineObj.copyMapID == copyMapID: + funcLineObj.OnCopyMapClose() zoneID, funcLineID = key GameWorld.Log(" 分区对应功能线路虚拟分线关闭: zoneID=%s,dataMapID%s,funcLineID=%s" % (zoneID, dataMapID, funcLineID)) break @@ -320,21 +364,21 @@ #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineCopyMapInfo=%s" % PyGameData.g_crossDynamicLineCopyMapInfo) return -def OnCrossDynamicMapReset(mapID, copyMapCount): +def OnCrossDynamicMapReset(msgList): ## 动态分配线路的地图重置 + realMapID, copyMapCount = msgList + mapID = GetRecordMapID(realMapID) + GameWorld.Log("动态分配虚拟线路地图重置 mapID=%s,realMapID=%s,copyMapCount=%s" % (mapID, realMapID, copyMapCount)) + PyGameData.g_crossMapCopyMapCountDict[realMapID] = copyMapCount - dataMapID = GetRecordMapID(mapID) - GameWorld.Log("动态分配虚拟线路地图重置 dataMapID=%s,mapID=%s,copyMapCount=%s" % (dataMapID, mapID, copyMapCount)) - PyGameData.g_crossMapCopyMapCountDict[mapID] = copyMapCount - - zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(dataMapID, {}) + zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {}) for key, funcLineObjList in zoneLineDict.items(): for funcLineObj in funcLineObjList: - if funcLineObj.mapID == mapID: - funcLineObj.OnCopyMapClose(None) + if funcLineObj.realMapID == realMapID: + funcLineObj.OnCopyMapClose() for key in PyGameData.g_crossDynamicLineCopyMapInfo.keys(): - if key[0] == mapID: + if key[0] == realMapID: PyGameData.g_crossDynamicLineCopyMapInfo.pop(key) #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) -- Gitblit v1.8.0