From ee4705284b8064b4f3964dfd13c22386b7d5c20f Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期三, 26 二月 2025 15:48:24 +0800 Subject: [PATCH] 10407 【越南】【英语】【BT】【GM】【砍树】周末BUG汇总(修复排行榜功能开启时同步开服活动榜数据异常bug;) --- ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py | 147 ++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 121 insertions(+), 26 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py index 48853d9..db4f559 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py @@ -33,7 +33,11 @@ import IPY_PlayerDefine import CrossBattlefield import CrossRealmPlayer +import CrossChampionship +import PlayerPackData +import DataRecordPack import CrossRealmMsg +import PyDataManager import ShareDefine import CrossBoss import time @@ -62,8 +66,9 @@ ## 跨服地图动态分配的虚拟线路信息 {(mapID, copyMapID):CrossCopyMapInfo, ...} class CrossCopyMapInfo(): - def __init__(self, zoneID, funcLineID): + def __init__(self, zoneID, funcMapID, funcLineID): self.zoneID = zoneID + self.funcMapID = funcMapID self.funcLineID = funcLineID self.newFuncLineNum = 0 self.realMapID = 0 @@ -93,9 +98,28 @@ return totalPlayerCount - def IsMustCopyMapPlayer(self, playerID): + def IsMustCopyMapPlayer(self, playerID, checkTeam=True): ## 是否必定在此分线的玩家, 在请求队列里 或 曾经进入到该分线的,都强制认为属于该分线的玩家 - return playerID in self.waitPlayerDict or playerID in self.enterPlayerIDList + if playerID in self.waitPlayerDict or playerID in self.enterPlayerIDList: + return True + if self.openState != IPY_PlayerDefine.fbosOpen: + return False + if not checkTeam: + return False + # 队友强制在一起 + funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager() + teamID = funcTeamMgr.GetPlayerTeamID(playerID, self.funcMapID) + if not teamID: + return False + funcTeam = funcTeamMgr.GetFuncTeam(teamID) + if not funcTeam: + return False + for memID in funcTeam.GetMemberIDList(): + if memID in self.waitPlayerDict or memID in self.enterPlayerIDList: + GameWorld.DebugLog("强制和队友在一条线路! funcMapID=%s,memID=%s,realMapID=%s,copyMapID=%s" + % (self.funcMapID, memID, self.realMapID, self.copyMapID), playerID) + return True + return False def OnRequestEnterCrossCopyMap(self, playerID, tick, copyMapPlayerMax, includeOffline): if not copyMapPlayerMax or self.IsMustCopyMapPlayer(playerID): @@ -147,6 +171,10 @@ funcLineID = msgData["FuncLineID"] playerLV = msgData["LV"] + if mapID == ChConfig.Def_FBMapID_CrossChampionship: + #CrossChampionship.OnRequestChampionshipVSRoom(playerID, serverGroupID) + return + zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID) if not zoneIpyData: return @@ -168,10 +196,9 @@ pass elif mapID == ChConfig.Def_FBMapID_CrossBattlefield: - openTimeInfo = CrossBattlefield.GetCrossBattlefieldOpenTime(zoneID) + openTimeInfo = CrossBattlefield.GetCrossBattlefieldOpenTime(serverGroupID, zoneID, playerID) if not openTimeInfo: - PlayerControl.NotifyCodeCross(serverGroupID, playerID, "FBIsNotOpen") - GameWorld.ErrLog("非活动时间或未开启! funcLineID=%s,zoneID=%s" % (funcLineID, zoneID), playerID) + #GameWorld.ErrLog("非活动时间或未开启! funcLineID=%s,zoneID=%s" % (funcLineID, zoneID), playerID) return dynamicShuntType = DynamicShuntType_Equally isCallBattle, openHour, openMinute = openTimeInfo @@ -251,7 +278,7 @@ realMapID, copyMapID, openState = tagCopyMapObj.realMapID, tagCopyMapObj.copyMapID, tagCopyMapObj.openState - if openState == IPY_PlayerDefine.fbosWaitForClose: + if openState >= IPY_PlayerDefine.fbosWaitForClose: PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossFBClose") GameWorld.ErrLog("分流的副本线路关闭中! mapID=%s,funcLineID=%s,zoneID=%s,realMapID=%s,copyMapID=%s,openState=%s" % (mapID, funcLineID, zoneID, realMapID, copyMapID, openState), playerID) @@ -262,21 +289,25 @@ if openState == IPY_PlayerDefine.fbosOpen: funcLineID = tagCopyMapObj.funcLineID playerIDList = [playerID] - retInfo = [playerIDList, mapID, realMapID, copyMapID, funcLineID] + # 分流地图的地图数据ID直接使用场景ID,因为分流地图实际上是两张不同的地图,所以直接使用场景ID,不然会导致上传跨服玩家数据时坐标为0 + retInfo = [playerIDList, mapID, realMapID, realMapID, copyMapID, funcLineID] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID]) + dataDict = {} + dataDict.update(msgData) + dataDict.update({"mapID":mapID, "realMapID":realMapID, "copyMapID":copyMapID, "realFuncLineID":funcLineID, "openState":openState}) + DataRecordPack.SendEventPack("CrossFBRequest", dataDict) return tagCopyMapObj def CrossServerMsg_EnterFBRet(msgData, tick): ## 收到跨服服务器动态分配的跨服副本进入信息 - - playerIDList, dataMapID, mapID, copyMapID, funcLineID = msgData + playerIDList, dataMapID, mapID, realMapID, copyMapID, funcLineID = msgData for playerID in playerIDList: curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if not curPlayer: continue - CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, mapID, dataMapID, copyMapID, lineID=funcLineID) + CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, realMapID, mapID, copyMapID, lineID=funcLineID) return @@ -334,7 +365,7 @@ copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] openState = copyMapObj.openState - if openState == IPY_PlayerDefine.fbosWaitForClose: + if openState >= IPY_PlayerDefine.fbosWaitForClose: # 没有限制分流人数的情况,代表都在同一场,这种情况下当副本已经在关闭的状态下,则代表已经结束了,不可再进入 if not shuntPlayerMax: PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossFBClose") @@ -447,7 +478,7 @@ newFuncLineObj.copyMapID = copyMapID newFuncLineObj.newFuncLineNum = newFuncLineNum - copyMapObj = CrossCopyMapInfo(zoneID, funcLineID) + copyMapObj = CrossCopyMapInfo(zoneID, mapID, funcLineID) copyMapObj.realMapID = realMapID copyMapObj.copyMapID = copyMapID copyMapObj.newFuncLineNum = newFuncLineNum @@ -464,6 +495,15 @@ msgInfo = str([copyMapID, propertyID, funcLineDataCache]) GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, realMapID, "OpenFB", msgInfo, len(msgInfo)) return copyMapObj + +def SendMapOpenFBEx(realMapID, copyPropertyList): + ## 通知地图开启副本线路 + # @param realMapID: 地图ID + # @param copyPropertyList: [[copyMapID, propertyID], ...] + msgInfo = str(copyPropertyList) + GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, realMapID, "OpenFBEx", msgInfo, len(msgInfo)) + GameWorld.Log("SendMapOpenFBEx: realMapID=%s,msgInfo=%s" % (realMapID, msgInfo)) + return def OpenCrossDynamicLineBySys(zoneID, mapID, funcLineIDList, checkExist): ## 系统开启跨服动态线路 @@ -502,7 +542,7 @@ return 0 def OnCrossDynamicLineStateChange(msgList): - realMapID, copyMapID, state = msgList[:3] + mapID, realMapID, copyMapID, state = msgList[:4] if state == IPY_PlayerDefine.fbosWaitForClose: funcLineDataCache = msgList[3] @@ -510,11 +550,15 @@ elif state == IPY_PlayerDefine.fbosClosed: OnCrossDynamicLineClose(realMapID, copyMapID) elif state == IPY_PlayerDefine.fbosOpen: - OnCrossDynamicLineOpen(realMapID, copyMapID) - + OnCrossDynamicLineOpen(mapID, realMapID, copyMapID) + else: + key = (realMapID, copyMapID) + if key in PyGameData.g_crossDynamicLineCopyMapInfo: + copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] + copyMapObj.openState = state return -def OnCrossDynamicLineOpen(realMapID, copyMapID): +def OnCrossDynamicLineOpen(mapID, realMapID, copyMapID): ## 动态分配线路的地图虚拟线路启动成功 key = (realMapID, copyMapID) @@ -533,11 +577,11 @@ playerIDList = serverPlayerIDListDict[serverGroupID] playerIDList.append(playerID) - mapID = GetRecordMapID(realMapID) - GameWorld.Log("动态分配虚拟线路启动成功,通知子服等待玩家可进入: mapID=%s,realMapID=%s,copyMapID=%s,serverPlayerIDListDict=%s" - % (mapID, realMapID, copyMapID, serverPlayerIDListDict)) + recordMapID = GetRecordMapID(realMapID) + GameWorld.Log("动态分配虚拟线路启动成功,通知子服等待玩家可进入: recordMapID=%s,mapID=%s,realMapID=%s,copyMapID=%s,serverPlayerIDListDict=%s" + % (recordMapID, mapID, realMapID, copyMapID, serverPlayerIDListDict)) for serverGroupID, playerIDList in serverPlayerIDListDict.items(): - retInfo = [playerIDList, mapID, realMapID, copyMapID, funcLineID] + retInfo = [playerIDList, recordMapID, mapID, realMapID, copyMapID, funcLineID] CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID]) #GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo) @@ -710,7 +754,8 @@ # @param sendCMD: 请求的命令 根据请求类型和请求命令来决定最终操作 # @return None def EnterFBLine(curPlayer, queryCallName, sendCMD, tick): - GameWorld.Log("EnterFBLine()...queryCallName=%s,sendCMD=%s" % (queryCallName, sendCMD), curPlayer.GetPlayerID()) + playerID = curPlayer.GetPlayerID() + GameWorld.Log("EnterFBLine()...queryCallName=%s,sendCMD=%s" % (queryCallName, sendCMD), playerID) playerManager = GameWorld.GetPlayerManager() try: mapInfo = eval(sendCMD) @@ -725,12 +770,20 @@ #if mapInfo and len(mapInfo) == 2: tagMapID = mapInfo[0] tagLineID = mapInfo[1] + extendValue1 = mapInfo[2] if len(mapInfo) > 2 else None fbLineIpyData = GetFBLineIpyData(tagMapID, tagLineID) sceneMapID = tagMapID if not fbLineIpyData else fbLineIpyData.GetMapID() gameMap = GameWorld.GetMap(sceneMapID) if not gameMap: GameWorld.ErrLog("目标副本地图不存在!tagMapID=%s,sceneMapID=%s" % (tagMapID, sceneMapID), curPlayer.GetPlayerID()) + return + + if isinstance(extendValue1, dict): + if extendValue1.get("msgType", "") == "MirrorBattle": + PlayerPackData.OnMGReuestPlayerPackData(extendValue1) + playerManager.MapServer_QueryPlayer(curPlayer.GetPlayerID(), ChConfig.queryType_EnterFB, 0, sceneMapID, + queryCallName, sendCMD, len(sendCMD), curPlayer.GetRouteServerIndex()) return # 组队副本, 有队伍的情况才验证其他队员可否进入,否则代表单人进入 @@ -754,10 +807,6 @@ if not GameWorldFamilyWar.CheckPlayerCanEnterFamilyWarFBMap(curPlayer): return - elif tagMapID == ChConfig.Def_FBMapID_FamilyBossMap: - if not PlayerFamilyBoss.CheckIsFamilyBossFBOpen(curPlayer.GetFamilyID(), tagMapID): - GameWorld.Log("EnterFBLine mapID=%s is familyBossFB, but is not open!" % tagMapID) - return #守卫人皇 是否已参加 elif tagMapID == ChConfig.Def_FBMapID_FamilyInvade: if curPlayer.GetFamilyID() in PyGameData.g_swrhJoinRecord: @@ -783,3 +832,49 @@ playerManager.MapServer_QueryPlayer(curPlayer.GetPlayerID(), ChConfig.queryType_EnterFB, 0, tagMapID, queryCallName, sendCMD, len(sendCMD), curPlayer.GetRouteServerIndex()) return + +def Send_CrossServerMsg_EnterVSRoomRet(vsRoomDict, serverGroupIDList=None): + ## 发送子服跨服对战房间请求进入结果 + # @param vsRoomDict: {roomID:{playerID:playerInfo, ...}, } + # playerInfo key + # serverGroupID 所属服务器分组ID + # regMapInfo 传送跨服注册信息 [registerMap, mapID, dataMapID, copyMapID, posX, posY] + CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterVSRoomRet, vsRoomDict, serverGroupIDList) + return + +def CrossServerMsg_EnterVSRoomRet(msgData, tick): + ## 跨服对战房间请求进入结果 + + curServerGroupID = GameWorld.GetServerGroupID() + GameWorld.DebugLog("=== 跨服PK对战房间请求进入结果 === curServerGroupID=%s" % curServerGroupID) + vsRoomDict = msgData + for roomID, playerDict in vsRoomDict.items(): + GameWorld.DebugLog(" roomID=%s,playerDict=%s" % (roomID, playerDict)) + for playerID, playerInfo in playerDict.items(): + if "serverGroupID" in playerInfo: + serverGroupID = playerInfo["serverGroupID"] + if serverGroupID != curServerGroupID: + GameWorld.DebugLog(" 不是本服玩家,不处理!playerID=%s,serverGroupID=%s" % (playerID, serverGroupID)) + continue + + player = GameWorld.GetPlayerManager().FindPlayerByID(playerID) + if not player: + GameWorld.DebugLog(" 玩家不在线, playerID=%s" % (playerID)) + continue + if PlayerControl.GetIsTJG(player): + GameWorld.DebugLog(" 玩家脱机中, playerID=%s" % (playerID)) + continue + + if "regMapInfo" not in playerInfo: + continue + regMapInfo = playerInfo["regMapInfo"] + if len(regMapInfo) != 6: + continue + registerMap, mapID, dataMapID, copyMapID, posX, posY = regMapInfo + + PlayerControl.SetVsRoomId(player, roomID, True) + # 通知地图玩家匹配成功, 上传数据, 准备进入跨服服务器 + CrossRealmPlayer.SendCrossRealmReg(player, registerMap, mapID, dataMapID, copyMapID, posX, posY) + + return + -- Gitblit v1.8.0