hch
2019-04-19 f37fe3b1d7b81b2dcdaeeb81971a6cbdf0b9372d
Merge branch 'master' of http://192.168.0.87:10010/r/SnxxServerCode
10个文件已修改
291 ■■■■■ 已修改文件
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossGrassland.py 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
@@ -52,6 +52,11 @@
    curPlayer.NotifyCode(msgMark, __GetNotifyCodeList(msgParamList))
    return
def CrossNotifyCode(serverGroupID, playerID, msgMark, msgParamList=[]):
    crossNotifyList = [{"Type":ShareDefine.CrossNotify_Player, "Params":[playerID, msgMark, msgParamList]}]
    CrossNotify([serverGroupID], crossNotifyList)
    return
def GetCrossWorldNotifyInfo(country, msgMark, msgParamList=[]):
    return {"Type":ShareDefine.CrossNotify_World, "Params":[country, msgMark, msgParamList]}
@@ -79,7 +84,11 @@
        elif notifyType == ShareDefine.CrossNotify_Family:
            familyID, msgMark, msgParamList = params
            FamilyNotify(familyID, msgMark, msgParamList)
        elif notifyType == ShareDefine.CrossNotify_Player:
            playerID, msgMark, msgParamList = params
            curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
            if curPlayer:
                NotifyCode(curPlayer, msgMark, msgParamList)
    return
    
## 世界广播
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,37 @@
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:
    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
        
    elif dataMapID in [ChConfig.Def_FBMapID_CrossGrasslandLing, ChConfig.Def_FBMapID_CrossGrasslandXian]:
        copyMapPlayerMax = 10
    elif mapID in [ChConfig.Def_FBMapID_CrossGrasslandLing, ChConfig.Def_FBMapID_CrossGrasslandXian]:
        pass
        
    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 +181,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 +197,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 +310,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 +365,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)
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -512,19 +512,12 @@
        PlayerControl.CrossNotify(serverGroupIDList, crossNotifyList)
        return
    
    if callName == "DynamicLineMapOpen":
        realMapID, copyMapID = eval(resultName)
        PlayerFB.OnCrossDynamicLineOpen(realMapID, copyMapID)
        return
    if callName == "DynamicLineMapClose":
        realMapID, copyMapID, funcLineDataCache = eval(resultName)
        PlayerFB.OnCrossDynamicLineClose(realMapID, copyMapID, funcLineDataCache)
    if callName == "DynamicLineMapStateChange":
        PlayerFB.OnCrossDynamicLineStateChange(eval(resultName))
        return
    
    if callName == "DynamicLineMapInitOK":
        realMapID, copyMapCount = eval(resultName)
        PlayerFB.OnCrossDynamicMapReset(realMapID, copyMapCount)
        PlayerFB.OnCrossDynamicMapReset(eval(resultName))
        return
    
    if callName == "CommMapServerInitOK":
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1236,6 +1236,7 @@
#跨服广播类型定义
CrossNotify_World = "World"
CrossNotify_Family = "Family"
CrossNotify_Player = "Player"
#角色改名结果
(
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
@@ -2189,6 +2189,14 @@
    
    return callFunc(curPlayer, mapID, lineID, exData)
## 跨服功能线路数据缓存,下次开启同样功能线路时会用该数据进行还原之前的副本状态
def OnGetCrossFuncLineDataCache():
    do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnGetCrossFuncLineDataCache"))
    if callFunc == None:
        return
    return callFunc()
def OnPlayerLVUp(curPlayer):
    ## 玩家升级
    do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossGrassland.py
@@ -35,7 +35,7 @@
    if eventType == PlayerFairyDomain.FDEventType_GrasslandXian:
        npcID = IpyGameDataPY.GetFuncCfg("CrossGrasslandCfg", 1)
        if npcID:
            NPCCommon.UpdateNPCAttackCount(curPlayer, [npcID], 0)
            NPCCommon.UpdateNPCAttackCount(curPlayer, npcID, 0)
            
    return
    
@@ -53,13 +53,18 @@
        return False
    return True
## 跨服功能线路数据缓存,下次开启同样功能线路时会用该数据进行还原之前的副本状态
def OnGetCrossFuncLineDataCache():
    refreshNPCInfo = NPCCustomRefresh.GetCopyMapRandomRefreshNPCInfo()
    return refreshNPCInfo
## 开启副本
def OnOpenFB(tick):
    gameWorld = GameWorld.GetGameWorld()
    realMapID, copyMapID = gameWorld.GetRealMapID(), gameWorld.GetCopyMapID()
    key = (realMapID, copyMapID)
    if key in PyGameData.g_crossFuncLineDataCache:
        refreshNPCInfo = PyGameData.g_crossFuncLineDataCache[key]
        refreshNPCInfo = PyGameData.g_crossFuncLineDataCache.pop(key)
        GameWorld.DebugLog("副本开启根据保存的虚拟线路标试点刷怪信息刷怪: realMapID=%s,copyMapID=%s,refreshNPCInfo=%s" % (realMapID, copyMapID, refreshNPCInfo))
        NPCCustomRefresh.OnFBOpenSetRandomRefreshNPCInfo(refreshNPCInfo, tick)
        
@@ -81,26 +86,17 @@
    GameWorld.Log("DoEnterFB zoneID=%s,funcLineID=%s" % (zoneID, funcLineID), playerID)
    return
## 副本总逻辑计时器
def OnProcess(tick):
    return
## 关闭副本
def OnCloseFB(tick):
    gameWorld = GameWorld.GetGameWorld()
    refreshNPCInfo = NPCCustomRefresh.GetCopyMapRandomRefreshNPCInfo()
    if refreshNPCInfo:
        realMapID, copyMapID = gameWorld.GetRealMapID(), gameWorld.GetCopyMapID()
        key = (realMapID, copyMapID)
        PyGameData.g_crossFuncLineDataCache[key] = refreshNPCInfo
        GameWorld.DebugLog("缓存虚拟线路标试点刷怪信息: realMapID=%s,copyMapID=%s,refreshNPCInfo=%s" % (realMapID, copyMapID, refreshNPCInfo))
    GameWorld.GetGameWorld().SetPropertyID(0)
    return
## 玩家退出副本
def DoExitFB(curPlayer, tick):
    return
### 副本总逻辑计时器
#def OnProcess(tick):
#    return
#
### 关闭副本
#def OnCloseFB(tick):
#    return
#
### 玩家退出副本
#def DoExitFB(curPlayer, tick):
#    return
##玩家主动离开副本.
def DoPlayerLeaveFB(curPlayer, tick):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
@@ -77,8 +77,7 @@
    FBLogic.OnOpenFB(tick)
    
    if gameWorld.GetMapID() in ChConfig.Def_CrossDynamicLineMap:
        msgInfo = str([gameWorld.GetRealMapID(), gameWorld.GetCopyMapID()])
        GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "DynamicLineMapOpen", msgInfo, len(msgInfo))
        GameServer_DynamicLineMapStateChange(gameWorld, IPY_GameWorld.fbosOpen)
    return
## 副本关闭
@@ -97,7 +96,7 @@
    gameFBMgr = gameWorld.GetGameFB() 
    gameFBMgr.SetPlayerLogoffTick(0)
    gameFBMgr.SetIsSafeClose(0)
    lineID = gameWorld.GetLineID()
    GameWorld.Log("FB Close! lineID = %s, openState = %s"%(lineID, gameWorld.GetOpenState()))
    
@@ -172,11 +171,21 @@
    FreeOrClearFBByAutoSize(gameWorld)
    
    if gameWorld.GetMapID() in ChConfig.Def_CrossDynamicLineMap:
        realMapID, copyMapID = gameWorld.GetRealMapID(), gameWorld.GetCopyMapID()
        key = (mapID, copyMapID)
        funcLineDataCache = PyGameData.g_crossFuncLineDataCache.pop(key, None)
        msgInfo = str([realMapID, copyMapID, funcLineDataCache])
        GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "DynamicLineMapClose", msgInfo, len(msgInfo))
        GameServer_DynamicLineMapStateChange(gameWorld, IPY_GameWorld.fbosClosed)
    gameWorld.SetPropertyID(0)
    return
def GameServer_DynamicLineMapStateChange(gameWorld, state):
    realMapID, copyMapID = gameWorld.GetRealMapID(), gameWorld.GetCopyMapID()
    if state == IPY_GameWorld.fbosWaitForClose:
        crossFuncLineDataCache = FBLogic.OnGetCrossFuncLineDataCache()
        msgInfo = [realMapID, copyMapID, state, crossFuncLineDataCache]
    else:
        msgInfo = [realMapID, copyMapID, state]
    msgInfo = str(msgInfo)
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "DynamicLineMapStateChange", msgInfo, len(msgInfo))
    return
##根据表中的收缩类型释放或者清空副本状态
@@ -612,6 +621,10 @@
#  @remarks 函数详细说明.
def CloseFB(tick):
    GameWorld.GetGameWorld().SetCloseFBTick(tick)
    gameWorld = GameWorld.GetGameWorld()
    if gameWorld.GetMapID() in ChConfig.Def_CrossDynamicLineMap:
        GameServer_DynamicLineMapStateChange(gameWorld, IPY_GameWorld.fbosWaitForClose)
    return
## 玩家离开地图时,尝试关闭副本
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -5690,7 +5690,7 @@
        updCollTime = curCollTime + collectCnt
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime)
        SyncCollNPCTime(curPlayer, [npcID])
        GameWorld.DebugLog("        增加采集次数: npcID=%s,todayCollTime=%s,curCollTime=%s,updCollTime=%s" % (npcID, todayCollTime, curCollTime, updCollTime))
        GameWorld.DebugLog("    增加采集次数: npcID=%s,todayCollTime=%s,curCollTime=%s,updCollTime=%s" % (npcID, todayCollTime, curCollTime, updCollTime))
        isMaxTime = todayCollTime + collectCnt >= limitMaxTime
        
    awardItemList = []
@@ -5701,7 +5701,7 @@
        if collTotalTime in collectAppointAwardCfg:
            awardItemList.append(collectAppointAwardCfg[collTotalTime])
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTimeTotal % npcID, collTotalTime)
        #GameWorld.DebugLog("采集次数定制奖励: collTotalTime=%s,awardItemList=%s" % (collTotalTime, awardItemList))
        GameWorld.DebugLog("    采集次数定制奖励: collTotalTime=%s,awardItemList=%s" % (collTotalTime, awardItemList))
        
    if not awardItemList:
        alchemyDiffLV = collectNPCIpyData.GetAlchemyDiffLV()
@@ -5719,9 +5719,12 @@
        else:
            giveItemWeightList = collectAwardCfg
            
        GameWorld.DebugLog("    常规采集物品权重列表: alchemyDiffLV=%s,collectAwardCfg=%s,giveItemWeightList=%s" % (alchemyDiffLV, collectAwardCfg, giveItemWeightList))
        giveItemInfo = GameWorld.GetResultByWeightList(giveItemWeightList)
        awardItemList.append(giveItemInfo)
        if giveItemInfo:
            awardItemList.append(giveItemInfo)
    GameWorld.DebugLog("    最终采集奖励: awardItemList=%s" % awardItemList)
    if awardItemList:
        for itemID, itemCount, isAuctionItem in awardItemList:
            ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem])
@@ -5736,7 +5739,9 @@
                awardPack.AwardItemList.append(awardItem)
            awardPack.Count = len(awardPack.AwardItemList)
            NetPackCommon.SendFakePack(curPlayer, awardPack)
    else:
        GameWorld.ErrLog("采集物品没有奖励!npcID=%s" % (npcID))
    #采集成就
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, collectCnt, [npcID])
    #SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -1644,7 +1644,7 @@
                return
            extendInfo["BossID"] = bossID
            
        msgDict = {"PlayerID":curPlayer.GetPlayerID(), "DataMapID":mapID, "FuncLineID":lineID}
        msgDict = {"PlayerID":curPlayer.GetPlayerID(), "MapID":mapID, "FuncLineID":lineID}
        if extendInfo:
            msgDict.update(extendInfo)
        GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_EnterFB, msgDict)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1236,6 +1236,7 @@
#跨服广播类型定义
CrossNotify_World = "World"
CrossNotify_Family = "Family"
CrossNotify_Player = "Player"
#角色改名结果
(