Ported the local prediction player controller component

This commit is contained in:
karlberg
2021-05-05 20:07:16 -07:00
parent bbe3fcfdd9
commit a1fe8fe419
55 changed files with 1164 additions and 275 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/IEntityDomain.h>
#include <Include/IMultiplayer.h>
#include <Include/INetworkEntityManager.h>
#include <Include/IReplicationWindow.h>
#include <AzNetworking/ConnectionLayer/IConnection.h>
#include <AzNetworking/ConnectionLayer/IConnectionListener.h>
#include <AzNetworking/PacketLayer/IPacketHeader.h>
@@ -93,10 +93,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 +118,7 @@ namespace Multiplayer
void EntityReplicationManager::SendEntityUpdatesPacketHelper
(
AZ::TimeMs serverGameTimeMs,
AZ::TimeMs hostTimeMs,
EntityReplicatorList& toSendList,
uint32_t maxPayloadSize,
AzNetworking::IConnection& connection
@@ -127,7 +127,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 +250,7 @@ namespace Multiplayer
return toSendList;
}
void EntityReplicationManager::SendEntityUpdates(AZ::TimeMs serverGameTimeMs)
void EntityReplicationManager::SendEntityUpdates(AZ::TimeMs hostTimeMs)
{
EntityReplicatorList toSendList = GenerateEntityUpdateList();
@@ -264,7 +265,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 +748,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 +804,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 +816,7 @@ namespace Multiplayer
}
else
{
return entityReplicator->HandleRpcMessage(message);
return entityReplicator->HandleRpcMessage(invokingConnection, message);
}
}
@@ -833,8 +834,7 @@ namespace Multiplayer
);
return false;
}
return entityReplicator->HandleRpcMessage(message);
return entityReplicator->HandleRpcMessage(nullptr, message);
}
AZ::TimeMs EntityReplicationManager::GetResendTimeoutTimeMs() const
@@ -877,7 +877,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 +886,6 @@ namespace Multiplayer
}
m_entityRpcMap.erase(entityRpcsIter);
}
return AzNetworking::TimeoutResult::Delete;
}
@@ -1089,7 +1087,7 @@ namespace Multiplayer
if (m_updateMode == EntityReplicationManager::Mode::LocalServerToRemoteServer)
{
netBindComponent->NotifyMigration(GetRemoteHostId(), GetConnection().GetConnectionId());
netBindComponent->NotifyServerMigration(GetRemoteHostId(), GetConnection().GetConnectionId());
}
bool didSucceed = true;
@@ -1127,7 +1125,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 <Include/INetworkEntityManager.h>
#include <Include/IReplicationWindow.h>
#include <Include/IEntityDomain.h>
#include <Include/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;
@@ -628,7 +628,7 @@ 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();
@@ -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;
}
}
@@ -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
//! @{