ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -30,6 +30,12 @@
import PlayerTeam
import GameWorld
import ChConfig
import CrossRealmPlayer
import CrossRealmMsg
import ShareDefine
import CrossBoss
import random
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -70,6 +76,184 @@
            return dataMapID
    return mapID
def ClientServerMsg_EnterFB(serverGroupID, msgData):
    ## 收到子服请求进入动态分配的跨服副本
    playerID = msgData["PlayerID"]
    dataMapID = msgData["DataMapID"]
    funcLineID = msgData["FuncLineID"]
    if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing:
        zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(dataMapID, serverGroupID)
        if not zoneIpyData:
            return
        zoneID = zoneIpyData.GetZoneID()
        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
        # 如果是等待线路启动中的直接返回,等启动好后再通知可进入
        if __AddWaitCrossFBOpenPlayer(mapID, copyMapID, isOpenNew, playerID, serverGroupID):
            return
    else:
        return
    playerIDList = [playerID]
    retInfo = [playerIDList, dataMapID, mapID, copyMapID]
    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
    for playerID in playerIDList:
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
        if not curPlayer:
            continue
        CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, mapID, dataMapID, copyMapID, posX, posY)
    return
def __GetCrossDynamicLineInfo(dataMapID, funcLineID, zoneID):
    ## 获取跨服分区对应动态分配的副本地图虚拟线路信息
    isOpenNew = False
    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 dataMapID == ChConfig.Def_FBMapID_CrossDemonKing:
        mapIDList = IpyGameDataPY.GetFuncEvalCfg("CrossDemonKingMap", 1)
    # 其他地图待扩展
    else:
        return
    usedMapCopyList = zoneLineDict.values() # 已经使用中的地图虚拟线路
    openMapID, openCopyMapID = 0, 0
    for mapID in mapIDList:
        maxCopyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(mapID, 0)
        for copyMapID in xrange(maxCopyMapCount):
            if [mapID, copyMapID] not in usedMapCopyList:
                openMapID, openCopyMapID = mapID, copyMapID
                break
        if openMapID:
            break
    if not openMapID:
        GameWorld.ErrLog("没有空余的虚拟线路,无法动态开启跨服副本!dataMapID=%s, funcLineID=%s, zoneID=%s, mapIDList=%s"
                         % (dataMapID, funcLineID, zoneID, mapIDList))
        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))
    # 通知地图开启新的地图虚拟分线
    msgInfo = str([copyMapID, propertyID])
    GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, mapID, "OpenFB", msgInfo, len(msgInfo))
    return mapID, copyMapID, isOpenNew
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 OnCrossDynamicLineOpen(mapID, copyMapID):
    ## 动态分配线路的地图虚拟线路启动成功
    if mapID not in PyGameData.g_crossDynamicLineOpeningInfo:
        return
    openingCopyMapDict = PyGameData.g_crossDynamicLineOpeningInfo[mapID]
    waitingPlayerDict = openingCopyMapDict.pop(copyMapID, {})
    if not waitingPlayerDict:
        return
    # 通知子服等待中的玩家可以进入副本
    serverPlayerIDListDict = {}
    for playerID, serverGroupID in waitingPlayerDict.items():
        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))
    for serverGroupID, playerIDList in serverPlayerIDListDict.items():
        retInfo = [playerIDList, dataMapID, mapID, copyMapID]
        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)
    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, {})
    GameWorld.DebugLog("    PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo)
    GameWorld.DebugLog("    PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo)
    return
def OnCrossDynamicMapReset(mapID, 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)
    PyGameData.g_crossDynamicLineOpeningInfo.pop(mapID, None)
    return
## 请求进入副本分线
#  @param curPlayer: 请求玩家
#  @param queryCallName: 请求回调名