Merge branch 'main' into MultiplayerPipeline

This commit is contained in:
pereslav
2021-05-13 23:40:43 +01:00
2678 changed files with 54281 additions and 232128 deletions
@@ -14,14 +14,14 @@
#include <Source/NetworkEntity/EntityReplication/EntityReplicator.h>
#include <Source/NetworkEntity/EntityReplication/PropertyPublisher.h>
#include <Source/NetworkEntity/EntityReplication/PropertySubscriber.h>
#include <Source/ReplicationWindows/IReplicationWindow.h>
#include <Source/EntityDomains/IEntityDomain.h>
#include <Source/NetworkEntity/NetworkEntityUpdateMessage.h>
#include <Source/NetworkEntity/NetworkEntityRpcMessage.h>
#include <Source/NetworkEntity/INetworkEntityManager.h>
#include <Source/Components/NetBindComponent.h>
#include <Source/AutoGen/Multiplayer.AutoPackets.h>
#include <Include/IMultiplayer.h>
#include <Multiplayer/NetworkEntityUpdateMessage.h>
#include <Multiplayer/NetworkEntityRpcMessage.h>
#include <Multiplayer/NetBindComponent.h>
#include <Multiplayer/IEntityDomain.h>
#include <Multiplayer/IMultiplayer.h>
#include <Multiplayer/INetworkEntityManager.h>
#include <Multiplayer/IReplicationWindow.h>
#include <AzNetworking/ConnectionLayer/IConnection.h>
#include <AzNetworking/ConnectionLayer/IConnectionListener.h>
#include <AzNetworking/PacketLayer/IPacketHeader.h>
@@ -60,7 +60,11 @@ namespace Multiplayer
// Start window update events
m_updateWindow.Enqueue(AZ::TimeMs{ 0 }, true);
GetNetworkEntityManager()->AddEntityExitDomainHandler(m_entityExitDomainEventHandler);
INetworkEntityManager* networkEntityManager = GetNetworkEntityManager();
if (networkEntityManager != nullptr)
{
networkEntityManager->AddEntityExitDomainHandler(m_entityExitDomainEventHandler);
}
}
void EntityReplicationManager::SetRemoteHostId(HostId hostId)
@@ -93,10 +97,10 @@ namespace Multiplayer
}
}
void EntityReplicationManager::SendUpdates(AZ::TimeMs serverGameTimeMs)
void EntityReplicationManager::SendUpdates(AZ::TimeMs hostTimeMs)
{
m_frameTimeMs = AZ::GetElapsedTimeMs();
SendEntityUpdates(serverGameTimeMs);
SendEntityUpdates(hostTimeMs);
SendEntityRpcs(m_deferredRpcMessagesReliable, true);
SendEntityRpcs(m_deferredRpcMessagesUnreliable, false);
@@ -118,7 +122,7 @@ namespace Multiplayer
void EntityReplicationManager::SendEntityUpdatesPacketHelper
(
AZ::TimeMs serverGameTimeMs,
AZ::TimeMs hostTimeMs,
EntityReplicatorList& toSendList,
uint32_t maxPayloadSize,
AzNetworking::IConnection& connection
@@ -127,7 +131,8 @@ namespace Multiplayer
uint32_t pendingPacketSize = 0;
EntityReplicatorList replicatorUpdatedList;
MultiplayerPackets::EntityUpdates entityUpdatePacket;
entityUpdatePacket.SetHostTimeMs(serverGameTimeMs);
entityUpdatePacket.SetHostTimeMs(hostTimeMs);
entityUpdatePacket.SetHostFrameId(InvalidHostFrameId);
// Serialize everything
while (!toSendList.empty())
{
@@ -249,7 +254,7 @@ namespace Multiplayer
return toSendList;
}
void EntityReplicationManager::SendEntityUpdates(AZ::TimeMs serverGameTimeMs)
void EntityReplicationManager::SendEntityUpdates(AZ::TimeMs hostTimeMs)
{
EntityReplicatorList toSendList = GenerateEntityUpdateList();
@@ -264,7 +269,7 @@ namespace Multiplayer
// While our to send list is not empty, build up another packet to send
do
{
SendEntityUpdatesPacketHelper(serverGameTimeMs, toSendList, m_maxPayloadSize, m_connection);
SendEntityUpdatesPacketHelper(hostTimeMs, toSendList, m_maxPayloadSize, m_connection);
} while (!toSendList.empty());
}
@@ -747,7 +752,7 @@ namespace Multiplayer
bool EntityReplicationManager::HandleEntityUpdateMessage
(
[[maybe_unused]] AzNetworking::IConnection* connection,
[[maybe_unused]] AzNetworking::IConnection* invokingConnection,
const AzNetworking::IPacketHeader& packetHeader,
const NetworkEntityUpdateMessage& updateMessage
)
@@ -803,7 +808,7 @@ namespace Multiplayer
return handled;
}
bool EntityReplicationManager::HandleEntityRpcMessage([[maybe_unused]] AzNetworking::IConnection* connection, NetworkEntityRpcMessage& message)
bool EntityReplicationManager::HandleEntityRpcMessage(AzNetworking::IConnection* invokingConnection, NetworkEntityRpcMessage& message)
{
EntityReplicator* entityReplicator = GetEntityReplicator(message.GetEntityId());
const bool isReplicatorValid = (entityReplicator != nullptr) && !entityReplicator->IsMarkedForRemoval();
@@ -815,7 +820,7 @@ namespace Multiplayer
}
else
{
return entityReplicator->HandleRpcMessage(message);
return entityReplicator->HandleRpcMessage(invokingConnection, message);
}
}
@@ -823,7 +828,7 @@ namespace Multiplayer
{
if (entityReplicator == nullptr)
{
IMultiplayer* multiplayer = AZ::Interface<IMultiplayer>::Get();
IMultiplayer* multiplayer = GetMultiplayer();
AZLOG_INFO
(
"EntityReplicationManager: Dropping remote RPC message for component %s of rpc index %s, entityId %u has already been deleted",
@@ -833,8 +838,7 @@ namespace Multiplayer
);
return false;
}
return entityReplicator->HandleRpcMessage(message);
return entityReplicator->HandleRpcMessage(nullptr, message);
}
AZ::TimeMs EntityReplicationManager::GetResendTimeoutTimeMs() const
@@ -877,7 +881,6 @@ namespace Multiplayer
AzNetworking::TimeoutResult EntityReplicationManager::OrphanedEntityRpcs::HandleTimeout(AzNetworking::TimeoutQueue::TimeoutItem& item)
{
NetEntityId timedOutEntityId = aznumeric_cast<NetEntityId>(item.m_userData);
auto entityRpcsIter = m_entityRpcMap.find(timedOutEntityId);
if (entityRpcsIter != m_entityRpcMap.end())
{
@@ -887,7 +890,6 @@ namespace Multiplayer
}
m_entityRpcMap.erase(entityRpcsIter);
}
return AzNetworking::TimeoutResult::Delete;
}
@@ -1089,7 +1091,7 @@ namespace Multiplayer
if (m_updateMode == EntityReplicationManager::Mode::LocalServerToRemoteServer)
{
netBindComponent->NotifyMigration(GetRemoteHostId(), GetConnection().GetConnectionId());
netBindComponent->NotifyServerMigration(GetRemoteHostId(), GetConnection().GetConnectionId());
}
bool didSucceed = true;
@@ -1127,7 +1129,7 @@ namespace Multiplayer
}
}
bool EntityReplicationManager::HandleMessage([[maybe_unused]] AzNetworking::IConnection* connection, MultiplayerPackets::EntityMigration& message)
bool EntityReplicationManager::HandleMessage([[maybe_unused]] AzNetworking::IConnection* invokingConnection, MultiplayerPackets::EntityMigration& message)
{
EntityReplicator* replicator = GetEntityReplicator(message.GetEntityId());
{
@@ -13,11 +13,11 @@
#pragma once
#include <Source/NetworkEntity/EntityReplication/EntityReplicator.h>
#include <Source/NetworkEntity/INetworkEntityManager.h>
#include <Source/ReplicationWindows/IReplicationWindow.h>
#include <Source/EntityDomains/IEntityDomain.h>
#include <Source/NetworkEntity/NetworkEntityHandle.h>
#include <Source/Components/NetBindComponent.h>
#include <Multiplayer/NetBindComponent.h>
#include <Multiplayer/INetworkEntityManager.h>
#include <Multiplayer/IReplicationWindow.h>
#include <Multiplayer/IEntityDomain.h>
#include <Multiplayer/NetworkEntityHandle.h>
#include <AzNetworking/DataStructures/TimeoutQueue.h>
#include <AzNetworking/PacketLayer/IPacketHeader.h>
#include <AzCore/std/containers/map.h>
@@ -59,7 +59,7 @@ namespace Multiplayer
HostId GetRemoteHostId() const;
void ActivatePendingEntities();
void SendUpdates(AZ::TimeMs serverGameTimeMs);
void SendUpdates(AZ::TimeMs hostTimeMs);
void Clear(bool forMigration);
bool SetEntityRebasing(NetworkEntityHandle& entityHandle);
@@ -82,10 +82,10 @@ namespace Multiplayer
void AddAutonomousEntityReplicatorCreatedHandle(AZ::Event<NetEntityId>::Handler& handler);
bool HandleMessage(AzNetworking::IConnection* connection, MultiplayerPackets::EntityMigration& message);
bool HandleMessage(AzNetworking::IConnection* invokingConnection, MultiplayerPackets::EntityMigration& message);
bool HandleEntityDeleteMessage(EntityReplicator* entityReplicator, const AzNetworking::IPacketHeader& packetHeader, const NetworkEntityUpdateMessage& updateMessage);
bool HandleEntityUpdateMessage(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, const NetworkEntityUpdateMessage& updateMessage);
bool HandleEntityRpcMessage(AzNetworking::IConnection* connection, NetworkEntityRpcMessage& message);
bool HandleEntityUpdateMessage(AzNetworking::IConnection* invokingConnection, const AzNetworking::IPacketHeader& packetHeader, const NetworkEntityUpdateMessage& updateMessage);
bool HandleEntityRpcMessage(AzNetworking::IConnection* invokingConnection, NetworkEntityRpcMessage& message);
AZ::TimeMs GetResendTimeoutTimeMs() const;
@@ -118,9 +118,9 @@ namespace Multiplayer
using EntityReplicatorList = AZStd::deque<EntityReplicator*>;
EntityReplicatorList GenerateEntityUpdateList();
void SendEntityUpdatesPacketHelper(AZ::TimeMs serverGameTimeMs, EntityReplicatorList& toSendList, uint32_t maxPayloadSize, AzNetworking::IConnection& connection);
void SendEntityUpdatesPacketHelper(AZ::TimeMs hostTimeMs, EntityReplicatorList& toSendList, uint32_t maxPayloadSize, AzNetworking::IConnection& connection);
void SendEntityUpdates(AZ::TimeMs serverGameTimeMs);
void SendEntityUpdates(AZ::TimeMs hostTimeMs);
void SendEntityRpcs(RpcMessages& deferredRpcs, bool reliable);
void MigrateEntityInternal(NetEntityId entityId);
@@ -155,31 +155,27 @@ namespace Multiplayer
OrphanedEntityRpcs(EntityReplicationManager& replicationManager);
void Update();
bool DispatchOrphanedRpcs(EntityReplicator& entityReplicator);
void AddOrphanedRpc(NetEntityId entityId, NetworkEntityRpcMessage& entityPrcMessage);
void AddOrphanedRpc(NetEntityId entityId, NetworkEntityRpcMessage& entityRpcMessage);
AZStd::size_t Size() const { return m_entityRpcMap.size(); }
private:
AzNetworking::TimeoutResult HandleTimeout(AzNetworking::TimeoutQueue::TimeoutItem& item) override;
struct OrphanedRpcs
{
OrphanedRpcs() = default;
OrphanedRpcs(OrphanedRpcs&& rhs)
{
m_rpcMessages.swap(rhs.m_rpcMessages);
m_timeoutId = rhs.m_timeoutId;
rhs.m_timeoutId = AzNetworking::TimeoutId{ 0 };
m_rpcMessages.swap(rhs.m_rpcMessages);
}
AzNetworking::TimeoutId m_timeoutId = AzNetworking::TimeoutId{ 0 };
RpcMessages m_rpcMessages;
AzNetworking::TimeoutId m_timeoutId = AzNetworking::TimeoutId{ 0 };
};
typedef AZStd::unordered_map<NetEntityId, OrphanedRpcs> EntityRpcMap;
EntityRpcMap m_entityRpcMap;
AzNetworking::TimeoutQueue m_timeoutQueue;
EntityReplicationManager& m_replicationManager;
};
OrphanedEntityRpcs m_orphanedEntityRpcs;
EntityReplicatorMap m_entityReplicatorMap;
@@ -16,11 +16,11 @@
#include <Source/NetworkEntity/EntityReplication/PropertySubscriber.h>
#include <Source/NetworkEntity/NetworkEntityAuthorityTracker.h>
#include <Source/NetworkEntity/NetworkEntityTracker.h>
#include <Source/NetworkEntity/NetworkEntityRpcMessage.h>
#include <Source/Components/NetBindComponent.h>
#include <Source/Components/NetworkTransformComponent.h>
#include <Source/AutoGen/Multiplayer.AutoPackets.h>
#include <Include/IMultiplayer.h>
#include <Multiplayer/IMultiplayer.h>
#include <Multiplayer/NetworkEntityRpcMessage.h>
#include <Multiplayer/NetBindComponent.h>
#include <AzNetworking/PacketLayer/IPacket.h>
#include <AzNetworking/Serialization/ISerializer.h>
@@ -448,7 +448,7 @@ namespace Multiplayer
void EntityReplicator::DeferRpcMessage(NetworkEntityRpcMessage& entityRpcMessage)
{
// Received rpc metrics, log rpc sent, number of bytes, and the componentId/rpcId for bandwidth metrics
MultiplayerStats& stats = AZ::Interface<IMultiplayer>::Get()->GetStats();
MultiplayerStats& stats = GetMultiplayer()->GetStats();
stats.RecordRpcSent(entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex(), entityRpcMessage.GetEstimatedSerializeSize());
m_replicationManager.AddDeferredRpcMessage(entityRpcMessage);
@@ -628,10 +628,10 @@ namespace Multiplayer
return result;
}
bool EntityReplicator::HandleRpcMessage(NetworkEntityRpcMessage& entityRpcMessage)
bool EntityReplicator::HandleRpcMessage(AzNetworking::IConnection* invokingConnection, NetworkEntityRpcMessage& entityRpcMessage)
{
// Received rpc metrics, log rpc received, time spent, number of bytes, and the componentId/rpcId for bandwidth metrics
MultiplayerStats& stats = AZ::Interface<IMultiplayer>::Get()->GetStats();
MultiplayerStats& stats = GetMultiplayer()->GetStats();
stats.RecordRpcReceived(entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex(), entityRpcMessage.GetEstimatedSerializeSize());
if (!m_netBindComponent)
@@ -676,7 +676,7 @@ namespace Multiplayer
switch (result)
{
case RpcValidationResult::HandleRpc:
return m_netBindComponent->HandleRpcMessage(GetRemoteNetworkRole(), entityRpcMessage);
return m_netBindComponent->HandleRpcMessage(invokingConnection, GetRemoteNetworkRole(), entityRpcMessage);
case RpcValidationResult::DropRpc:
return true;
case RpcValidationResult::DropRpcAndDisconnect:
@@ -703,7 +703,7 @@ namespace Multiplayer
break;
}
AZ_Assert(false, "Unhandled ERpcValidationResult %d", result);
AZ_Assert(false, "Unhandled RpcValidationResult %d", result);
return false;
}
}
@@ -18,8 +18,8 @@
#include <AzCore/Component/EntityBus.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/std/containers/ring_buffer.h>
#include <Source/Components/NetBindComponent.h>
#include <Source/NetworkEntity/NetworkEntityUpdateMessage.h>
#include <Multiplayer/NetBindComponent.h>
#include <Multiplayer/NetworkEntityUpdateMessage.h>
namespace AzNetworking
{
@@ -75,8 +75,8 @@ namespace Multiplayer
const PropertyPublisher* GetPropertyPublisher() const;
PropertySubscriber* GetPropertySubscriber();
// Handlers for messages
bool HandleRpcMessage(NetworkEntityRpcMessage& entityRpcMessage);
// Handlers for Rpc messages
bool HandleRpcMessage(AzNetworking::IConnection* invokingConnection, NetworkEntityRpcMessage& entityRpcMessage);
//! AZ::EntityBus overrides
//! @{
@@ -12,7 +12,7 @@
#pragma once
#include <Source/Components/NetBindComponent.h>
#include <Multiplayer/NetBindComponent.h>
#include <AzCore/std/containers/ring_buffer.h>
namespace AzNetworking
@@ -12,7 +12,7 @@
#include <Source/NetworkEntity/EntityReplication/PropertySubscriber.h>
#include <Source/NetworkEntity/EntityReplication/EntityReplicationManager.h>
#include <Source/Components/NetBindComponent.h>
#include <Multiplayer/NetBindComponent.h>
namespace Multiplayer
{
@@ -10,7 +10,7 @@
*
*/
#include <Source/NetworkEntity/EntityReplication/ReplicationRecord.h>
#include <Multiplayer/ReplicationRecord.h>
namespace Multiplayer
{
@@ -1,104 +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/FixedSizeVectorBitset.h>
#include <AzNetworking/Serialization/ISerializer.h>
#include <AzNetworking/Utilities/NetworkCommon.h>
#include <Include/MultiplayerTypes.h>
namespace Multiplayer
{
struct ReplicationRecordStats
{
ReplicationRecordStats() = default;
ReplicationRecordStats
(
uint32_t authorityToAuthorityCount,
uint32_t authorityToClientCount,
uint32_t authorityToServerCount,
uint32_t authorityToAutonomousCount,
uint32_t autonomousToAuthorityCount
);
uint32_t m_authorityToAuthorityCount = 0;
uint32_t m_authorityToClientCount = 0;
uint32_t m_authorityToServerCount = 0;
uint32_t m_authorityToAutonomousCount = 0;
uint32_t m_autonomousToAuthorityCount = 0;
bool operator ==(const ReplicationRecordStats& rhs) const;
ReplicationRecordStats operator-(const ReplicationRecordStats& rhs) const;
};
class ReplicationRecord
{
public:
static constexpr uint32_t MaxRecordBits = 2048;
ReplicationRecord() = default;
ReplicationRecord(NetEntityRole netEntityRole);
void SetNetworkRole(NetEntityRole netEntityRole);
NetEntityRole GetNetworkRole() const;
bool AreAllBitsConsumed() const;
void ResetConsumedBits();
void Clear();
void Append(const ReplicationRecord &rhs);
void Subtract(const ReplicationRecord &rhs);
bool HasChanges() const;
bool Serialize(AzNetworking::ISerializer& serializer);
void ConsumeAuthorityToAuthorityBits(uint32_t consumedBits);
void ConsumeAuthorityToClientBits(uint32_t consumedBits);
void ConsumeAuthorityToServerBits(uint32_t consumedBits);
void ConsumeAuthorityToAutonomousBits(uint32_t consumedBits);
void ConsumeAutonomousToAuthorityBits(uint32_t consumedBits);
bool ContainsAuthorityToAuthorityBits() const;
bool ContainsAuthorityToClientBits() const;
bool ContainsAuthorityToServerBits() const;
bool ContainsAuthorityToAutonomousBits() const;
bool ContainsAutonomousToAuthorityBits() const;
uint32_t GetRemainingAuthorityToAuthorityBits() const;
uint32_t GetRemainingAuthorityToClientBits() const;
uint32_t GetRemainingAuthorityToServerBits() const;
uint32_t GetRemainingAuthorityToAutonomousBits() const;
uint32_t GetRemainingAutonomousToAuthorityBits() const;
ReplicationRecordStats GetStats() const;
using RecordBitset = AzNetworking::FixedSizeVectorBitset<MaxRecordBits>;
RecordBitset m_authorityToAuthority;
RecordBitset m_authorityToClient;
RecordBitset m_authorityToServer;
RecordBitset m_authorityToAutonomous;
RecordBitset m_autonomousToAuthority;
uint32_t m_authorityToAuthorityConsumedBits = 0;
uint32_t m_authorityToClientConsumedBits = 0;
uint32_t m_authorityToServerConsumedBits = 0;
uint32_t m_authorityToAutonomousConsumedBits = 0;
uint32_t m_autonomousToAuthorityConsumedBits = 0;
// Sequence number this ReplicationRecord was sent on
AzNetworking::PacketId m_sentPacketId = AzNetworking::InvalidPacketId;
NetEntityRole m_netEntityRole = NetEntityRole::InvalidRole;;
};
}