From 68dd06e06c1a4a155884c31403da1155be6f10e8 Mon Sep 17 00:00:00 2001
From: hch <305670599@qq.com>
Date: 星期四, 18 四月 2019 17:11:31 +0800
Subject: [PATCH] Merge branch 'master' of http://192.168.0.87:10010/r/SnxxServerCode
---
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py | 331 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 330 insertions(+), 1 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
index 9436b24..b22e5d8 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -21,15 +21,69 @@
#---------------------------------------------------------------------
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
#---------------------------------------------------------------------
+## 跨服地图动态分配的功能线路,如果有人数上限的,则同分区同地图玩法的可能同时存在多个相同功能线路的数据
+class CrossFuncLineInfo():
+
+ def __init__(self):
+ self.mapID = 0
+ self.copyMapID = 0
+ self.funcLineDataCache = None # 功能线路自定义缓存数据
+ return
+
+ def OnCopyMapClose(self, funcLineDataCache):
+ self.mapID = 0
+ self.copyMapID = 0
+ self.funcLineDataCache = funcLineDataCache
+ return
+
+## 跨服地图动态分配的虚拟线路信息
+class CrossCopyMapInfo():
+
+ def __init__(self, zoneID, funcLineID):
+ self.zoneID = zoneID
+ self.funcLineID = funcLineID
+ self.openState = 0
+ self.fbPlayerDict = {} # 副本中的玩家信息 {playerID:serverGroupID, ...}
+ self.waitPlayerDict = {} # 等待进入的玩家信息 {playerID:[serverGroupID, tick], ...}
+ 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)
@@ -67,6 +121,266 @@
if mapID in mapIDList:
return dataMapID
return mapID
+
+def ClientServerMsg_EnterFB(serverGroupID, msgData, tick):
+ ## 收到子服请求进入动态分配的跨服副本
+ playerID = msgData["PlayerID"]
+ dataMapID = msgData["DataMapID"]
+ funcLineID = msgData["FuncLineID"]
+
+ zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(dataMapID, serverGroupID)
+ if not zoneIpyData:
+ return
+ zoneID = zoneIpyData.GetZoneID()
+
+ copyMapPlayerMax = 0 # 0为不限制人数,默认不限制
+ if dataMapID == 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
+
+ else:
+ return
+
+ mapCopyLineInfo = __GetCrossDynamicLineInfo(playerID, serverGroupID, dataMapID, funcLineID, zoneID, copyMapPlayerMax, tick)
+ if not mapCopyLineInfo:
+ return
+ mapID, copyMapID, openState = mapCopyLineInfo
+ if not openState:
+ return
+
+ playerIDList = [playerID]
+ retInfo = [playerIDList, dataMapID, mapID, copyMapID, funcLineID]
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID])
+ return
+
+def CrossServerMsg_EnterFBRet(msgData, tick):
+ ## 收到跨服服务器动态分配的跨服副本进入信息
+
+ playerIDList, dataMapID, mapID, copyMapID, funcLineID = msgData
+
+ dynamicLineMapDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 1)
+ if dataMapID not in dynamicLineMapDict:
+ return
+ mapPosInfo = dynamicLineMapDict[dataMapID][0]
+ 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, lineID=funcLineID)
+
+ return
+
+def __GetCrossDynamicLineInfo(playerID, serverGroupID, dataMapID, 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 zoneLineKey not in zoneLineDict:
+ zoneLineDict[zoneLineKey] = []
+ funcLineObjList = zoneLineDict[zoneLineKey]
+
+ 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
+
+ key = (mapID, copyMapID)
+ if key not in PyGameData.g_crossDynamicLineCopyMapInfo:
+ GameWorld.ErrLog("已经分配的虚拟线路不存在缓存对应关系里!zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s"
+ % (zoneID, funcLineID, mapID, copyMapID))
+ continue
+
+ copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key]
+ openState = copyMapObj.openState
+ canEnter = copyMapObj.OnRequestEnterCrossCopyMap(playerID, serverGroupID, tick, copyMapPlayerMax)
+ if canEnter:
+ #GameWorld.DebugLog("可进入动态分布的虚拟线路! mapID=%s,copyMapID=%s,openState=%s" % (mapID, copyMapID, openState))
+ #GameWorld.DebugLog(" 副本中的玩家ID: %s" % copyMapObj.fbPlayerDict)
+ #GameWorld.DebugLog(" 等待中的玩家ID: %s" % copyMapObj.waitPlayerDict)
+ return mapID, copyMapID, openState
+
+ dynamicLineMapDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 1)
+ if dataMapID not in dynamicLineMapDict:
+ return
+ mapIDList = dynamicLineMapDict[dataMapID][1]
+
+ 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 PyGameData.g_crossDynamicLineCopyMapInfo:
+ 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
+
+ if newFuncLineObj == None:
+ newFuncLineObj = CrossFuncLineInfo()
+ funcLineObjList.append(newFuncLineObj)
+ newFuncLineNum = len(funcLineObjList)
+ mapID, copyMapID = openMapID, openCopyMapID
+ newFuncLineObj.mapID = mapID
+ newFuncLineObj.copyMapID = copyMapID
+ funcLineDataCache = newFuncLineObj.funcLineDataCache
+
+ key = (mapID, 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))
+
+ # 通知地图开启新的地图虚拟分线
+ msgInfo = str([copyMapID, propertyID, funcLineDataCache])
+ GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, mapID, "OpenFB", msgInfo, len(msgInfo))
+ return mapID, copyMapID, openState
+
+def GetCrossDynamicLineZoneID(dataMapID, mapID, copyMapID):
+ ## 获取跨服动态分配的虚拟线路对应分区ID
+ zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(dataMapID, {})
+ for key, funcLineObjList in zoneLineDict.items():
+ for funcLineObj in funcLineObjList:
+ if funcLineObj.mapID == mapID and funcLineObj.copyMapID == copyMapID:
+ zoneID = key[0]
+ return zoneID
+ return 0
+
+def OnCrossDynamicLineOpen(mapID, copyMapID):
+ ## 动态分配线路的地图虚拟线路启动成功
+
+ key = (mapID, copyMapID)
+ if key not in PyGameData.g_crossDynamicLineCopyMapInfo:
+ return
+ copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key]
+ copyMapObj.openState = 1
+ funcLineID = copyMapObj.funcLineID
+
+ # 通知子服等待中的玩家可以进入副本
+ serverPlayerIDListDict = {}
+ 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))
+ for serverGroupID, playerIDList in serverPlayerIDListDict.items():
+ retInfo = [playerIDList, dataMapID, mapID, 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):
+ ## 动态分配线路的地图虚拟线路关闭
+
+ 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)
+ zoneID, funcLineID = key
+ GameWorld.Log(" 分区对应功能线路虚拟分线关闭: zoneID=%s,dataMapID%s,funcLineID=%s" % (zoneID, dataMapID, funcLineID))
+ break
+
+ key = (mapID, copyMapID)
+ 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 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, funcLineObjList in zoneLineDict.items():
+ for funcLineObj in funcLineObjList:
+ if funcLineObj.mapID == mapID:
+ funcLineObj.OnCopyMapClose(None)
+
+ for key in PyGameData.g_crossDynamicLineCopyMapInfo.keys():
+ if key[0] == mapID:
+ 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.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)
+ 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)
+
+ #GameWorld.DebugLog("玩家退出动态分配的跨服地图: GetMapID=%s,GetRealMapID=%s,GetFBID()=%s"
+ # % (curPlayer.GetMapID(), mapID, copyMapID), playerID)
+ #GameWorld.DebugLog(" 副本中的玩家ID: %s" % copyMapObj.fbPlayerDict)
+ #GameWorld.DebugLog(" 等待中的玩家ID: %s" % copyMapObj.waitPlayerDict)
+ return
+
+##--------------------------------------------------------------------------------------------------
## 请求进入副本分线
# @param curPlayer: 请求玩家
@@ -121,7 +435,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())
--
Gitblit v1.8.0