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;;
};
}
@@ -1,41 +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 <Source/NetworkEntity/INetworkEntityManager.h>
namespace Multiplayer
{
//! @class INetworkEntityDomain
//! @brief A class that determines if an entity should belong to a particular EntityManager.
class INetworkEntityDomain
{
public:
using EntitiesNotInDomain = AZStd::unordered_set<NetEntityId>;
virtual ~INetworkEntityDomain() = default;
//! Enable Entity Domain Exit Tracking for entities on the server.
//! @param ownedEntitySet
virtual void ActivateTracking(const INetworkEntityManager::OwnedEntitySet& ownedEntitySet) = 0;
//! Return the set of entities not in this domain.
//! @param outEntitiesNotInDomain
virtual void RetrieveEntitiesNotInDomain(EntitiesNotInDomain& outEntitiesNotInDomain) const = 0;
//! Returns whether or not an entity should be owned by an entity manager.
//! @param entityHandle the handle of the entity to check for inclusion in the domain
//! @return false if this entity should not belong to the entity manger, true if it could be owned by the entity manager
virtual bool IsInDomain(const ConstNetworkEntityHandle& entityHandle) const = 0;
};
}
@@ -1,158 +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 <Include/MultiplayerTypes.h>
#include <Source/NetworkEntity/NetworkEntityHandle.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/EBus/Event.h>
#include <AzCore/Asset/AssetCommon.h>
namespace Multiplayer
{
class NetworkEntityTracker;
class NetworkEntityAuthorityTracker;
class NetworkEntityRpcMessage;
class MultiplayerComponentRegistry;
using EntityExitDomainEvent = AZ::Event<const ConstNetworkEntityHandle&>;
using ControllersActivatedEvent = AZ::Event<const ConstNetworkEntityHandle&, EntityIsMigrating>;
using ControllersDeactivatedEvent = AZ::Event<const ConstNetworkEntityHandle&, EntityIsMigrating>;
//! @class INetworkEntityManager
//! @brief The interface for managing all networked entities.
class INetworkEntityManager
{
public:
AZ_RTTI(INetworkEntityManager, "{109759DE-9492-439C-A0B1-AE46E6FD029C}");
using OwnedEntitySet = AZStd::unordered_set<ConstNetworkEntityHandle>;
using EntityList = AZStd::vector<NetworkEntityHandle>;
virtual ~INetworkEntityManager() = default;
//! Returns the NetworkEntityTracker for this INetworkEntityManager instance.
//! @return the NetworkEntityTracker for this INetworkEntityManager instance
virtual NetworkEntityTracker* GetNetworkEntityTracker() = 0;
//! Returns the NetworkEntityAuthorityTracker for this INetworkEntityManager instance.
//! @return the NetworkEntityAuthorityTracker for this INetworkEntityManager instance
virtual NetworkEntityAuthorityTracker* GetNetworkEntityAuthorityTracker() = 0;
//! Returns the MultiplayerComponentRegistry for this INetworkEntityManager instance.
//! @return the MultiplayerComponentRegistry for this INetworkEntityManager instance
virtual MultiplayerComponentRegistry* GetMultiplayerComponentRegistry() = 0;
//! Returns the HostId for this INetworkEntityManager instance.
//! @return the HostId for this INetworkEntityManager instance
virtual HostId GetHostId() const = 0;
//! Creates new entities of the given archetype
//! @param prefabEntryId the name of the spawnable to spawn
virtual EntityList CreateEntitiesImmediate(
const PrefabEntityId& prefabEntryId, NetEntityId netEntityId, NetEntityRole netEntityRole, AutoActivate autoActivate,
const AZ::Transform& transform) = 0;
//! Returns an ConstEntityPtr for the provided entityId.
//! @param netEntityId the netEntityId to get an ConstEntityPtr for
//! @return the requested ConstEntityPtr
virtual ConstNetworkEntityHandle GetEntity(NetEntityId netEntityId) const = 0;
//! Returns the total number of entities tracked by this INetworkEntityManager instance.
//! @return the total number of entities tracked by this INetworkEntityManager instance
virtual uint32_t GetEntityCount() const = 0;
//! Adds the provided entity to the internal entity map identified by the provided netEntityId.
//! @param netEntityId the identifier to use for the added entity
//! @param entity the entity to add to the internal entity map
//! @return a NetworkEntityHandle for the newly added entity
virtual NetworkEntityHandle AddEntityToEntityMap(NetEntityId netEntityId, AZ::Entity* entity) = 0;
//! Marks the specified entity for removal and deletion.
//! @param entityHandle the entity to remove and delete
virtual void MarkForRemoval(const ConstNetworkEntityHandle& entityHandle) = 0;
//! Returns true if the indicated entity is marked for removal.
//! @param entityHandle the entity to test if marked for removal
//! @return boolean true if the specified entity is marked for removal, false otherwise
virtual bool IsMarkedForRemoval(const ConstNetworkEntityHandle& entityHandle) const = 0;
//! Unmarks the specified entity so it will no longer be removed and deleted.
//! @param entityHandle the entity to unmark for removal and deletion
virtual void ClearEntityFromRemovalList(const ConstNetworkEntityHandle& entityHandle) = 0;
//! Clears out and deletes all entities registered with the entity manager.
virtual void ClearAllEntities() = 0;
//! Adds an event handler to be invoked when we notify which entities have been marked dirty.
//! @param entityMarkedDirtyHandle event handler for the dirtied entity
virtual void AddEntityMarkedDirtyHandler(AZ::Event<>::Handler& entityMarkedDirtyHandle) = 0;
//! Adds an event handler to be invoked when we notify entities to send their change notifications.
//! @param entityNotifyChangesHandle event handler for the dirtied entity
virtual void AddEntityNotifyChangesHandler(AZ::Event<>::Handler& entityNotifyChangesHandle) = 0;
//! Adds an event handler to be invoked when we notify entities to send their change notifications.
//! @param entityNotifyChangesHandle event handler for the dirtied entity
virtual void AddEntityExitDomainHandler(EntityExitDomainEvent::Handler& entityExitDomainHandler) = 0;
//! Adds an event handler to be invoked when an entities controllers have activated
//! @param controllersActivatedHandler event handler for the entity
virtual void AddControllersActivatedHandler(ControllersActivatedEvent::Handler& controllersActivatedHandler) = 0;
//! Adds an event handler to be invoked when an entities controllers have been deactivated
//! @param controllersDeactivatedHandler event handler for the entity
virtual void AddControllersDeactivatedHandler(ControllersDeactivatedEvent::Handler& controllersDeactivatedHandler) = 0;
//! Notifies entities that they should process their dirty state.
virtual void NotifyEntitiesDirtied() = 0;
//! Notifies entities that they should process change notifications.
virtual void NotifyEntitiesChanged() = 0;
//! Notifies that an entities controllers have activated.
//! @param entityHandle handle to the entity whose controllers have activated
//! @param entityIsMigrating true if the entity is activating after a migration
virtual void NotifyControllersActivated(const ConstNetworkEntityHandle& entityHandle, EntityIsMigrating entityIsMigrating) = 0;
//! Notifies that an entities controllers have been deactivated.
//! @param entityHandle handle to the entity whose controllers have been deactivated
//! @param entityIsMigrating true if the entity is deactivating due to a migration
virtual void NotifyControllersDeactivated(const ConstNetworkEntityHandle& entityHandle, EntityIsMigrating entityIsMigrating) = 0;
//! Handle a local rpc message.
//! @param entityRpcMessage the local rpc message to handle
virtual void HandleLocalRpcMessage(NetworkEntityRpcMessage& message) = 0;
};
// Convenience helpers
inline INetworkEntityManager* GetNetworkEntityManager()
{
return AZ::Interface<INetworkEntityManager>::Get();
}
inline NetworkEntityTracker* GetNetworkEntityTracker()
{
return GetNetworkEntityManager()->GetNetworkEntityTracker();
}
inline NetworkEntityAuthorityTracker* GetNetworkEntityAuthorityTracker()
{
return GetNetworkEntityManager()->GetNetworkEntityAuthorityTracker();
}
inline MultiplayerComponentRegistry* GetMultiplayerComponentRegistry()
{
return GetNetworkEntityManager()->GetMultiplayerComponentRegistry();
}
}
@@ -11,8 +11,8 @@
*/
#include <Source/NetworkEntity/NetworkEntityAuthorityTracker.h>
#include <Source/NetworkEntity/INetworkEntityManager.h>
#include <Source/Components/NetBindComponent.h>
#include <Multiplayer/NetBindComponent.h>
#include <Multiplayer/INetworkEntityManager.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/Console/ILogger.h>
#include <AzNetworking/Utilities/NetworkCommon.h>
@@ -10,11 +10,11 @@
*
*/
#include <Source/NetworkEntity/NetworkEntityHandle.h>
#include <Multiplayer/NetworkEntityHandle.h>
#include <Multiplayer/MultiplayerController.h>
#include <Multiplayer/MultiplayerComponent.h>
#include <Multiplayer/NetBindComponent.h>
#include <Source/NetworkEntity/NetworkEntityTracker.h>
#include <Source/Components/NetBindComponent.h>
#include <Source/Components/MultiplayerController.h>
#include <Source/Components/MultiplayerComponent.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/Console/ILogger.h>
@@ -1,141 +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 <AzCore/Component/Entity.h>
#include <Include/MultiplayerTypes.h>
namespace Multiplayer
{
class MultiplayerController;
class NetworkEntityTracker;
class NetBindComponent;
//! @class ConstNetworkEntityHandle
//! @brief This class provides a wrapping around handle ids.
//! It is optimized to avoid using the hashmap lookup unless the hashmap has had an item removed.
class ConstNetworkEntityHandle
{
public:
//! Constructs a nullptr handle.
ConstNetworkEntityHandle() = default;
//! Constructs a ConstNetworkEntityHandle given an entity, an entity tracker
//! @param entity pointer to the entity to construct a ConstNetworkEntityHandle for
//! @param entityTracker pointer to the entity tracker that tracks the entity
ConstNetworkEntityHandle(AZ::Entity* entity, const NetworkEntityTracker* entityTracker);
//! Constructs a ConstNetworkEntityHandle given an entity, a networkEntityId, and an entity tracker
//! @param entity pointer to the entity to construct a ConstNetworkEntityHandle for
//! @param netEntityId the networkEntityId of the entity
//! @param entityTracker pointer to the entity tracker that tracks the entity
ConstNetworkEntityHandle(AZ::Entity* entity, NetEntityId netEntityId, const NetworkEntityTracker* entityTracker);
//! Constructs a ConstNetworkEntityHandle given an entity, a networked entityId, an entity tracker, and a dirty version
//! @param netBindComponent pointer to the entities NetBindComponent
//! @param entityTracker pointer to the entity tracker that tracks the entity
ConstNetworkEntityHandle(NetBindComponent* netBindComponent, const NetworkEntityTracker* entityTracker);
ConstNetworkEntityHandle(const ConstNetworkEntityHandle&) = default;
//! Access the AZ::Entity if it safely exists, nullptr or false is returned if the entity does not exist.
//! @{
bool Exists() const;
AZ::Entity* GetEntity();
const AZ::Entity* GetEntity() const;
//! @}
//! Operators providing pointer semantics.
//! @{
bool operator ==(const ConstNetworkEntityHandle& rhs) const;
bool operator !=(const ConstNetworkEntityHandle& rhs) const;
friend bool operator ==(const ConstNetworkEntityHandle& lhs, AZStd::nullptr_t);
friend bool operator ==(AZStd::nullptr_t, const ConstNetworkEntityHandle& rhs);
friend bool operator !=(const ConstNetworkEntityHandle& lhs, AZStd::nullptr_t);
friend bool operator !=(AZStd::nullptr_t, const ConstNetworkEntityHandle& rhs);
friend bool operator ==(const ConstNetworkEntityHandle& lhs, const AZ::Entity* rhs);
friend bool operator ==(const AZ::Entity* lhs, const ConstNetworkEntityHandle& rhs);
friend bool operator !=(const ConstNetworkEntityHandle& lhs, const AZ::Entity* rhs);
friend bool operator !=(const AZ::Entity* lhs, const ConstNetworkEntityHandle& rhs);
//! @}
bool operator <(const ConstNetworkEntityHandle& rhs) const;
explicit operator bool() const;
//! Resets the handle to a nullptr state.
void Reset();
void Reset(const ConstNetworkEntityHandle& handle);
//! Returns the networkEntityId of the entity this handle points to.
//! @return the networkEntityId of the entity this handle points to
NetEntityId GetNetEntityId() const;
//! Returns the cached netBindComponent for this entity, or nullptr if it doesn't exist.
//! @return the cached netBindComponent for this entity, or nullptr if it doesn't exist
NetBindComponent* GetNetBindComponent() const;
//! Returns a specific component on of entity given a typeId.
//! @param typeId the typeId of the component to find and return
//! @return pointer to the requested component, or nullptr if it doesn't exist on the entity
const AZ::Component* FindComponent(const AZ::TypeId& typeId) const;
//! Returns a specific component on of entity by class type.
//! @return pointer to the requested component, or nullptr if it doesn't exist on the entity
template <typename Component>
const Component* FindComponent() const;
//! Helper function for sorting EntityHandles by netEntityId.
static bool Compare(const ConstNetworkEntityHandle& lhs, const ConstNetworkEntityHandle& rhs);
protected:
mutable uint32_t m_changeDirty = 0; // Optimization so we don't need to recheck the hashmap
mutable AZ::Entity* m_entity = nullptr;
mutable NetBindComponent* m_netBindComponent = nullptr;
const NetworkEntityTracker* m_networkEntityTracker = nullptr;
NetEntityId m_netEntityId = InvalidNetEntityId;
};
class NetworkEntityHandle
: public ConstNetworkEntityHandle
{
public:
using ConstNetworkEntityHandle::ConstNetworkEntityHandle;
//! Initializes the underlying entity if possible.
void Init();
//! Activates the underlying entity if possible.
void Activate();
//! Deactivates the underlying entity if possible.
void Deactivate();
//! Gets the BaseController from the first component on an Entity with the supplied typeId AND which inherits from Multiplayer::BaseComponent
MultiplayerController* FindController(const AZ::TypeId& typeId);
template <typename Controller>
Controller* FindController();
using ConstNetworkEntityHandle::FindComponent;
AZ::Component* FindComponent(const AZ::TypeId& typeId);
template <typename ComponentType>
ComponentType* FindComponent();
};
}
#include "Source/NetworkEntity/NetworkEntityHandle.inl"
@@ -1,138 +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.
*
*/
namespace Multiplayer
{
inline bool operator ==(const ConstNetworkEntityHandle& lhs, AZStd::nullptr_t)
{
return !lhs.Exists();
}
inline bool operator ==(AZStd::nullptr_t, const ConstNetworkEntityHandle& rhs)
{
return !rhs.Exists();
}
inline bool operator !=(const ConstNetworkEntityHandle& lhs, AZStd::nullptr_t)
{
return lhs.Exists();
}
inline bool operator !=(AZStd::nullptr_t, const ConstNetworkEntityHandle& rhs)
{
return rhs.Exists();
}
inline bool operator==(const ConstNetworkEntityHandle& lhs, const AZ::Entity* rhs)
{
return lhs.m_entity == rhs;
}
inline bool operator==(const AZ::Entity* lhs, const ConstNetworkEntityHandle& rhs)
{
return operator==(rhs, lhs);
}
inline bool operator!=(const ConstNetworkEntityHandle& lhs, const AZ::Entity* rhs)
{
return lhs.m_entity != rhs;
}
inline bool operator!=(const AZ::Entity* lhs, const ConstNetworkEntityHandle& rhs)
{
return operator!=(rhs, lhs);
}
inline NetEntityId ConstNetworkEntityHandle::GetNetEntityId() const
{
return m_netEntityId;
}
template <class ComponentType>
inline const ComponentType* ConstNetworkEntityHandle::FindComponent() const
{
if (const AZ::Entity* entity{ GetEntity() })
{
return entity->template FindComponent<ComponentType>();
}
return nullptr;
}
inline bool ConstNetworkEntityHandle::Compare(const ConstNetworkEntityHandle& lhs, const ConstNetworkEntityHandle& rhs)
{
return lhs.m_netEntityId < rhs.m_netEntityId;
}
inline void NetworkEntityHandle::Init()
{
if (AZ::Entity* entity{ GetEntity() })
{
entity->Init();
}
}
inline void NetworkEntityHandle::Activate()
{
if (AZ::Entity* entity{ GetEntity() })
{
entity->Activate();
}
}
inline void NetworkEntityHandle::Deactivate()
{
if (AZ::Entity* entity{ GetEntity() })
{
entity->Deactivate();
}
}
template <typename ControllerType>
inline ControllerType* NetworkEntityHandle::FindController()
{
return static_cast<ControllerType*>(FindController(ControllerType::ComponentType::RTTI_Type()));
}
template <typename ComponentType>
inline ComponentType* NetworkEntityHandle::FindComponent()
{
if (AZ::Entity* entity{ GetEntity() })
{
return entity->template FindComponent<ComponentType>();
}
return nullptr;
}
}
//! AZStd::hash support.
namespace AZStd
{
template <>
class hash<Multiplayer::NetworkEntityHandle>
{
public:
size_t operator()(const Multiplayer::NetworkEntityHandle &rhs) const
{
return hash<Multiplayer::NetEntityId>()(rhs.GetNetEntityId());
}
};
template <>
class hash<Multiplayer::ConstNetworkEntityHandle>
{
public:
size_t operator()(const Multiplayer::ConstNetworkEntityHandle &rhs) const
{
return hash<Multiplayer::NetEntityId>()(rhs.GetNetEntityId());
}
};
}
@@ -11,7 +11,6 @@
*/
#include <Source/NetworkEntity/NetworkEntityManager.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/Console/ILogger.h>
@@ -22,9 +21,9 @@
#include <AzFramework/Entity/EntityContextBus.h>
#include <AzFramework/Entity/GameEntityContextBus.h>
#include <AzFramework/Spawnable/SpawnableEntitiesInterface.h>
#include <Include/IMultiplayer.h>
#include <Multiplayer/IMultiplayer.h>
#include <Multiplayer/NetBindComponent.h>
#include <Pipeline/NetworkSpawnableHolderComponent.h>
#include <Source/Components/NetBindComponent.h>
namespace Multiplayer
{
@@ -38,7 +37,6 @@ namespace Multiplayer
, m_onSpawnedHandler([this](AZ::Data::Asset<AzFramework::Spawnable> spawnable) { this->OnSpawned(spawnable); })
, m_onDespawnedHandler([this](AZ::Data::Asset<AzFramework::Spawnable> spawnable) { this->OnDespawned(spawnable); })
{
AZ::Interface<INetworkEntityManager>::Register(this);
AzFramework::RootSpawnableNotificationBus::Handler::BusConnect();
AzFramework::SpawnableEntitiesInterface::Get()->AddOnSpawnedHandler(m_onSpawnedHandler);
@@ -48,7 +46,6 @@ namespace Multiplayer
NetworkEntityManager::~NetworkEntityManager()
{
AzFramework::RootSpawnableNotificationBus::Handler::BusDisconnect();
AZ::Interface<INetworkEntityManager>::Unregister(this);
}
void NetworkEntityManager::Initialize(HostId hostId, AZStd::unique_ptr<IEntityDomain> entityDomain)
@@ -218,7 +215,7 @@ namespace Multiplayer
{
NetBindComponent* netBindComponent = entity->FindComponent<NetBindComponent>();
AZ_Assert(netBindComponent != nullptr, "Attempting to send an RPC to an entity with no NetBindComponent");
netBindComponent->HandleRpcMessage(NetEntityRole::Server, rpcMessage);
netBindComponent->HandleRpcMessage(nullptr, NetEntityRole::Server, rpcMessage);
}
}
m_localDeferredRpcMessages.clear();
@@ -389,9 +386,24 @@ namespace Multiplayer
return returnList;
}
INetworkEntityManager::EntityList NetworkEntityManager::CreateEntitiesImmediate(
const PrefabEntityId& prefabEntryId, NetEntityId netEntityId, NetEntityRole netEntityRole,
AutoActivate autoActivate, const AZ::Transform& transform)
INetworkEntityManager::EntityList NetworkEntityManager::CreateEntitiesImmediate
(
const PrefabEntityId& prefabEntryId,
NetEntityRole netEntityRole,
const AZ::Transform& transform
)
{
return CreateEntitiesImmediate(prefabEntryId, NextId(), netEntityRole, AutoActivate::Activate, transform);
}
INetworkEntityManager::EntityList NetworkEntityManager::CreateEntitiesImmediate
(
const PrefabEntityId& prefabEntryId,
NetEntityId netEntityId,
NetEntityRole netEntityRole,
AutoActivate autoActivate,
const AZ::Transform& transform
)
{
INetworkEntityManager::EntityList returnList;
@@ -460,7 +472,7 @@ namespace Multiplayer
void NetworkEntityManager::OnRootSpawnableAssigned(
[[maybe_unused]] AZ::Data::Asset<AzFramework::Spawnable> rootSpawnable, [[maybe_unused]] uint32_t generation)
{
auto* multiplayer = AZ::Interface<IMultiplayer>::Get();
auto* multiplayer = GetMultiplayer();
const auto agentType = multiplayer->GetAgentType();
if (agentType == MultiplayerAgentType::Client)
@@ -472,7 +484,7 @@ namespace Multiplayer
void NetworkEntityManager::OnRootSpawnableReleased([[maybe_unused]] uint32_t generation)
{
// TODO: Do we need to clear all entities here?
auto* multiplayer = AZ::Interface<IMultiplayer>::Get();
auto* multiplayer = GetMultiplayer();
const auto agentType = multiplayer->GetAgentType();
if (agentType == MultiplayerAgentType::Client)
@@ -518,7 +530,7 @@ namespace Multiplayer
return;
}
auto* multiplayer = AZ::Interface<IMultiplayer>::Get();
auto* multiplayer = GetMultiplayer();
const auto agentType = multiplayer->GetAgentType();
const bool spawnImmediately =
@@ -15,13 +15,13 @@
#include <AzCore/EBus/ScheduledEvent.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
#include <Source/NetworkEntity/INetworkEntityManager.h>
#include <Source/NetworkEntity/NetworkEntityAuthorityTracker.h>
#include <Source/NetworkEntity/NetworkEntityTracker.h>
#include <Source/NetworkEntity/NetworkEntityRpcMessage.h>
#include <Source/EntityDomains/IEntityDomain.h>
#include <Source/NetworkEntity/NetworkSpawnableLibrary.h>
#include <Source/Components/MultiplayerComponentRegistry.h>
#include <Multiplayer/IEntityDomain.h>
#include <Multiplayer/INetworkEntityManager.h>
#include <Multiplayer/MultiplayerComponentRegistry.h>
#include <Multiplayer/NetworkEntityRpcMessage.h>
namespace Multiplayer
{
@@ -47,10 +47,20 @@ namespace Multiplayer
ConstNetworkEntityHandle GetEntity(NetEntityId netEntityId) const override;
EntityList CreateEntitiesImmediate(const AzFramework::Spawnable& spawnable, NetEntityRole netEntityRole);
EntityList CreateEntitiesImmediate(
const PrefabEntityId& prefabEntryId, NetEntityId netEntityId, NetEntityRole netEntityRole,
AutoActivate autoActivate, const AZ::Transform& transform) override;
EntityList CreateEntitiesImmediate
(
const PrefabEntityId& prefabEntryId,
NetEntityRole netEntityRole,
const AZ::Transform& transform
) override;
EntityList CreateEntitiesImmediate
(
const PrefabEntityId& prefabEntryId,
NetEntityId netEntityId,
NetEntityRole netEntityRole,
AutoActivate autoActivate,
const AZ::Transform& transform
) override;
uint32_t GetEntityCount() const override;
NetworkEntityHandle AddEntityToEntityMap(NetEntityId netEntityId, AZ::Entity* entity) override;
@@ -81,7 +91,6 @@ namespace Multiplayer
private:
void RemoveEntities();
NetEntityId NextId();
void OnSpawned(AZ::Data::Asset<AzFramework::Spawnable> spawnable);
@@ -10,7 +10,7 @@
*
*/
#include <Source/NetworkEntity/NetworkEntityRpcMessage.h>
#include <Multiplayer/NetworkEntityRpcMessage.h>
#include <AzNetworking/Serialization/NetworkInputSerializer.h>
#include <AzNetworking/Serialization/NetworkOutputSerializer.h>
#include <AzCore/Console/ILogger.h>
@@ -1,122 +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/Serialization/ISerializer.h>
#include <AzNetworking/DataStructures/ByteBuffer.h>
#include <Include/MultiplayerTypes.h>
namespace Multiplayer
{
struct IRpcParamStruct;
// The maximum number of RPC's we can aggregate into a single packet
static constexpr uint32_t MaxAggregateRpcMessages = 1024;
//! @class NetworkEntityRpcMessage
//! @brief Remote procedure call data.
class NetworkEntityRpcMessage
{
public:
AZ_TYPE_INFO(NetworkEntityRpcMessage, "{3AA5E1A5-6383-46C1-9817-F1B8C2325178}");
NetworkEntityRpcMessage() = default;
NetworkEntityRpcMessage(NetworkEntityRpcMessage&& rhs);
NetworkEntityRpcMessage(const NetworkEntityRpcMessage& rhs);
//! Fill explicit constructor.
//! @param rpcDeliveryType the delivery type (origin and target) for this rpc
//! @param entityId the networked entityId of the entity handling this rpc
//! @param componentType the networked componentId of the component handling this rpc
//! @param rpcIndex the component defined rpc index, so the component knows which rpc this message corresponds to
//! @param isReliable whether or not this rpc should be sent reliably
explicit NetworkEntityRpcMessage(RpcDeliveryType rpcDeliveryType, NetEntityId entityId, NetComponentId componentId, RpcIndex rpcIndex, ReliabilityType isReliable);
NetworkEntityRpcMessage& operator =(NetworkEntityRpcMessage&& rhs);
NetworkEntityRpcMessage& operator =(const NetworkEntityRpcMessage& rhs);
bool operator ==(const NetworkEntityRpcMessage& rhs) const;
bool operator !=(const NetworkEntityRpcMessage& rhs) const;
//! Returns an estimated serialization footprint for this NetworkEntityRpcMessage.
//! @return an estimated serialization footprint for this NetworkEntityRpcMessage
uint32_t GetEstimatedSerializeSize() const;
//! Gets the current value of RpcDeliveryType.
//! @return the current value of RpcDeliveryType
RpcDeliveryType GetRpcDeliveryType() const;
//! Sets the current value for RpcDeliveryType.
//! @param value the value to set RpcDeliveryType to
void SetRpcDeliveryType(RpcDeliveryType value);
//! Gets the current value of EntityId.
//! @return the current value of EntityId
NetEntityId GetEntityId() const;
//! Gets the current value of EntityComponentType.
//! @return the current value of EntityComponentType
NetComponentId GetComponentId() const;
//! Gets the current value of RpcIndex.
//! @return the current value of RpcIndex
RpcIndex GetRpcIndex() const;
//! Writes the data contained inside a_Params to this NetworkEntityRpcMessage's blob buffer.
//! @param params the parameters to save inside this NetworkEntityRpcMessage instance
bool SetRpcParams(IRpcParamStruct& params);
//! Reads the data contained inside this NetworkEntityRpcMessage's blob buffer and stores them in outParams.
//! @param outParams the parameters instance to store to the resulting data inside
bool GetRpcParams(IRpcParamStruct& outParams);
//! Base serialize method for all serializable structures or classes to implement.
//! @param serializer ISerializer instance to use for serialization
//! @return boolean true for success, false for serialization failure
bool Serialize(AzNetworking::ISerializer& serializer);
//! Sets this RPC's reliable delivery flag.
//! @param reliabilityType the reliability type for this RPC
void SetReliability(ReliabilityType reliabilityType);
//! Returns whether or not this RPC has been flagged for reliable delivery.
//! @return the reliability type of this RPC
ReliabilityType GetReliability() const;
private:
// Serialized payload data
RpcDeliveryType m_rpcDeliveryType = RpcDeliveryType::None;
NetEntityId m_entityId = InvalidNetEntityId;
NetComponentId m_componentId = InvalidNetComponentId;
RpcIndex m_rpcIndex = RpcIndex{ 0 };
// Only allocated if we actually have data
// This is to prevent blowing out stack memory if we declare an array of these EntityUpdateMessages
AZStd::unique_ptr<AzNetworking::PacketEncodingBuffer> m_data;
// Non-serialized RPC metadata
ReliabilityType m_isReliable = ReliabilityType::Reliable;
};
struct IRpcParamStruct
{
virtual ~IRpcParamStruct() {}
virtual bool Serialize(AzNetworking::ISerializer& serializer) = 0;
};
struct ComponentRpcEmptyStruct
: public IRpcParamStruct
{
bool Serialize(AzNetworking::ISerializer&) override { return true; }
};
}
@@ -11,7 +11,7 @@
*/
#include <Source/NetworkEntity/NetworkEntityTracker.h>
#include <Source/NetworkEntity/NetworkEntityHandle.h>
#include <Multiplayer/NetworkEntityHandle.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/Console/ILogger.h>
@@ -12,8 +12,8 @@
#pragma once
#include <Include/MultiplayerTypes.h>
#include <Source/NetworkEntity/NetworkEntityHandle.h>
#include <Multiplayer/MultiplayerTypes.h>
#include <Multiplayer/NetworkEntityHandle.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/Component/Entity.h>
@@ -10,7 +10,7 @@
*
*/
#include <Source/NetworkEntity/NetworkEntityUpdateMessage.h>
#include <Multiplayer/NetworkEntityUpdateMessage.h>
#include <AzNetworking/Serialization/NetworkInputSerializer.h>
#include <AzNetworking/Serialization/NetworkOutputSerializer.h>
#include <AzCore/Console/ILogger.h>
@@ -1,125 +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/Serialization/ISerializer.h>
#include <AzNetworking/DataStructures/ByteBuffer.h>
#include <AzCore/Name/Name.h>
#include <Include/MultiplayerTypes.h>
namespace Multiplayer
{
// The maximum number of entity updates we can stuff into a single update packet
static const uint32_t MaxAggregateEntityMessages = 2048;
//! @class NetworkEntityUpdateMessage
//! @brief Property replication packet.
class NetworkEntityUpdateMessage
{
public:
AZ_TYPE_INFO(NetworkEntityUpdateMessage, "{CFCA08F7-547B-4B89-9794-37A8679608DF}");
NetworkEntityUpdateMessage() = default;
NetworkEntityUpdateMessage(NetworkEntityUpdateMessage&& rhs);
NetworkEntityUpdateMessage(const NetworkEntityUpdateMessage& rhs);
//! Constructor for update without a slice name (remote replicator established).
//! @param entityRole the role of the entity being replicated
//! @param entityId the networkId of the entity being replicated
explicit NetworkEntityUpdateMessage(NetEntityRole entityRole, NetEntityId entityId);
//! Constructor for update with a slice name (no remote replicator established).
//! @param entityRole the role of the entity being replicated
//! @param entityId the networkId of the entity being replicated
//! @param prefabEntityId the prefab entityId to clone this replicated entity from
explicit NetworkEntityUpdateMessage(NetEntityRole entityRole, NetEntityId entityId, const PrefabEntityId& prefabEntityId);
//! Constructor for an entity delete message.
//! @param entityId the networkId of the entity being deleted
//! @param isMigrated whether or not the entity is being migrated or deleted
//! @param takeOwnership true if the remote replicator should take ownership of the entity
explicit NetworkEntityUpdateMessage(NetEntityId entityId, bool isMigrated, bool takeOwnership);
NetworkEntityUpdateMessage& operator =(NetworkEntityUpdateMessage&& rhs);
NetworkEntityUpdateMessage& operator =(const NetworkEntityUpdateMessage& rhs);
bool operator ==(const NetworkEntityUpdateMessage& rhs) const;
bool operator !=(const NetworkEntityUpdateMessage& rhs) const;
//! Returns an estimated serialization footprint for this NetworkEntityUpdateMessage.
//! @return an estimated serialization footprint for this NetworkEntityUpdateMessage
uint32_t GetEstimatedSerializeSize() const;
//! Gets the current value of NetworkRole.
//! @return the current value of NetworkRole
NetEntityRole GetNetworkRole() const;
//! Gets the entities networkId.
//! @return the entities networkId
NetEntityId GetEntityId() const;
//! Gets the current value of IsDelete (true if this represents a DeleteProxy message).
//! @return the current value of IsDelete
bool GetIsDelete() const;
//! Returns whether or not the entity was migrated.
//! @return whether or not the entity was migrated
bool GetWasMigrated() const;
//! Gets the current value of TakeOwnership.
//! @return the current value of TakeOwnership
bool GetTakeOwnership() const;
//! Gets the current value of HasValidPrefabId.
//! @return the current value of HasValidPrefabId
bool GetHasValidPrefabId() const;
//! Sets the current value for PrefabEntityId.
//! @param value the value to set PrefabEntityId to
void SetPrefabEntityId(const PrefabEntityId& value);
//! Gets the current value of PrefabEntityId.
//! @return the current value of PrefabEntityId
const PrefabEntityId& GetPrefabEntityId() const;
//! Sets the current value for Data
//! @param value the value to set Data to
void SetData(const AzNetworking::PacketEncodingBuffer& value);
//! Gets the current value of Data.
//! @return the current value of Data
const AzNetworking::PacketEncodingBuffer* GetData() const;
//! Retrieves a non-const reference to the value of Data.
//! @return a non-const reference to the value of Data
AzNetworking::PacketEncodingBuffer& ModifyData();
//! Base serialize method for all serializable structures or classes to implement.
//! @param serializer ISerializer instance to use for serialization
//! @return boolean true for success, false for serialization failure
bool Serialize(AzNetworking::ISerializer& serializer);
private:
NetEntityRole m_networkRole = NetEntityRole::InvalidRole;
NetEntityId m_entityId = InvalidNetEntityId;
bool m_isDelete = false;
bool m_wasMigrated = false;
bool m_takeOwnership = false;
bool m_hasValidPrefabId = false;
PrefabEntityId m_prefabEntityId;
// Only allocated if we actually have data
// This is to prevent blowing out stack memory if we declare an array of these EntityUpdateMessages
AZStd::unique_ptr<AzNetworking::PacketEncodingBuffer> m_data;
};
}