Fixes and cleanup for recent correction changes

Signed-off-by: kberg-amzn <karlberg@amazon.com>
monroegm-disable-blank-issue-2
kberg-amzn 4 years ago
parent d0394ec3fc
commit f85e8124a9

@ -10,19 +10,6 @@
namespace AzNetworking
{
StringifySerializer::StringifySerializer(char delimeter, bool outputFieldNames, const AZStd::string& seperator)
: m_delimeter(delimeter)
, m_outputFieldNames(outputFieldNames)
, m_separator(seperator)
{
;
}
const AZStd::string& StringifySerializer::GetString() const
{
return m_string;
}
const StringifySerializer::ValueMap& StringifySerializer::GetValueMap() const
{
return m_valueMap;
@ -138,21 +125,8 @@ namespace AzNetworking
bool StringifySerializer::ProcessData(const char* name, const T& value)
{
const AZStd::string keyString = m_prefix + name;
if (!m_string.empty())
{
// Only add delimeters after we have processed at least one element
m_string += m_delimeter;
}
if (m_outputFieldNames)
{
m_string += keyString;
}
AZ::CVarFixedString valueString = AZ::ConsoleTypeHelpers::ValueToString(value);
m_valueMap[keyString] = valueString.c_str();
return true;
}
}

@ -22,10 +22,7 @@ namespace AzNetworking
using ValueMap = AZStd::map<AZStd::string, AZStd::string>;
StringifySerializer(char delimeter = ' ', bool outputFieldNames = true, const AZStd::string& seperator = "=");
//! After serializing objects, get the serialized values as a single string.
const AZStd::string& GetString() const;
StringifySerializer() = default;
//! After serializing objects, get the serialized values as a map of key/value pairs.
const ValueMap& GetValueMap() const;
@ -60,15 +57,8 @@ namespace AzNetworking
template <typename T>
bool ProcessData(const char* name, const T& value);
private:
char m_delimeter;
bool m_outputFieldNames = true;
ValueMap m_valueMap;
AZStd::string m_string;
AZStd::string m_prefix;
AZStd::string m_separator;
AZStd::deque<AZStd::size_t> m_prefixSizeStack;
};
}

@ -14,8 +14,6 @@
namespace Multiplayer
{
using CorrectionEvent = AZ::Event<>;
class LocalPredictionPlayerInputComponent
: public LocalPredictionPlayerInputComponentBase
{
@ -65,8 +63,6 @@ namespace Multiplayer
ClientInputId GetLastInputId() const;
HostFrameId GetInputFrameId(const NetworkInput& input) const;
void CorrectionEventAddHandle(CorrectionEvent::Handler& handler);
private:
void OnMigrateStart(ClientInputId migratedInputId);
@ -86,7 +82,6 @@ namespace Multiplayer
AZ::ScheduledEvent m_autonomousUpdateEvent; // Drives autonomous input collection
AZ::ScheduledEvent m_updateBankedTimeEvent; // Drives authority bank time updates
CorrectionEvent m_correctionEvent;
EntityMigrationStartEvent::Handler m_migrateStartHandler;
EntityMigrationEndEvent::Handler m_migrateEndHandler;

@ -36,6 +36,7 @@ namespace Multiplayer
using EntityMigrationEndEvent = AZ::Event<>;
using EntityServerMigrationEvent = AZ::Event<const ConstNetworkEntityHandle&, HostId, AzNetworking::ConnectionId>;
using EntityPreRenderEvent = AZ::Event<float, float>;
using EntityCorrectionEvent = AZ::Event<>;
//! @class NetBindComponent
//! @brief Component that provides net-binding to a networked entity.
@ -118,6 +119,7 @@ namespace Multiplayer
void NotifyMigrationEnd();
void NotifyServerMigration(HostId hostId, AzNetworking::ConnectionId connectionId);
void NotifyPreRender(float deltaTime, float blendFactor);
void NotifyCorrection();
void AddEntityStopEventHandler(EntityStopEvent::Handler& eventHandler);
void AddEntityDirtiedEventHandler(EntityDirtiedEvent::Handler& eventHandler);
@ -126,6 +128,7 @@ namespace Multiplayer
void AddEntityMigrationEndEventHandler(EntityMigrationEndEvent::Handler& eventHandler);
void AddEntityServerMigrationEventHandler(EntityServerMigrationEvent::Handler& eventHandler);
void AddEntityPreRenderEventHandler(EntityPreRenderEvent::Handler& eventHandler);
void AddEntityCorrectionEventHandler(EntityCorrectionEvent::Handler& handler);
bool SerializeEntityCorrection(AzNetworking::ISerializer& serializer);
@ -175,6 +178,7 @@ namespace Multiplayer
EntityMigrationEndEvent m_entityMigrationEndEvent;
EntityServerMigrationEvent m_entityServerMigrationEvent;
EntityPreRenderEvent m_entityPreRenderEvent;
EntityCorrectionEvent m_entityCorrectionEvent;
AZ::Event<> m_onRemove;
RpcSendEvent::Handler m_handleLocalServerRpcMessageEventHandle;
AZ::Event<>::Handler m_handleMarkedDirty;

@ -30,6 +30,7 @@ namespace Multiplayer
private:
void OnPreRender(float deltaTime, float blendFactor);
void OnCorrection();
void OnRotationChangedEvent(const AZ::Quaternion& rotation);
void OnTranslationChangedEvent(const AZ::Vector3& translation);
@ -47,6 +48,7 @@ namespace Multiplayer
AZ::Event<uint8_t>::Handler m_resetCountEventHandler;
EntityPreRenderEvent::Handler m_entityPreRenderEventHandler;
EntityCorrectionEvent::Handler m_entityCorrectionEventHandler;
Multiplayer::HostFrameId m_targetHostFrameId = HostFrameId(0);
};

@ -32,21 +32,6 @@ namespace Multiplayer
AZ_CVAR(AZ::TimeMs, sv_MinCorrectionTimeMs, AZ::TimeMs{ 100 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Minimum time to wait between sending out corrections in order to avoid flooding corrections on high-latency connections");
AZ_CVAR(AZ::TimeMs, sv_InputUpdateTimeMs, AZ::TimeMs{ 5 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Minimum time between component updates");
// Debug helper functions
AZStd::string GetInputString(NetworkInput& input)
{
AzNetworking::StringifySerializer serializer(',', false);
input.Serialize(serializer);
return serializer.GetString();
}
AZStd::string GetCorrectionDataString(NetBindComponent* netBindComponent)
{
AzNetworking::StringifySerializer serializer(',', false);
netBindComponent->SerializeEntityCorrection(serializer);
return serializer.GetString();
}
void PrintCorrectionDifferences(const AzNetworking::StringifySerializer& client, const AzNetworking::StringifySerializer& server)
{
const auto& clientMap = client.GetValueMap();
@ -289,14 +274,7 @@ namespace Multiplayer
ScopedAlterTime scopedTime(input.GetHostFrameId(), input.GetHostTimeMs(), input.GetHostBlendFactor(), invokingConnection->GetConnectionId());
GetNetBindComponent()->ProcessInput(input, clientInputRateSec);
AZLOG
(
NET_Prediction,
"Migrated InputId=%d - i=[%s] o=[%s]",
aznumeric_cast<int32_t>(input.GetClientInputId()),
GetInputString(input).c_str(),
GetCorrectionDataString(GetNetBindComponent()).c_str()
);
AZLOG(NET_Prediction, "Migrated InputId=%d", aznumeric_cast<int32_t>(input.GetClientInputId()));
// Don't bother checking for corrections here, the next regular input will trigger any corrections if necessary
// Also don't bother with any cheat detection here, because the input array is limited in size and at most and can only be sent once
@ -329,7 +307,7 @@ namespace Multiplayer
// Apply the correction
AzNetworking::TrackChangedSerializer<AzNetworking::NetworkOutputSerializer> serializer(correction.GetBuffer(), correction.GetSize());
GetNetBindComponent()->SerializeEntityCorrection(serializer);
m_correctionEvent.Signal();
GetNetBindComponent()->NotifyCorrection();
#ifndef AZ_RELEASE_BUILD
if (cl_EnableDesyncDebugging)
@ -350,14 +328,6 @@ namespace Multiplayer
}
#endif
AZLOG
(
NET_Prediction,
"Corrected InputId=%d - o=[%s]",
aznumeric_cast<int32_t>(m_lastCorrectionInputId),
GetCorrectionDataString(GetNetBindComponent()).c_str()
);
const uint32_t inputHistorySize = m_inputHistory.Size();
const uint32_t historicalDelta = aznumeric_cast<uint32_t>(m_clientInputId - inputId); // Do not replay the move we just corrected, that was already processed by the server
@ -372,14 +342,7 @@ namespace Multiplayer
ScopedAlterTime scopedTime(input.GetHostFrameId(), input.GetHostTimeMs(), input.GetHostBlendFactor(), invokingConnection->GetConnectionId());
GetNetBindComponent()->ReprocessInput(input, clientInputRateSec);
AZLOG
(
NET_Prediction,
"Replayed InputId=%d - i=[%s] o=[%s]",
aznumeric_cast<int32_t>(input.GetClientInputId()),
GetInputString(input).c_str(),
GetCorrectionDataString(GetNetBindComponent()).c_str()
);
AZLOG(NET_Prediction, "Replayed InputId=%d", aznumeric_cast<int32_t>(input.GetClientInputId()));
}
}
@ -402,11 +365,6 @@ namespace Multiplayer
return (input.GetHostFrameId() == InvalidHostFrameId) ? m_serverMigrateFrameId : input.GetHostFrameId();
}
void LocalPredictionPlayerInputComponentController::CorrectionEventAddHandle(CorrectionEvent::Handler& handler)
{
handler.Connect(m_correctionEvent);
}
void LocalPredictionPlayerInputComponentController::OnMigrateStart(ClientInputId migratedInputId)
{
m_lastMigratedInputId = migratedInputId;
@ -480,14 +438,7 @@ namespace Multiplayer
// Process the input for this frame
GetNetBindComponent()->ProcessInput(input, inputRate);
AZLOG
(
NET_Prediction,
"Processed InutId=%d - i=[%s] o=[%s]",
aznumeric_cast<int32_t>(m_clientInputId),
GetInputString(input).c_str(),
GetCorrectionDataString(GetNetBindComponent()).c_str()
);
AZLOG(NET_Prediction, "Processed InputId=%d", aznumeric_cast<int32_t>(m_clientInputId));
// Generate a hash based on the current client predicted states
AzNetworking::HashSerializer hashSerializer;
@ -553,14 +504,7 @@ namespace Multiplayer
GetNetBindComponent()->ProcessInput(input, inputRate);
}
AZLOG
(
NET_Prediction,
"Forced InputId=%d - i=[%s] o=[%s]",
aznumeric_cast<int32_t>(input.GetClientInputId()),
GetInputString(input).c_str(),
GetCorrectionDataString(GetNetBindComponent()).c_str()
);
AZLOG(NET_Prediction, "Forced InputId=%d", aznumeric_cast<int32_t>(input.GetClientInputId()));
}
// Decay our bank time window, in case the remote endpoint has suffered a more persistent shift in latency, this should cause the client to eventually recover

@ -408,6 +408,11 @@ namespace Multiplayer
m_entityPreRenderEvent.Signal(deltaTime, blendFactor);
}
void NetBindComponent::NotifyCorrection()
{
m_entityCorrectionEvent.Signal();
}
void NetBindComponent::AddEntityStopEventHandler(EntityStopEvent::Handler& eventHandler)
{
eventHandler.Connect(m_entityStopEvent);
@ -443,6 +448,11 @@ namespace Multiplayer
eventHandler.Connect(m_entityPreRenderEvent);
}
void NetBindComponent::AddEntityCorrectionEventHandler(EntityCorrectionEvent::Handler& eventHandler)
{
eventHandler.Connect(m_entityCorrectionEvent);
}
bool NetBindComponent::SerializeEntityCorrection(AzNetworking::ISerializer& serializer)
{
m_predictableRecord.ResetConsumedBits();

@ -31,6 +31,7 @@ namespace Multiplayer
, m_scaleEventHandler([this](float scale) { OnScaleChangedEvent(scale); })
, m_resetCountEventHandler([this](const uint8_t&) { OnResetCountChangedEvent(); })
, m_entityPreRenderEventHandler([this](float deltaTime, float blendFactor) { OnPreRender(deltaTime, blendFactor); })
, m_entityCorrectionEventHandler([this]() { OnCorrection(); })
{
;
}
@ -47,6 +48,7 @@ namespace Multiplayer
ScaleAddEvent(m_scaleEventHandler);
ResetCountAddEvent(m_resetCountEventHandler);
GetNetBindComponent()->AddEntityPreRenderEventHandler(m_entityPreRenderEventHandler);
GetNetBindComponent()->AddEntityCorrectionEventHandler(m_entityCorrectionEventHandler);
// When coming into relevance, reset all blending factors so we don't interpolate to our start position
OnResetCountChangedEvent();
@ -119,6 +121,18 @@ namespace Multiplayer
}
}
void NetworkTransformComponent::OnCorrection()
{
// Snap to latest
OnResetCountChangedEvent();
// Hard set the entities transform
if (!GetTransformComponent()->GetWorldTM().IsClose(m_targetTransform))
{
GetTransformComponent()->SetWorldTM(m_targetTransform);
}
}
NetworkTransformComponentController::NetworkTransformComponentController(NetworkTransformComponent& parent)
: NetworkTransformComponentControllerBase(parent)

Loading…
Cancel
Save