Merge pull request #4461 from aws-lumberyard-dev/LYN-7080_FixEditorServerConnectionRaceCondition
Fix EditorServer Connection
This commit is contained in:
@@ -48,6 +48,7 @@ namespace Multiplayer
|
||||
using NotifyClientMigrationEvent = AZ::Event<const HostId&, uint64_t, ClientInputId>;
|
||||
using NotifyEntityMigrationEvent = AZ::Event<const ConstNetworkEntityHandle&, const HostId&>;
|
||||
using ConnectionAcquiredEvent = AZ::Event<MultiplayerAgentDatum>;
|
||||
using ServerAcceptanceReceivedEvent = AZ::Event<>;
|
||||
using SessionInitEvent = AZ::Event<AzNetworking::INetworkInterface*>;
|
||||
using SessionShutdownEvent = AZ::Event<AzNetworking::INetworkInterface*>;
|
||||
|
||||
@@ -122,6 +123,10 @@ namespace Multiplayer
|
||||
//! @param handler The ConnectionAcquiredEvent Handler to add
|
||||
virtual void AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler) = 0;
|
||||
|
||||
//! Adds a ServerAcceptanceReceived Handler which is invoked when the client receives the accept packet from the server.
|
||||
//! @param handler The ServerAcceptanceReceived Handler to add
|
||||
virtual void AddServerAcceptanceReceivedHandler(ServerAcceptanceReceivedEvent::Handler& handler) = 0;
|
||||
|
||||
//! Adds a SessionInitEvent Handler which is invoked when a new network session starts.
|
||||
//! @param handler The SessionInitEvent Handler to add
|
||||
virtual void AddSessionInitHandler(SessionInitEvent::Handler& handler) = 0;
|
||||
|
||||
@@ -146,7 +146,6 @@ namespace Multiplayer
|
||||
{
|
||||
// Connect the Editor to the editor server for Multiplayer simulation
|
||||
AZ::Interface<IMultiplayer>::Get()->Connect(remoteAddress.c_str(), remotePort);
|
||||
AZ::Interface<IMultiplayer>::Get()->SendReadyForEntityUpdates(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ namespace Multiplayer
|
||||
}
|
||||
|
||||
MultiplayerEditorSystemComponent::MultiplayerEditorSystemComponent()
|
||||
: m_serverAcceptanceReceivedHandler([this](){OnServerAcceptanceReceived();})
|
||||
{
|
||||
;
|
||||
}
|
||||
@@ -70,6 +71,7 @@ namespace Multiplayer
|
||||
{
|
||||
AzFramework::GameEntityContextEventBus::Handler::BusConnect();
|
||||
AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
|
||||
AZ::Interface<IMultiplayer>::Get()->AddServerAcceptanceReceivedHandler(m_serverAcceptanceReceivedHandler);
|
||||
}
|
||||
|
||||
void MultiplayerEditorSystemComponent::Deactivate()
|
||||
@@ -143,7 +145,11 @@ namespace Multiplayer
|
||||
|
||||
// Start the configured server if it's available
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
processLaunchInfo.m_commandlineParameters = AZStd::string::format("\"%s\" --editorsv_isDedicated true", serverPath.c_str());
|
||||
processLaunchInfo.m_commandlineParameters = AZStd::string::format(
|
||||
R"("%s" --project-path "%s" --editorsv_isDedicated true --sv_defaultPlayerSpawnAsset "%s")",
|
||||
serverPath.c_str(),
|
||||
AZ::Utils::GetProjectPath().c_str(),
|
||||
static_cast<AZ::CVarFixedString>(sv_defaultPlayerSpawnAsset).c_str());
|
||||
processLaunchInfo.m_showWindow = true;
|
||||
processLaunchInfo.m_processPriority = AzFramework::ProcessPriority::PROCESSPRIORITY_NORMAL;
|
||||
|
||||
@@ -239,4 +245,12 @@ namespace Multiplayer
|
||||
void MultiplayerEditorSystemComponent::OnGameEntitiesReset()
|
||||
{
|
||||
}
|
||||
|
||||
void MultiplayerEditorSystemComponent::OnServerAcceptanceReceived()
|
||||
{
|
||||
// We're now accepting the connection to the EditorServer.
|
||||
// In normal game clients SendReadyForEntityUpdates will be enabled once the appropriate level's root spawnable is loaded,
|
||||
// but since we're in Editor, we're already in the level.
|
||||
AZ::Interface<IMultiplayer>::Get()->SendReadyForEntityUpdates(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Multiplayer/IMultiplayer.h>
|
||||
|
||||
#include <IEditor.h>
|
||||
|
||||
#include <Editor/MultiplayerEditorConnection.h>
|
||||
@@ -45,6 +47,9 @@ namespace Multiplayer
|
||||
MultiplayerEditorSystemComponent();
|
||||
~MultiplayerEditorSystemComponent() override = default;
|
||||
|
||||
//! Called once the editor receives the server's accept packet
|
||||
void OnServerAcceptanceReceived();
|
||||
|
||||
//! AZ::Component overrides.
|
||||
//! @{
|
||||
void Activate() override;
|
||||
@@ -71,5 +76,7 @@ namespace Multiplayer
|
||||
IEditor* m_editor = nullptr;
|
||||
AzFramework::ProcessWatcher* m_serverProcess = nullptr;
|
||||
AzNetworking::ConnectionId m_editorConnId;
|
||||
|
||||
ServerAcceptanceReceivedEvent::Handler m_serverAcceptanceReceivedHandler;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -497,6 +497,8 @@ namespace Multiplayer
|
||||
AZ::Interface<AZ::IConsole>::Get()->PerformCommand(commandString.c_str());
|
||||
AZ::CVarFixedString loadLevelString = "LoadLevel " + packet.GetMap();
|
||||
AZ::Interface<AZ::IConsole>::Get()->PerformCommand(loadLevelString.c_str());
|
||||
|
||||
m_serverAcceptanceReceivedEvent.Signal();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -821,6 +823,11 @@ namespace Multiplayer
|
||||
handler.Connect(m_connectionAcquiredEvent);
|
||||
}
|
||||
|
||||
void MultiplayerSystemComponent::AddServerAcceptanceReceivedHandler(ServerAcceptanceReceivedEvent::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_serverAcceptanceReceivedEvent);
|
||||
}
|
||||
|
||||
void MultiplayerSystemComponent::AddSessionInitHandler(SessionInitEvent::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_initEvent);
|
||||
@@ -1034,7 +1041,7 @@ namespace Multiplayer
|
||||
INetworkEntityManager::EntityList entityList = m_networkEntityManager.CreateEntitiesImmediate(playerPrefabEntityId, NetEntityRole::Authority, AZ::Transform::CreateIdentity(), Multiplayer::AutoActivate::DoNotActivate);
|
||||
|
||||
NetworkEntityHandle controlledEntity;
|
||||
if (entityList.size() > 0)
|
||||
if (!entityList.empty())
|
||||
{
|
||||
controlledEntity = entityList[0];
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace AzNetworking
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
AZ_CVAR_EXTERNED(AZ::CVarFixedString, sv_defaultPlayerSpawnAsset);
|
||||
|
||||
//! Multiplayer system component wraps the bridging logic between the game and transport layer.
|
||||
class MultiplayerSystemComponent final
|
||||
: public AZ::Component
|
||||
@@ -116,6 +118,7 @@ namespace Multiplayer
|
||||
void AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler) override;
|
||||
void AddSessionInitHandler(SessionInitEvent::Handler& handler) override;
|
||||
void AddSessionShutdownHandler(SessionShutdownEvent::Handler& handler) override;
|
||||
void AddServerAcceptanceReceivedHandler(ServerAcceptanceReceivedEvent::Handler& handler) override;
|
||||
void SendNotifyClientMigrationEvent(const HostId& hostId, uint64_t userIdentifier, ClientInputId lastClientInputId) override;
|
||||
void SendNotifyEntityMigrationEvent(const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId) override;
|
||||
void SendReadyForEntityUpdates(bool readyForEntityUpdates) override;
|
||||
@@ -157,6 +160,7 @@ namespace Multiplayer
|
||||
SessionInitEvent m_initEvent;
|
||||
SessionShutdownEvent m_shutdownEvent;
|
||||
ConnectionAcquiredEvent m_connectionAcquiredEvent;
|
||||
ServerAcceptanceReceivedEvent m_serverAcceptanceReceivedEvent;
|
||||
ClientDisconnectedEvent m_clientDisconnectedEvent;
|
||||
ClientMigrationStartEvent m_clientMigrationStartEvent;
|
||||
ClientMigrationEndEvent m_clientMigrationEndEvent;
|
||||
|
||||
@@ -328,6 +328,7 @@ namespace Multiplayer
|
||||
void Terminate([[maybe_unused]] AzNetworking::DisconnectReason reason) override {}
|
||||
void AddClientDisconnectedHandler([[maybe_unused]] ClientDisconnectedEvent::Handler& handler) override {}
|
||||
void AddConnectionAcquiredHandler([[maybe_unused]] ConnectionAcquiredEvent::Handler& handler) override {}
|
||||
void AddServerAcceptanceReceivedHandler([[maybe_unused]] ServerAcceptanceReceivedEvent::Handler& handler) override {}
|
||||
void AddSessionInitHandler([[maybe_unused]] SessionInitEvent::Handler& handler) override {}
|
||||
void AddSessionShutdownHandler([[maybe_unused]] SessionShutdownEvent::Handler& handler) override {}
|
||||
void SendReadyForEntityUpdates([[maybe_unused]] bool readyForEntityUpdates) override {}
|
||||
|
||||
@@ -29,9 +29,10 @@ namespace UnitTest
|
||||
MOCK_METHOD1(AddClientDisconnectedHandler, void(AZ::Event<>::Handler&));
|
||||
MOCK_METHOD1(AddNotifyClientMigrationHandler, void(Multiplayer::NotifyClientMigrationEvent::Handler&));
|
||||
MOCK_METHOD1(AddNotifyEntityMigrationEventHandler, void(Multiplayer::NotifyEntityMigrationEvent::Handler&));
|
||||
MOCK_METHOD1(AddConnectionAcquiredHandler, void(AZ::Event<Multiplayer::MultiplayerAgentDatum>::Handler&));
|
||||
MOCK_METHOD1(AddSessionInitHandler, void(AZ::Event<AzNetworking::INetworkInterface*>::Handler&));
|
||||
MOCK_METHOD1(AddSessionShutdownHandler, void(AZ::Event<AzNetworking::INetworkInterface*>::Handler&));
|
||||
MOCK_METHOD1(AddConnectionAcquiredHandler, void(Multiplayer::ConnectionAcquiredEvent::Handler&));
|
||||
MOCK_METHOD1(AddServerAcceptanceReceivedHandler, void(Multiplayer::ServerAcceptanceReceivedEvent::Handler&));
|
||||
MOCK_METHOD1(AddSessionInitHandler, void(Multiplayer::SessionInitEvent::Handler&));
|
||||
MOCK_METHOD1(AddSessionShutdownHandler, void(Multiplayer::SessionShutdownEvent::Handler&));
|
||||
MOCK_METHOD3(SendNotifyClientMigrationEvent, void(const Multiplayer::HostId&, uint64_t, Multiplayer::ClientInputId));
|
||||
MOCK_METHOD2(SendNotifyEntityMigrationEvent, void(const Multiplayer::ConstNetworkEntityHandle&, const Multiplayer::HostId&));
|
||||
MOCK_METHOD1(SendReadyForEntityUpdates, void(bool));
|
||||
|
||||
Reference in New Issue
Block a user