SPEC-7469 Multiplayer Editor Ctrl+G fails due to EditorInfo packets reordering. SPEC-7471 Multiplayer Editor Ctrl+G asserts after CreateEntitiesImmediate

This commit is contained in:
pereslav
2021-06-24 01:12:19 +01:00
parent 970dcea16e
commit 6b1d3d1f9a
7 changed files with 28 additions and 43 deletions
@@ -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"/>
@@ -11,9 +11,9 @@
*/
#include <Multiplayer/IMultiplayer.h>
#include <Multiplayer/INetworkSpawnableLibrary.h>
#include <Multiplayer/MultiplayerConstants.h>
#include <Editor/MultiplayerEditorConnection.h>
#include <Editor/MultiplayerEditorUtils.h>
#include <Source/AutoGen/AutoComponentTypes.h>
#include <AzCore/Asset/AssetManager.h>
@@ -56,16 +56,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(GetMaxEditorServerInitSize(), 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;
@@ -107,6 +103,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());
@@ -12,11 +12,11 @@
#include <Multiplayer/IMultiplayer.h>
#include <Multiplayer/IMultiplayerTools.h>
#include <Multiplayer/INetworkSpawnableLibrary.h>
#include <Multiplayer/MultiplayerConstants.h>
#include <MultiplayerSystemComponent.h>
#include <Editor/MultiplayerEditorSystemComponent.h>
#include <Editor/MultiplayerEditorUtils.h>
#include <Source/AutoGen/Multiplayer.AutoPackets.h>
#include <AzCore/Component/ComponentApplicationBus.h>
@@ -192,6 +192,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.");
@@ -212,10 +215,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 = GetMaxEditorServerInitSize();
size_t readSize = outBuffer.GetCapacity();
size_t byteStreamSize = byteStream.GetLength() - byteStream.GetCurPos();
if (byteStreamSize < readSize)
{
@@ -233,6 +236,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();
}
}
@@ -68,7 +68,8 @@ namespace Multiplayer
//! GameEntityContextEventBus::Handler overrides
//! @{
void OnGameEntitiesStarted() override;
void OnGameEntitiesStarted() override;
void OnGameEntitiesReset() override;
//! @}
IEditor* m_editor = nullptr;
@@ -1,27 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzNetworking/DataStructures/ByteBuffer.h>
namespace Multiplayer
{
static constexpr size_t GetMaxEditorServerInitSize()
{
constexpr size_t totalCapacity = AzNetworking::TcpPacketEncodingBuffer::GetCapacity();
constexpr size_t packetOverhead = sizeof(bool) + 2 * sizeof(uint16_t); // m_lastUpdate + m_assetBuffer
static_assert(totalCapacity > packetOverhead);
return totalCapacity - packetOverhead;
}
}
@@ -32,6 +32,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())
@@ -68,7 +68,6 @@ set(FILES
Source/ConnectionData/ServerToClientConnectionData.inl
Source/Editor/MultiplayerEditorConnection.cpp
Source/Editor/MultiplayerEditorConnection.h
Source/Editor/MultiplayerEditorUtils.h
Source/EntityDomains/FullOwnershipEntityDomain.cpp
Source/EntityDomains/FullOwnershipEntityDomain.h
Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp