From f12bbdcbaebff76914ae6dc735941d19f8f4e87f Mon Sep 17 00:00:00 2001 From: hch <305670599@qq.com> Date: 星期二, 25 六月 2019 02:00:11 +0800 Subject: [PATCH] 860312 印记飘字的优先级高于压制 --- ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py | 424 +++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 318 insertions(+), 106 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py index 4b3114f..a316f70 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py @@ -30,14 +30,60 @@ import PlayerTeam import GameWorld import ChConfig +import IPY_PlayerDefine import CrossRealmPlayer import CrossRealmMsg import ShareDefine import CrossBoss -import random #--------------------------------------------------------------------- +## 跨服地图动态分配的功能线路,如果有人数上限的,则同分区同地图玩法的可能同时存在多个相同功能线路的数据 +class CrossFuncLineInfo(): + + def __init__(self): + self.realMapID = 0 + self.copyMapID = 0 + self.funcLineDataCache = None # 功能线路自定义缓存数据 + return + + def OnCopyMapClose(self): + self.realMapID = 0 + self.copyMapID = 0 + return + +## 跨服地图动态分配的虚拟线路信息 +class CrossCopyMapInfo(): + + def __init__(self, zoneID, funcLineID): + self.zoneID = zoneID + self.funcLineID = funcLineID + 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): + # 已经在请求队列里,可进入 + if playerID in self.waitPlayerDict or not copyMapPlayerMax: + self.waitPlayerDict[playerID] = [serverGroupID, tick] + return True + + # 移除请求进入超时的玩家 + for waitPlayerID, playerInfo in self.waitPlayerDict.items(): + serverGroupID, requestTick = playerInfo + if tick - requestTick > 60000: # 请求进入时间保留1分钟 + self.waitPlayerDict.pop(waitPlayerID) + + # 判断是否超过人数上限 + fbPlayerCount, waitPlayerCount = len(self.fbPlayerDict), len(self.waitPlayerDict) + if fbPlayerCount + waitPlayerCount >= copyMapPlayerMax: + return False + + self.waitPlayerDict[playerID] = [serverGroupID, tick] + return True + #--------------------------------------------------------------------- def GetFBLineIpyData(mapID, lineID, isDefaultLine=True): mapID = GetRecordMapID(mapID) @@ -76,184 +122,350 @@ return dataMapID return mapID -def ClientServerMsg_EnterFB(serverGroupID, msgData): +def ClientServerMsg_EnterFB(serverGroupID, msgData, tick): ## 收到子服请求进入动态分配的跨服副本 playerID = msgData["PlayerID"] - dataMapID = msgData["DataMapID"] + mapID = msgData["MapID"] funcLineID = msgData["FuncLineID"] - if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing: - zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(dataMapID, serverGroupID) - if not zoneIpyData: - return - zoneID = zoneIpyData.GetZoneID() + zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID) + if not zoneIpyData: + return + zoneID = zoneIpyData.GetZoneID() + + 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): GameWorld.DebugLog("当前跨服妖王死亡状态,不可进入! serverGroupID=%s,funcLineID=%s,zoneID=%s,bossID=%s" % (serverGroupID, funcLineID, zoneID, bossID)) return - mapCopyLineInfo = __GetCrossDynamicLineInfo(dataMapID, funcLineID, zoneID) - if not mapCopyLineInfo: - return - mapID, copyMapID, isOpenNew = mapCopyLineInfo + elif mapID in [ChConfig.Def_FBMapID_CrossGrasslandLing, ChConfig.Def_FBMapID_CrossGrasslandXian]: + pass - # 如果是等待线路启动中的直接返回,等启动好后再通知可进入 - if __AddWaitCrossFBOpenPlayer(mapID, copyMapID, isOpenNew, playerID, serverGroupID): - return else: return + mapCopyLineInfo = __GetCrossDynamicLineInfo(playerID, serverGroupID, mapID, funcLineID, zoneID, copyMapPlayerMax, tick) + if not mapCopyLineInfo: + return + realMapID, copyMapID, openState = mapCopyLineInfo + if openState != IPY_PlayerDefine.fbosOpen: + return + playerIDList = [playerID] - retInfo = [playerIDList, dataMapID, mapID, copyMapID] + retInfo = [playerIDList, mapID, realMapID, copyMapID, funcLineID] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID]) return def CrossServerMsg_EnterFBRet(msgData, tick): ## 收到跨服服务器动态分配的跨服副本进入信息 - playerIDList, dataMapID, mapID, copyMapID = msgData - - if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing: - mapPosInfo = IpyGameDataPY.GetFuncEvalCfg("CrossDemonKingMap", 2) - else: - return - posX, posY = mapPosInfo + playerIDList, dataMapID, mapID, copyMapID, funcLineID = msgData for playerID in playerIDList: curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if not curPlayer: continue - CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, mapID, dataMapID, copyMapID, posX, posY) + CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, mapID, dataMapID, copyMapID, lineID=funcLineID) return -def __GetCrossDynamicLineInfo(dataMapID, funcLineID, zoneID): - ## 获取跨服分区对应动态分配的副本地图虚拟线路信息 - - isOpenNew = False +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):[mapID, copyMapID], ...}, ...} - if zoneLineKey in zoneLineDict: - mapID, copyMapID = zoneLineDict[zoneLineKey] - GameWorld.DebugLog("已存在该分区功能线路ID,不需要重新分配: zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s" % (zoneID, funcLineID, mapID, copyMapID)) - return mapID, copyMapID, isOpenNew + 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] - if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing: - mapIDList = IpyGameDataPY.GetFuncEvalCfg("CrossDemonKingMap", 1) + newFuncLineNum = None + newFuncLineObj = None + for index, funcLineObj in enumerate(funcLineObjList, 1): + realMapID, copyMapID = funcLineObj.realMapID, funcLineObj.copyMapID + if not realMapID: + if not newFuncLineObj: + newFuncLineNum, newFuncLineObj = index, funcLineObj + continue - # 其他地图待扩展 - else: - return + key = (realMapID, copyMapID) + if key not in PyGameData.g_crossDynamicLineCopyMapInfo: + 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("可进入动态分布的虚拟线路! realMapID=%s,copyMapID=%s,openState=%s" % (realMapID, copyMapID, openState)) + #GameWorld.DebugLog(" 副本中的玩家ID: %s" % copyMapObj.fbPlayerDict) + #GameWorld.DebugLog(" 等待中的玩家ID: %s" % copyMapObj.waitPlayerDict) + return realMapID, copyMapID, openState + + dynamicLineMapDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 1) + dynamicMapIDList = dynamicLineMapDict.get(mapID, [mapID]) - usedMapCopyList = zoneLineDict.values() # 已经使用中的地图虚拟线路 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 usedMapCopyList: - 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 - isOpenNew = True - mapID, copyMapID = openMapID, openCopyMapID - zoneLineDict[zoneLineKey] = [mapID, copyMapID] - propertyID = zoneID * 1000 + funcLineID - GameWorld.DebugLog("不存在该分区功能线路ID,重新分配: zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s,propertyID=%s" - % (zoneID, funcLineID, mapID, copyMapID, propertyID)) + if newFuncLineObj == None: + newFuncLineObj = CrossFuncLineInfo() + funcLineObjList.append(newFuncLineObj) + newFuncLineNum = len(funcLineObjList) + realMapID, copyMapID = openMapID, openCopyMapID + newFuncLineObj.realMapID = realMapID + newFuncLineObj.copyMapID = copyMapID + funcLineDataCache = newFuncLineObj.funcLineDataCache + + 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,realMapID=%s,copyMapID=%s,propertyID=%s" + % (zoneID, funcLineID, realMapID, copyMapID, propertyID)) # 通知地图开启新的地图虚拟分线 - msgInfo = str([copyMapID, propertyID]) - GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, mapID, "OpenFB", msgInfo, len(msgInfo)) - return mapID, copyMapID, isOpenNew + msgInfo = str([copyMapID, propertyID, funcLineDataCache]) + GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, realMapID, "OpenFB", msgInfo, len(msgInfo)) + return realMapID, copyMapID, openState -def __AddWaitCrossFBOpenPlayer(mapID, copyMapID, isOpenNew, playerID, serverGroupID): - ## 添加跨服玩家进入等待动态副本虚拟线路开启队列 - - if mapID not in PyGameData.g_crossDynamicLineOpeningInfo: - PyGameData.g_crossDynamicLineOpeningInfo[mapID] = {} - openingMapCopyIDDict = PyGameData.g_crossDynamicLineOpeningInfo[mapID] # 跨服动态线路正在开启中的线路信息 {mapID:{copyMapID:{playerID:serverGroupID, ...}, ...}, ...} - - if isOpenNew or copyMapID in openingMapCopyIDDict: - if copyMapID not in openingMapCopyIDDict: - openingMapCopyIDDict[copyMapID] = {} - waitingPlayerDict = openingMapCopyIDDict[copyMapID] - waitingPlayerDict[playerID] = serverGroupID - GameWorld.Log("添加玩家进入等待跨服动态副本虚拟线路开启队列: mapID=%s,copyMapID=%s,isOpenNew=%s,playerID=%s,serverGroupID=%s" - % (mapID, copyMapID, isOpenNew, playerID, serverGroupID)) - GameWorld.Log(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo) - return True - return False +def GetCrossDynamicLineZoneID(mapID, realMapID, copyMapID): + ## 获取跨服动态分配的虚拟线路对应分区ID + zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {}) + for key, funcLineObjList in zoneLineDict.items(): + for funcLineObj in funcLineObjList: + 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): ## 动态分配线路的地图虚拟线路启动成功 - if mapID not in PyGameData.g_crossDynamicLineOpeningInfo: + key = (realMapID, copyMapID) + if key not in PyGameData.g_crossDynamicLineCopyMapInfo: return - openingCopyMapDict = PyGameData.g_crossDynamicLineOpeningInfo[mapID] - waitingPlayerDict = openingCopyMapDict.pop(copyMapID, {}) - if not waitingPlayerDict: - return + copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] + copyMapObj.openState = IPY_PlayerDefine.fbosOpen + funcLineID = copyMapObj.funcLineID # 通知子服等待中的玩家可以进入副本 serverPlayerIDListDict = {} - for playerID, serverGroupID in waitingPlayerDict.items(): + for playerID, playerInfo in copyMapObj.waitPlayerDict.items(): + serverGroupID = playerInfo[0] if serverGroupID not in serverPlayerIDListDict: serverPlayerIDListDict[serverGroupID] = [] 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] + 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_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo) + #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) + #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineCopyMapInfo=%s" % PyGameData.g_crossDynamicLineCopyMapInfo) + return + +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, mapCopyInfo in zoneLineDict.items(): - if mapCopyInfo[0] == mapID and mapCopyInfo[1] == copyMapID: - zoneLineDict.pop(key) - break - - openingCopyMapDict = PyGameData.g_crossDynamicLineOpeningInfo.get(mapID, {}) - openingCopyMapDict.pop(copyMapID, {}) + for key, funcLineObjList in zoneLineDict.items(): + for funcLineObj in funcLineObjList: + 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 - GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) - GameWorld.DebugLog(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo) + key = (mapID, copyMapID) + 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(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, {}) - for key, mapCopyInfo in zoneLineDict.items(): - if mapCopyInfo[0] == mapID: - zoneLineDict.pop(key) + zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {}) + for key, funcLineObjList in zoneLineDict.items(): + for funcLineObj in funcLineObjList: + if funcLineObj.realMapID == realMapID: + funcLineObj.OnCopyMapClose() - PyGameData.g_crossDynamicLineOpeningInfo.pop(mapID, None) + for key in PyGameData.g_crossDynamicLineCopyMapInfo.keys(): + if key[0] == realMapID: + PyGameData.g_crossDynamicLineCopyMapInfo.pop(key) + + #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) + #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineCopyMapInfo=%s" % PyGameData.g_crossDynamicLineCopyMapInfo) return +def PlayerLoginLoadCrossMapOK(curPlayer): + ## 玩家登录跨服地图 + + mapID, copyMapID = curPlayer.GetRealMapID(), curPlayer.GetFBID() + key = (mapID, copyMapID) + if key not in PyGameData.g_crossDynamicLineCopyMapInfo: + return + copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] + + 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): + ## 玩家离开跨服服务器 + + mapID, copyMapID = curPlayer.GetRealMapID(), curPlayer.GetFBID() + key = (mapID, copyMapID) + if key not in PyGameData.g_crossDynamicLineCopyMapInfo: + return + copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] + + playerID = curPlayer.GetPlayerID() + copyMapObj.waitPlayerDict.pop(playerID, None) + copyMapObj.fbPlayerDict.pop(playerID, None) + + 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 + +##-------------------------------------------------------------------------------------------------- + ## 请求进入副本分线 # @param curPlayer: 请求玩家 # @param queryCallName: 请求回调名 -- Gitblit v1.8.0