Merge pull request #1516 from aws-lumberyard-dev/MultiplayerEditorFixes

SPEC-7469 Fixed EditorServerInfo packet serialization
This commit is contained in:
SergeyAMZN
2021-06-24 16:56:52 +01:00
committed by GitHub
6 changed files with 34 additions and 13 deletions
@@ -200,6 +200,7 @@ namespace AzNetworking
NetworkInputSerializer serializer(buffer.GetBuffer(), buffer.GetCapacity());
if (!const_cast<IPacket&>(packet).Serialize(serializer))
{
AZ_Assert(false, "SendReliablePacket: Unable to serialize packet [Type: %d]", packet.GetPacketType());
return false;
}
buffer.Resize(serializer.GetSize());
@@ -7,7 +7,9 @@
<Packet Name="EditorServerInit" Desc="A packet that initializes a local server launched from the editor">
<Member Type="bool" Name="lastUpdate" Init="false"/>
<Member Type="AzNetworking::TcpPacketEncodingBuffer" Name="assetData"/>
<!--16379 is 16384 (max TCP packet size) - 1 byte (bool lastUpdate) - 4 bytes (serialization overhead for ByteBuffer) -->
<Member Type="AzNetworking::ByteBuffer&lt;16379&gt;" Name="assetData"/>
</Packet>
<Packet Name="EditorServerReady" Desc="A response packet the local server should send when ready for traffic"/>
@@ -6,6 +6,7 @@
*/
#include <Multiplayer/IMultiplayer.h>
#include <Multiplayer/INetworkSpawnableLibrary.h>
#include <Multiplayer/MultiplayerConstants.h>
#include <Editor/MultiplayerEditorConnection.h>
#include <Source/AutoGen/AutoComponentTypes.h>
@@ -50,16 +51,12 @@ namespace Multiplayer
)
{
// Editor Server Init is intended for non-release targets
if (!packet.GetLastUpdate())
{
// More packets are expected, flush this to the buffer
m_byteStream.Write(TcpPacketEncodingBuffer::GetCapacity(), reinterpret_cast<void*>(packet.ModifyAssetData().GetBuffer()));
}
else
{
// This is the last expected packet, flush it to the buffer
m_byteStream.Write(packet.GetAssetData().GetSize(), reinterpret_cast<void*>(packet.ModifyAssetData().GetBuffer()));
m_byteStream.Write(packet.GetAssetData().GetSize(), reinterpret_cast<void*>(packet.ModifyAssetData().GetBuffer()));
// In case if this is the last update, process the byteStream buffer. Otherwise more packets are expected
if (packet.GetLastUpdate())
{
// This is the last expected packet
// Read all assets out of the buffer
m_byteStream.Seek(0, AZ::IO::GenericStream::SeekMode::ST_SEEK_BEGIN);
AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>> assetData;
@@ -75,6 +72,11 @@ namespace Multiplayer
size_t assetSize = m_byteStream.GetCurPos();
AZ::Data::AssetData* assetDatum = AZ::Utils::LoadObjectFromStream<AZ::Data::AssetData>(m_byteStream, nullptr);
if (!assetDatum)
{
AZLOG_ERROR("EditorServerInit packet contains no asset data. Asset: %s", assetHint.c_str());
return false;
}
assetSize = m_byteStream.GetCurPos() - assetSize;
AZ::Data::Asset<AZ::Data::AssetData> asset = AZ::Data::Asset<AZ::Data::AssetData>(assetId, assetDatum, AZ::Data::AssetLoadBehavior::NoLoad);
asset.SetHint(assetHint);
@@ -96,6 +98,9 @@ namespace Multiplayer
m_byteStream.Seek(0, AZ::IO::GenericStream::SeekMode::ST_SEEK_BEGIN);
m_byteStream.Truncate();
// Spawnable library needs to be rebuilt since now we have newly registered in-memory spawnable assets
AZ::Interface<INetworkSpawnableLibrary>::Get()->BuildSpawnablesList();
// Load the level via the root spawnable that was registered
const AZ::CVarFixedString loadLevelString = "LoadLevel Root.spawnable";
AZ::Interface<AZ::IConsole>::Get()->PerformCommand(loadLevelString.c_str());
@@ -7,6 +7,7 @@
#include <Multiplayer/IMultiplayer.h>
#include <Multiplayer/IMultiplayerTools.h>
#include <Multiplayer/INetworkSpawnableLibrary.h>
#include <Multiplayer/MultiplayerConstants.h>
#include <MultiplayerSystemComponent.h>
@@ -186,6 +187,9 @@ namespace Multiplayer
m_serverProcess = LaunchEditorServer();
}
// Spawnable library needs to be rebuilt since now we have newly registered in-memory spawnable assets
AZ::Interface<INetworkSpawnableLibrary>::Get()->BuildSpawnablesList();
// Now that the server has launched, attempt to connect the NetworkInterface
INetworkInterface* editorNetworkInterface = AZ::Interface<INetworking>::Get()->RetrieveNetworkInterface(AZ::Name(MPEditorInterfaceName));
AZ_Assert(editorNetworkInterface, "MP Editor Network Interface was unregistered before Editor could connect.");
@@ -206,10 +210,10 @@ namespace Multiplayer
while (byteStream.GetCurPos() < byteStream.GetLength())
{
MultiplayerEditorPackets::EditorServerInit packet;
AzNetworking::TcpPacketEncodingBuffer& outBuffer = packet.ModifyAssetData();
auto& outBuffer = packet.ModifyAssetData();
// Size the packet's buffer appropriately
size_t readSize = TcpPacketEncodingBuffer::GetCapacity();
size_t readSize = outBuffer.GetCapacity();
size_t byteStreamSize = byteStream.GetLength() - byteStream.GetCurPos();
if (byteStreamSize < readSize)
{
@@ -227,6 +231,11 @@ namespace Multiplayer
editorNetworkInterface->SendReliablePacket(m_editorConnId, packet);
}
}
}
void MultiplayerEditorSystemComponent::OnGameEntitiesReset()
{
// Rebuild the library to clear temporary in-memory spawnable assets
AZ::Interface<INetworkSpawnableLibrary>::Get()->BuildSpawnablesList();
}
}
@@ -63,7 +63,8 @@ namespace Multiplayer
//! GameEntityContextEventBus::Handler overrides
//! @{
void OnGameEntitiesStarted() override;
void OnGameEntitiesStarted() override;
void OnGameEntitiesReset() override;
//! @}
IEditor* m_editor = nullptr;
@@ -27,6 +27,9 @@ namespace Multiplayer
void NetworkSpawnableLibrary::BuildSpawnablesList()
{
m_spawnables.clear();
m_spawnablesReverseLookup.clear();
auto enumerateCallback = [this](const AZ::Data::AssetId id, const AZ::Data::AssetInfo& info)
{
if (info.m_assetType == AZ::AzTypeInfo<AzFramework::Spawnable>::Uuid())