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:
@@ -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<16379>" 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
|
||||
|
||||
Reference in New Issue
Block a user