ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -21,13 +21,21 @@
#---------------------------------------------------------------------
import GameWorldBoss
import PlayerFamilyBoss
import PlayerHorsePetBoss
import GameWorldFamilyWar
import PlayerControl
import PyGameData
import IpyGameDataPY
import PlayerDBGSEvent
import PlayerTeam
import GameWorld
import ChConfig
import CrossRealmPlayer
import CrossRealmMsg
import ShareDefine
import CrossBoss
import random
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -68,6 +76,187 @@
            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[: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)
    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: 请求回调名
@@ -103,7 +292,7 @@
        return
    
    #封魔坛副本判断里面的BOSS是否到了刷新时间
    if tagMapID == ChConfig.Def_FBMapID_SealDemon:
    if tagMapID in ChConfig.WorldBossFBMapIDList:
        bossID = mapInfo[2]
        if not GameWorldBoss.GetBossIsAliveOrCanReborn(bossID):
            return
@@ -121,7 +310,22 @@
        if curPlayer.GetFamilyID() in PyGameData.g_swrhJoinRecord:
            PlayerControl.NotifyCode(curPlayer, "TheEmperor1")
            return
    #多仙盟BOSS 是否已结束
    elif tagMapID == ChConfig.Def_FBMapID_AllFamilyBoss:
        if not PlayerFamilyBoss.IsInAllFamilyBoss(tagLineID):
            #活动未开启
            return
        if PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_AllFamilyBossTime):
            #BOSS已被击杀
            return
    #骑宠BOSS 是否已结束
    elif tagMapID == ChConfig.Def_FBMapID_HorsePetBoss:
        if not PlayerHorsePetBoss.IsInHorsePetBoss():
            #活动未开启
            return
        if PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_HorsePetBossTime % tagLineID):
            #BOSS已被击杀
            return
    # MapServer_QueryPlayer(int srcPlayerID, int queryType, int queryID, int mapID, char *callName, char *cmd,WORD cmdLen, int RouteServerIndex)
    playerManager.MapServer_QueryPlayer(curPlayer.GetPlayerID(), ChConfig.queryType_EnterFB, 0, tagMapID,
                queryCallName, sendCMD, len(sendCMD), curPlayer.GetRouteServerIndex())