Fixes to sending entity updates and entity rpcs within an environment set up for cross host entity migration
Signed-off-by: kberg-amzn <karlberg@amazon.com>
This commit is contained in:
@@ -40,8 +40,7 @@ namespace Multiplayer
|
||||
virtual EntityReplicationManager& GetReplicationManager() = 0;
|
||||
|
||||
//! Creates and manages sending updates to the remote endpoint.
|
||||
//! @param hostTimeMs current server game time in milliseconds
|
||||
virtual void Update(AZ::TimeMs hostTimeMs) = 0;
|
||||
virtual void Update() = 0;
|
||||
|
||||
//! Returns whether update messages can be sent to the connection.
|
||||
//! @return true if update messages can be sent
|
||||
|
||||
+4
-6
@@ -60,7 +60,7 @@ namespace Multiplayer
|
||||
const HostId& GetRemoteHostId() const;
|
||||
|
||||
void ActivatePendingEntities();
|
||||
void SendUpdates(AZ::TimeMs hostTimeMs);
|
||||
void SendUpdates();
|
||||
void Clear(bool forMigration);
|
||||
|
||||
bool SetEntityRebasing(NetworkEntityHandle& entityHandle);
|
||||
@@ -81,7 +81,7 @@ namespace Multiplayer
|
||||
|
||||
void AddDeferredRpcMessage(NetworkEntityRpcMessage& rpcMessage);
|
||||
|
||||
void AddAutonomousEntityReplicatorCreatedHandle(AZ::Event<NetEntityId>::Handler& handler);
|
||||
void AddAutonomousEntityReplicatorCreatedHandler(AZ::Event<NetEntityId>::Handler& handler);
|
||||
void AddSendMigrateEntityEventHandler(SendMigrateEntityEvent::Handler& handler);
|
||||
|
||||
bool HandleEntityMigration(AzNetworking::IConnection* invokingConnection, EntityMigrationMessage& message);
|
||||
@@ -120,10 +120,8 @@ namespace Multiplayer
|
||||
using EntityReplicatorList = AZStd::deque<EntityReplicator*>;
|
||||
EntityReplicatorList GenerateEntityUpdateList();
|
||||
|
||||
void SendEntityUpdatesPacketHelper(AZ::TimeMs hostTimeMs, EntityReplicatorList& toSendList, uint32_t maxPayloadSize, AzNetworking::IConnection& connection);
|
||||
|
||||
void SendEntityUpdates(AZ::TimeMs hostTimeMs);
|
||||
void SendEntityRpcs(RpcMessages& deferredRpcs, bool reliable);
|
||||
void SendEntityUpdateMessages(EntityReplicatorList& replicatorList);
|
||||
void SendEntityRpcs(RpcMessages& rpcMessages, bool reliable);
|
||||
|
||||
void MigrateEntityInternal(NetEntityId entityId);
|
||||
void OnEntityExitDomain(const ConstNetworkEntityHandle& entityHandle);
|
||||
|
||||
+1
@@ -66,6 +66,7 @@ namespace Multiplayer
|
||||
bool IsReadyToActivate() const;
|
||||
|
||||
NetworkEntityUpdateMessage GenerateUpdatePacket();
|
||||
void FinalizeSerialization(AzNetworking::PacketId sentId);
|
||||
|
||||
AZ::TimeMs GetResendTimeoutTimeMs() const;
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ namespace Multiplayer
|
||||
// Non-serialized RPC metadata
|
||||
ReliabilityType m_isReliable = ReliabilityType::Reliable;
|
||||
};
|
||||
using NetworkEntityRpcVector = AZStd::fixed_vector<NetworkEntityRpcMessage, MaxAggregateRpcMessages>;
|
||||
|
||||
struct IRpcParamStruct
|
||||
{
|
||||
|
||||
@@ -118,4 +118,5 @@ namespace Multiplayer
|
||||
// This is to prevent blowing out stack memory if we declare an array of these EntityUpdateMessages
|
||||
AZStd::unique_ptr<AzNetworking::PacketEncodingBuffer> m_data;
|
||||
};
|
||||
using NetworkEntityUpdateVector = AZStd::fixed_vector<NetworkEntityUpdateMessage, MaxAggregateEntityMessages>;
|
||||
}
|
||||
|
||||
@@ -10,10 +10,14 @@
|
||||
|
||||
#include <Multiplayer/MultiplayerTypes.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityRpcMessage.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityUpdateMessage.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
class EntityReplicator;
|
||||
|
||||
struct EntityReplicationData
|
||||
{
|
||||
EntityReplicationData() = default;
|
||||
@@ -21,6 +25,8 @@ namespace Multiplayer
|
||||
float m_priority = 0.0f;
|
||||
};
|
||||
using ReplicationSet = AZStd::map<ConstNetworkEntityHandle, EntityReplicationData>;
|
||||
using RpcMessages = AZStd::list<NetworkEntityRpcMessage>;
|
||||
using EntityReplicatorList = AZStd::deque<EntityReplicator*>;
|
||||
|
||||
class IReplicationWindow
|
||||
{
|
||||
@@ -33,6 +39,8 @@ namespace Multiplayer
|
||||
virtual uint32_t GetMaxProxyEntityReplicatorSendCount() const = 0;
|
||||
virtual bool IsInWindow(const ConstNetworkEntityHandle& entityPtr, NetEntityRole& outNetworkRole) const = 0;
|
||||
virtual void UpdateWindow() = 0;
|
||||
virtual AzNetworking::PacketId SendEntityUpdateMessages(NetworkEntityUpdateVector& entityUpdateVector) = 0;
|
||||
virtual void SendEntityRpcs(NetworkEntityRpcVector& entityRpcVector, bool reliable) = 0;
|
||||
virtual void DebugDraw() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<Packet Name="Accept" HandshakePacket="true" Desc="Server accept packet">
|
||||
<Member Type="Multiplayer::LongNetworkString" Name="map" />
|
||||
</Packet>
|
||||
|
||||
|
||||
<Packet Name="ReadyForEntityUpdates" Desc="Client confirming it is ready to receive entity updates">
|
||||
<Member Type="bool" Name="readyForEntityUpdates" />
|
||||
</Packet>
|
||||
@@ -31,11 +31,11 @@
|
||||
<Packet Name="EntityUpdates" Desc="A packet that contains multiple entity updates">
|
||||
<Member Type="AZ::TimeMs" Name="hostTimeMs" Init="AZ::TimeMs{ 0 }" />
|
||||
<Member Type="Multiplayer::HostFrameId" Name="hostFrameId" Init="Multiplayer::InvalidHostFrameId" />
|
||||
<Member Type="Multiplayer::NetworkEntityUpdateMessage" Name="entityMessages" Container="Vector" Count="Multiplayer::MaxAggregateEntityMessages" />
|
||||
<Member Type="Multiplayer::NetworkEntityUpdateVector" Name="entityMessages" />
|
||||
</Packet>
|
||||
|
||||
<Packet Name="EntityRpcs" Desc="A packet that contains multiple entity rpcs">
|
||||
<Member Type="Multiplayer::NetworkEntityRpcMessage" Name="entityRpcs" Container="Vector" Count="Multiplayer::MaxAggregateRpcMessages" />
|
||||
<Member Type="Multiplayer::NetworkEntityRpcVector" Name="entityRpcs" />
|
||||
</Packet>
|
||||
|
||||
<Packet Name="ClientMigration" Desc="Tell a client to migrate to a new server">
|
||||
|
||||
@@ -50,9 +50,9 @@ namespace Multiplayer
|
||||
return m_entityReplicationManager;
|
||||
}
|
||||
|
||||
void ClientToServerConnectionData::Update(AZ::TimeMs hostTimeMs)
|
||||
void ClientToServerConnectionData::Update()
|
||||
{
|
||||
m_entityReplicationManager.ActivatePendingEntities();
|
||||
m_entityReplicationManager.SendUpdates(hostTimeMs);
|
||||
m_entityReplicationManager.SendUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Multiplayer
|
||||
ConnectionDataType GetConnectionDataType() const override;
|
||||
AzNetworking::IConnection* GetConnection() const override;
|
||||
EntityReplicationManager& GetReplicationManager() override;
|
||||
void Update(AZ::TimeMs hostTimeMs) override;
|
||||
void Update() override;
|
||||
bool CanSendUpdates() const override;
|
||||
void SetCanSendUpdates(bool canSendUpdates) override;
|
||||
//! @}
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Multiplayer
|
||||
return m_entityReplicationManager;
|
||||
}
|
||||
|
||||
void ServerToClientConnectionData::Update(AZ::TimeMs hostTimeMs)
|
||||
void ServerToClientConnectionData::Update()
|
||||
{
|
||||
m_entityReplicationManager.ActivatePendingEntities();
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace Multiplayer
|
||||
// potentially false if we just migrated the player, if that is the case, don't send any more updates
|
||||
if (netBindComponent != nullptr && (netBindComponent->GetNetEntityRole() == NetEntityRole::Authority))
|
||||
{
|
||||
m_entityReplicationManager.SendUpdates(hostTimeMs);
|
||||
m_entityReplicationManager.SendUpdates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Multiplayer
|
||||
ConnectionDataType GetConnectionDataType() const override;
|
||||
AzNetworking::IConnection* GetConnection() const override;
|
||||
EntityReplicationManager& GetReplicationManager() override;
|
||||
void Update(AZ::TimeMs hostTimeMs) override;
|
||||
void Update() override;
|
||||
bool CanSendUpdates() const override;
|
||||
void SetCanSendUpdates(bool canSendUpdates) override;
|
||||
//! @}
|
||||
|
||||
@@ -307,7 +307,6 @@ namespace Multiplayer
|
||||
void MultiplayerSystemComponent::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
|
||||
{
|
||||
const AZ::TimeMs deltaTimeMs = aznumeric_cast<AZ::TimeMs>(static_cast<int32_t>(deltaTime * 1000.0f));
|
||||
const AZ::TimeMs hostTimeMs = AZ::GetElapsedTimeMs();
|
||||
const AZ::TimeMs serverRateMs = static_cast<AZ::TimeMs>(sv_serverSendRateMs);
|
||||
const float serverRateSeconds = static_cast<float>(serverRateMs) / 1000.0f;
|
||||
|
||||
@@ -344,12 +343,12 @@ namespace Multiplayer
|
||||
|
||||
// Send out the game state update to all connections
|
||||
{
|
||||
auto sendNetworkUpdates = [hostTimeMs, &stats](IConnection& connection)
|
||||
auto sendNetworkUpdates = [&stats](IConnection& connection)
|
||||
{
|
||||
if (connection.GetUserData() != nullptr)
|
||||
{
|
||||
IConnectionData* connectionData = reinterpret_cast<IConnectionData*>(connection.GetUserData());
|
||||
connectionData->Update(hostTimeMs);
|
||||
connectionData->Update();
|
||||
if (connectionData->GetConnectionDataType() == ConnectionDataType::ServerToClient)
|
||||
{
|
||||
stats.m_clientConnectionCount++;
|
||||
@@ -671,7 +670,7 @@ namespace Multiplayer
|
||||
else
|
||||
{
|
||||
connection->SetUserData(new ClientToServerConnectionData(connection, *this, providerTicket));
|
||||
AZStd::unique_ptr<IReplicationWindow> window = AZStd::make_unique<NullReplicationWindow>();
|
||||
AZStd::unique_ptr<IReplicationWindow> window = AZStd::make_unique<NullReplicationWindow>(connection);
|
||||
reinterpret_cast<ClientToServerConnectionData*>(connection->GetUserData())->GetReplicationManager().SetReplicationWindow(AZStd::move(window));
|
||||
}
|
||||
}
|
||||
|
||||
+82
-102
@@ -10,7 +10,6 @@
|
||||
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h>
|
||||
#include <Source/NetworkEntity/EntityReplication/PropertyPublisher.h>
|
||||
#include <Source/NetworkEntity/EntityReplication/PropertySubscriber.h>
|
||||
#include <Source/AutoGen/Multiplayer.AutoPackets.h>
|
||||
#include <Multiplayer/IMultiplayer.h>
|
||||
#include <Multiplayer/Components/NetBindComponent.h>
|
||||
#include <Multiplayer/EntityDomains/IEntityDomain.h>
|
||||
@@ -107,10 +106,34 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
|
||||
void EntityReplicationManager::SendUpdates(AZ::TimeMs hostTimeMs)
|
||||
void EntityReplicationManager::SendUpdates()
|
||||
{
|
||||
m_frameTimeMs = AZ::GetElapsedTimeMs();
|
||||
SendEntityUpdates(hostTimeMs);
|
||||
|
||||
{
|
||||
EntityReplicatorList toSendList = GenerateEntityUpdateList();
|
||||
|
||||
AZLOG
|
||||
(
|
||||
NET_ReplicationInfo,
|
||||
"Sending %zd updates from %s to %s",
|
||||
toSendList.size(),
|
||||
GetNetworkEntityManager()->GetHostId().GetString().c_str(),
|
||||
GetRemoteHostId().GetString().c_str()
|
||||
);
|
||||
|
||||
// Prep a replication record for send, at this point, everything needs to be sent
|
||||
for (EntityReplicator* replicator : toSendList)
|
||||
{
|
||||
replicator->GetPropertyPublisher()->PrepareSerialization();
|
||||
}
|
||||
|
||||
// While our to send list is not empty, build up another packet to send
|
||||
do
|
||||
{
|
||||
SendEntityUpdateMessages(toSendList);
|
||||
} while (!toSendList.empty());
|
||||
}
|
||||
|
||||
SendEntityRpcs(m_deferredRpcMessagesReliable, true);
|
||||
SendEntityRpcs(m_deferredRpcMessagesUnreliable, false);
|
||||
@@ -130,65 +153,6 @@ namespace Multiplayer
|
||||
);
|
||||
}
|
||||
|
||||
void EntityReplicationManager::SendEntityUpdatesPacketHelper
|
||||
(
|
||||
AZ::TimeMs hostTimeMs,
|
||||
EntityReplicatorList& toSendList,
|
||||
uint32_t maxPayloadSize,
|
||||
AzNetworking::IConnection& connection
|
||||
)
|
||||
{
|
||||
uint32_t pendingPacketSize = 0;
|
||||
EntityReplicatorList replicatorUpdatedList;
|
||||
MultiplayerPackets::EntityUpdates entityUpdatePacket;
|
||||
entityUpdatePacket.SetHostTimeMs(hostTimeMs);
|
||||
entityUpdatePacket.SetHostFrameId(GetNetworkTime()->GetHostFrameId());
|
||||
// Serialize everything
|
||||
while (!toSendList.empty())
|
||||
{
|
||||
EntityReplicator* replicator = toSendList.front();
|
||||
NetworkEntityUpdateMessage updateMessage(replicator->GenerateUpdatePacket());
|
||||
|
||||
const uint32_t nextMessageSize = updateMessage.GetEstimatedSerializeSize();
|
||||
|
||||
// Check if we are over our limits
|
||||
const bool payloadFull = (pendingPacketSize + nextMessageSize > maxPayloadSize);
|
||||
const bool capacityReached = (entityUpdatePacket.GetEntityMessages().size() >= entityUpdatePacket.GetEntityMessages().capacity());
|
||||
const bool largeEntityDetected = (payloadFull && replicatorUpdatedList.empty());
|
||||
if (capacityReached || (payloadFull && !largeEntityDetected))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pendingPacketSize += nextMessageSize;
|
||||
entityUpdatePacket.ModifyEntityMessages().push_back(updateMessage);
|
||||
replicatorUpdatedList.push_back(replicator);
|
||||
toSendList.pop_front();
|
||||
|
||||
if (largeEntityDetected)
|
||||
{
|
||||
AZLOG_WARN("\n\n*******************************");
|
||||
AZLOG_WARN
|
||||
(
|
||||
"Serializing extremely large entity (%u) - MaxPayload: %d NeededSize %d",
|
||||
aznumeric_cast<uint32_t>(replicator->GetEntityHandle().GetNetEntityId()),
|
||||
maxPayloadSize,
|
||||
nextMessageSize
|
||||
);
|
||||
AZLOG_WARN("*******************************");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const AzNetworking::PacketId sentId = connection.SendUnreliablePacket(entityUpdatePacket);
|
||||
|
||||
// Update the sent things with the packet id
|
||||
for (EntityReplicator* replicator : replicatorUpdatedList)
|
||||
{
|
||||
replicator->GetPropertyPublisher()->FinalizeSerialization(sentId);
|
||||
}
|
||||
}
|
||||
|
||||
EntityReplicationManager::EntityReplicatorList EntityReplicationManager::GenerateEntityUpdateList()
|
||||
{
|
||||
if (m_replicationWindow == nullptr)
|
||||
@@ -260,76 +224,92 @@ namespace Multiplayer
|
||||
return toSendList;
|
||||
}
|
||||
|
||||
void EntityReplicationManager::SendEntityUpdates(AZ::TimeMs hostTimeMs)
|
||||
void EntityReplicationManager::SendEntityUpdateMessages(EntityReplicatorList& replicatorList)
|
||||
{
|
||||
EntityReplicatorList toSendList = GenerateEntityUpdateList();
|
||||
|
||||
AZLOG
|
||||
(
|
||||
NET_ReplicationInfo,
|
||||
"Sending %zd updates from %s to %s",
|
||||
toSendList.size(),
|
||||
GetNetworkEntityManager()->GetHostId().GetString().c_str(),
|
||||
GetRemoteHostId().GetString().c_str()
|
||||
);
|
||||
|
||||
// prep a replication record for send, at this point, everything needs to be sent
|
||||
for (EntityReplicator* replicator : toSendList)
|
||||
uint32_t pendingPacketSize = 0;
|
||||
EntityReplicatorList replicatorUpdatedList;
|
||||
NetworkEntityUpdateVector entityUpdates;
|
||||
// Serialize everything
|
||||
while (!replicatorList.empty())
|
||||
{
|
||||
replicator->GetPropertyPublisher()->PrepareSerialization();
|
||||
EntityReplicator* replicator = replicatorList.front();
|
||||
NetworkEntityUpdateMessage updateMessage(replicator->GenerateUpdatePacket());
|
||||
|
||||
const uint32_t nextMessageSize = updateMessage.GetEstimatedSerializeSize();
|
||||
|
||||
// Check if we are over our limits
|
||||
const bool payloadFull = (pendingPacketSize + nextMessageSize > m_maxPayloadSize);
|
||||
const bool capacityReached = (entityUpdates.size() >= entityUpdates.capacity());
|
||||
const bool largeEntityDetected = (payloadFull && replicatorUpdatedList.empty());
|
||||
if (capacityReached || (payloadFull && !largeEntityDetected))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pendingPacketSize += nextMessageSize;
|
||||
entityUpdates.push_back(updateMessage);
|
||||
replicatorUpdatedList.push_back(replicator);
|
||||
replicatorList.pop_front();
|
||||
|
||||
if (largeEntityDetected)
|
||||
{
|
||||
AZLOG_WARN
|
||||
(
|
||||
"Serializing extremely large entity (%u) - MaxPayload: %d NeededSize %d",
|
||||
aznumeric_cast<uint32_t>(replicator->GetEntityHandle().GetNetEntityId()),
|
||||
m_maxPayloadSize,
|
||||
nextMessageSize
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// While our to send list is not empty, build up another packet to send
|
||||
do
|
||||
const AzNetworking::PacketId sentId = m_replicationWindow->SendEntityUpdateMessages(entityUpdates);
|
||||
|
||||
// Update the sent things with the packet id
|
||||
for (EntityReplicator* replicator : replicatorUpdatedList)
|
||||
{
|
||||
SendEntityUpdatesPacketHelper(hostTimeMs, toSendList, m_maxPayloadSize, m_connection);
|
||||
} while (!toSendList.empty());
|
||||
replicator->FinalizeSerialization(sentId);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityReplicationManager::SendEntityRpcs(RpcMessages& deferredRpcs, bool reliable)
|
||||
void EntityReplicationManager::SendEntityRpcs(RpcMessages& rpcMessages, bool reliable)
|
||||
{
|
||||
while (!deferredRpcs.empty())
|
||||
while (!rpcMessages.empty())
|
||||
{
|
||||
MultiplayerPackets::EntityRpcs entityRpcsPacket;
|
||||
NetworkEntityRpcVector entityRpcs;
|
||||
uint32_t pendingPacketSize = 0;
|
||||
|
||||
while (!deferredRpcs.empty())
|
||||
while (!rpcMessages.empty())
|
||||
{
|
||||
NetworkEntityRpcMessage& message = deferredRpcs.front();
|
||||
NetworkEntityRpcMessage& message = rpcMessages.front();
|
||||
|
||||
const uint32_t nextRpcSize = message.GetEstimatedSerializeSize();
|
||||
|
||||
if ((pendingPacketSize + nextRpcSize) > m_maxPayloadSize)
|
||||
{
|
||||
// We're over our limit, break and send an Rpc packet
|
||||
if (entityRpcsPacket.GetEntityRpcs().size() == 0)
|
||||
if (entityRpcs.size() == 0)
|
||||
{
|
||||
AZLOG(NET_Replicator, "Encountered an RPC that is above our MTU, message will be segmented (object size %u, max allowed size %u)", nextRpcSize, m_maxPayloadSize);
|
||||
entityRpcsPacket.ModifyEntityRpcs().push_back(message);
|
||||
deferredRpcs.pop_front();
|
||||
entityRpcs.push_back(message);
|
||||
rpcMessages.pop_front();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
pendingPacketSize += nextRpcSize;
|
||||
if (entityRpcsPacket.GetEntityRpcs().full())
|
||||
if (entityRpcs.full())
|
||||
{
|
||||
// Packet was full, send what we've accumulated so far
|
||||
AZLOG(NET_Replicator, "We've hit our RPC message limit (RPC count %u, packet size %u)", aznumeric_cast<uint32_t>(entityRpcsPacket.GetEntityRpcs().size()), pendingPacketSize);
|
||||
AZLOG(NET_Replicator, "We've hit our RPC message limit (RPC count %u, packet size %u)", aznumeric_cast<uint32_t>(entityRpcs.size()), pendingPacketSize);
|
||||
break;
|
||||
}
|
||||
entityRpcsPacket.ModifyEntityRpcs().push_back(message);
|
||||
deferredRpcs.pop_front();
|
||||
entityRpcs.push_back(message);
|
||||
rpcMessages.pop_front();
|
||||
}
|
||||
|
||||
if (reliable)
|
||||
{
|
||||
m_connection.SendReliablePacket(entityRpcsPacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_connection.SendUnreliablePacket(entityRpcsPacket);
|
||||
}
|
||||
m_replicationWindow->SendEntityRpcs(entityRpcs, reliable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +454,7 @@ namespace Multiplayer
|
||||
}
|
||||
|
||||
// @nt: TODO - delete once dropped RPC problem fixed
|
||||
void EntityReplicationManager::AddAutonomousEntityReplicatorCreatedHandle(AZ::Event<NetEntityId>::Handler& handler)
|
||||
void EntityReplicationManager::AddAutonomousEntityReplicatorCreatedHandler(AZ::Event<NetEntityId>::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_autonomousEntityReplicatorCreated);
|
||||
}
|
||||
|
||||
+3
-5
@@ -79,7 +79,7 @@ namespace Multiplayer
|
||||
|
||||
void AddDeferredRpcMessage(NetworkEntityRpcMessage& rpcMessage);
|
||||
|
||||
void AddAutonomousEntityReplicatorCreatedHandle(AZ::Event<NetEntityId>::Handler& handler);
|
||||
void AddAutonomousEntityReplicatorCreatedHandler(AZ::Event<NetEntityId>::Handler& handler);
|
||||
|
||||
bool HandleEntityMigration(AzNetworking::IConnection* invokingConnection, EntityMigrationMessage& message);
|
||||
bool HandleEntityDeleteMessage(EntityReplicator* entityReplicator, const AzNetworking::IPacketHeader& packetHeader, const NetworkEntityUpdateMessage& updateMessage);
|
||||
@@ -117,10 +117,8 @@ namespace Multiplayer
|
||||
using EntityReplicatorList = AZStd::deque<EntityReplicator*>;
|
||||
EntityReplicatorList GenerateEntityUpdateList();
|
||||
|
||||
void SendEntityUpdatesPacketHelper(AZ::TimeMs hostTimeMs, EntityReplicatorList& toSendList, uint32_t maxPayloadSize, AzNetworking::IConnection& connection);
|
||||
|
||||
void SendEntityUpdates(AZ::TimeMs hostTimeMs);
|
||||
void SendEntityRpcs(RpcMessages& deferredRpcs, bool reliable);
|
||||
void SendEntityUpdateMessages(EntityReplicatorList& replicatorList);
|
||||
void SendEntityRpcs(RpcMessages& rpcMessages, bool reliable);
|
||||
|
||||
void MigrateEntityInternal(NetEntityId entityId);
|
||||
void OnEntityExitDomain(const ConstNetworkEntityHandle& entityHandle);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityRpcMessage.h>
|
||||
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h>
|
||||
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h>
|
||||
#include <Source/AutoGen/Multiplayer.AutoPackets.h>
|
||||
#include <Source/NetworkEntity/NetworkEntityAuthorityTracker.h>
|
||||
#include <Source/NetworkEntity/NetworkEntityTracker.h>
|
||||
#include <Source/NetworkEntity/EntityReplication/PropertyPublisher.h>
|
||||
@@ -495,6 +494,11 @@ namespace Multiplayer
|
||||
return updateMessage;
|
||||
}
|
||||
|
||||
void EntityReplicator::FinalizeSerialization(AzNetworking::PacketId sentId)
|
||||
{
|
||||
m_propertyPublisher->FinalizeSerialization(sentId);
|
||||
}
|
||||
|
||||
void EntityReplicator::DeferRpcMessage(NetworkEntityRpcMessage& entityRpcMessage)
|
||||
{
|
||||
// Received rpc metrics, log rpc sent, number of bytes, and the componentId/rpcId for bandwidth metrics
|
||||
|
||||
@@ -336,7 +336,6 @@ namespace Multiplayer
|
||||
case PropertyPublisher::EntityReplicatorState::Deleting:
|
||||
{
|
||||
AZ_Assert(m_serializationPhase == PropertyPublisher::EntityReplicatorSerializationPhase::Prepared, "Unexpected serialization phase");
|
||||
|
||||
FinalizeDeleteEntityRecord(sentId);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -7,9 +7,16 @@
|
||||
*/
|
||||
|
||||
#include <Source/ReplicationWindows/NullReplicationWindow.h>
|
||||
#include <Source/AutoGen/Multiplayer.AutoPackets.h>
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
NullReplicationWindow::NullReplicationWindow(AzNetworking::IConnection* connection)
|
||||
: m_connection(connection)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
bool NullReplicationWindow::ReplicationSetUpdateReady()
|
||||
{
|
||||
return true;
|
||||
@@ -36,6 +43,29 @@ namespace Multiplayer
|
||||
;
|
||||
}
|
||||
|
||||
AzNetworking::PacketId NullReplicationWindow::SendEntityUpdateMessages(NetworkEntityUpdateVector& entityUpdateVector)
|
||||
{
|
||||
MultiplayerPackets::EntityUpdates entityUpdatePacket;
|
||||
entityUpdatePacket.SetHostTimeMs(GetNetworkTime()->GetHostTimeMs());
|
||||
entityUpdatePacket.SetHostFrameId(GetNetworkTime()->GetHostFrameId());
|
||||
entityUpdatePacket.SetEntityMessages(entityUpdateVector);
|
||||
return m_connection->SendUnreliablePacket(entityUpdatePacket);
|
||||
}
|
||||
|
||||
void NullReplicationWindow::SendEntityRpcs(NetworkEntityRpcVector& entityRpcVector, bool reliable)
|
||||
{
|
||||
MultiplayerPackets::EntityRpcs entityRpcsPacket;
|
||||
entityRpcsPacket.SetEntityRpcs(entityRpcVector);
|
||||
if (reliable)
|
||||
{
|
||||
m_connection->SendReliablePacket(entityRpcsPacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_connection->SendUnreliablePacket(entityRpcsPacket);
|
||||
}
|
||||
}
|
||||
|
||||
void NullReplicationWindow::DebugDraw() const
|
||||
{
|
||||
// Nothing to draw
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Multiplayer/ReplicationWindows/IReplicationWindow.h>
|
||||
#include <AzNetworking/ConnectionLayer/IConnection.h>
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
@@ -16,7 +17,7 @@ namespace Multiplayer
|
||||
: public IReplicationWindow
|
||||
{
|
||||
public:
|
||||
NullReplicationWindow() = default;
|
||||
NullReplicationWindow(AzNetworking::IConnection* connection);
|
||||
|
||||
//! IReplicationWindow interface
|
||||
//! @{
|
||||
@@ -25,10 +26,13 @@ namespace Multiplayer
|
||||
uint32_t GetMaxProxyEntityReplicatorSendCount() const override;
|
||||
bool IsInWindow(const ConstNetworkEntityHandle& entityPtr, NetEntityRole& outNetworkRole) const override;
|
||||
void UpdateWindow() override;
|
||||
AzNetworking::PacketId SendEntityUpdateMessages(NetworkEntityUpdateVector& entityUpdateVector) override;
|
||||
void SendEntityRpcs(NetworkEntityRpcVector& entityRpcVector, bool reliable) override;
|
||||
void DebugDraw() const override;
|
||||
//! @}
|
||||
|
||||
private:
|
||||
ReplicationSet m_emptySet;
|
||||
AzNetworking::IConnection* m_connection = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
+25
-1
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <Source/ReplicationWindows/ServerToClientReplicationWindow.h>
|
||||
#include <Source/AutoGen/Multiplayer.AutoPackets.h>
|
||||
#include <Multiplayer/Components/NetBindComponent.h>
|
||||
#include <AzFramework/Visibility/IVisibilitySystem.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
@@ -50,7 +51,7 @@ namespace Multiplayer
|
||||
return m_priority < rhs.m_priority;
|
||||
}
|
||||
|
||||
ServerToClientReplicationWindow::ServerToClientReplicationWindow(NetworkEntityHandle controlledEntity, const AzNetworking::IConnection* connection)
|
||||
ServerToClientReplicationWindow::ServerToClientReplicationWindow(NetworkEntityHandle controlledEntity, AzNetworking::IConnection* connection)
|
||||
: m_controlledEntity(controlledEntity)
|
||||
, m_entityActivatedEventHandler([this](AZ::Entity* entity) { OnEntityActivated(entity); })
|
||||
, m_entityDeactivatedEventHandler([this](AZ::Entity* entity) { OnEntityDeactivated(entity); })
|
||||
@@ -179,6 +180,29 @@ namespace Multiplayer
|
||||
//}
|
||||
}
|
||||
|
||||
AzNetworking::PacketId ServerToClientReplicationWindow::SendEntityUpdateMessages(NetworkEntityUpdateVector& entityUpdateVector)
|
||||
{
|
||||
MultiplayerPackets::EntityUpdates entityUpdatePacket;
|
||||
entityUpdatePacket.SetHostTimeMs(GetNetworkTime()->GetHostTimeMs());
|
||||
entityUpdatePacket.SetHostFrameId(GetNetworkTime()->GetHostFrameId());
|
||||
entityUpdatePacket.SetEntityMessages(entityUpdateVector);
|
||||
return m_connection->SendUnreliablePacket(entityUpdatePacket);
|
||||
}
|
||||
|
||||
void ServerToClientReplicationWindow::SendEntityRpcs(NetworkEntityRpcVector& entityRpcVector, bool reliable)
|
||||
{
|
||||
MultiplayerPackets::EntityRpcs entityRpcsPacket;
|
||||
entityRpcsPacket.SetEntityRpcs(entityRpcVector);
|
||||
if (reliable)
|
||||
{
|
||||
m_connection->SendReliablePacket(entityRpcsPacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_connection->SendUnreliablePacket(entityRpcsPacket);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerToClientReplicationWindow::DebugDraw() const
|
||||
{
|
||||
//static const float BoundaryStripeHeight = 1.0f;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Multiplayer
|
||||
// we sort lowest priority first, so that we can easily keep the biggest N priorities
|
||||
using ReplicationCandidateQueue = AZStd::priority_queue<PrioritizedReplicationCandidate>;
|
||||
|
||||
ServerToClientReplicationWindow(NetworkEntityHandle controlledEntity, const AzNetworking::IConnection* connection);
|
||||
ServerToClientReplicationWindow(NetworkEntityHandle controlledEntity, AzNetworking::IConnection* connection);
|
||||
|
||||
//! IReplicationWindow interface
|
||||
//! @{
|
||||
@@ -47,6 +47,8 @@ namespace Multiplayer
|
||||
uint32_t GetMaxProxyEntityReplicatorSendCount() const override;
|
||||
bool IsInWindow(const ConstNetworkEntityHandle& entityPtr, NetEntityRole& outNetworkRole) const override;
|
||||
void UpdateWindow() override;
|
||||
AzNetworking::PacketId SendEntityUpdateMessages(NetworkEntityUpdateVector& entityUpdateVector) override;
|
||||
void SendEntityRpcs(NetworkEntityRpcVector& entityRpcVector, bool reliable) override;
|
||||
void DebugDraw() const override;
|
||||
//! @}
|
||||
|
||||
@@ -75,7 +77,7 @@ namespace Multiplayer
|
||||
|
||||
//NetBindComponent* m_controlledNetBindComponent = nullptr;
|
||||
|
||||
const AzNetworking::IConnection* m_connection = nullptr;
|
||||
AzNetworking::IConnection* m_connection = nullptr;
|
||||
|
||||
// Cached values to detect a poor network connection
|
||||
uint32_t m_lastCheckedSentPackets = 0;
|
||||
|
||||
@@ -33,6 +33,9 @@ set(FILES
|
||||
Include/Multiplayer/MultiplayerConstants.h
|
||||
Include/Multiplayer/MultiplayerStats.h
|
||||
Include/Multiplayer/MultiplayerTypes.h
|
||||
Include/Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h
|
||||
Include/Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h
|
||||
Include/Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.inl
|
||||
Include/Multiplayer/NetworkEntity/EntityReplication/ReplicationRecord.h
|
||||
Include/Multiplayer/NetworkEntity/IFilterEntityManager.h
|
||||
Include/Multiplayer/NetworkEntity/INetworkEntityManager.h
|
||||
|
||||
Reference in New Issue
Block a user