2019-12-26 14:45:42 -05:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
2016-01-07 04:39:47 -05:00
|
|
|
|
2015-07-08 23:03:46 -04:00
|
|
|
#include "ReliabilityHandlerComponent.h"
|
2016-11-23 15:48:37 -05:00
|
|
|
#include "Modules/ModuleManager.h"
|
2019-10-10 20:04:46 -04:00
|
|
|
#include "Net/Core/Misc/PacketAudit.h"
|
2018-09-25 10:11:35 -04:00
|
|
|
#include "HAL/PlatformTime.h"
|
2015-07-08 23:03:46 -04:00
|
|
|
|
|
|
|
|
IMPLEMENT_MODULE(FReliabilityHandlerComponentModuleInterface, ReliabilityHandlerComponent);
|
|
|
|
|
|
|
|
|
|
// RELIABILITY
|
|
|
|
|
ReliabilityHandlerComponent::ReliabilityHandlerComponent()
|
2017-12-05 21:57:41 -05:00
|
|
|
: HandlerComponent(FName(TEXT("ReliabilityHandlerComponent")))
|
|
|
|
|
, LocalPacketID(1)
|
2015-07-09 03:42:46 -04:00
|
|
|
, LocalPacketIDACKED(0)
|
2015-07-08 23:03:46 -04:00
|
|
|
, RemotePacketID(0)
|
|
|
|
|
, RemotePacketIDACKED(0)
|
2018-09-25 10:11:35 -04:00
|
|
|
, ResendResolutionTime(0.1)
|
|
|
|
|
, LastResendTime(0.0)
|
2015-07-08 23:03:46 -04:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-30 23:19:16 -05:00
|
|
|
void ReliabilityHandlerComponent::CountBytes(FArchive& Ar) const
|
|
|
|
|
{
|
|
|
|
|
HandlerComponent::CountBytes(Ar);
|
|
|
|
|
|
|
|
|
|
const SIZE_T SizeOfThis = sizeof(*this) - sizeof(HandlerComponent);
|
|
|
|
|
Ar.CountBytes(SizeOfThis, SizeOfThis);
|
|
|
|
|
|
|
|
|
|
BufferedPackets.CountBytes(Ar);
|
|
|
|
|
for (BufferedPacket const * const LocalPacket : BufferedPackets)
|
|
|
|
|
{
|
|
|
|
|
if (LocalPacket)
|
|
|
|
|
{
|
|
|
|
|
LocalPacket->CountBytes(Ar);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-08 23:03:46 -04:00
|
|
|
void ReliabilityHandlerComponent::Initialize()
|
|
|
|
|
{
|
|
|
|
|
SetActive(true);
|
|
|
|
|
Initialized();
|
|
|
|
|
State = Handler::Component::State::Initialized;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ReliabilityHandlerComponent::IsValid() const
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-25 10:11:35 -04:00
|
|
|
void ReliabilityHandlerComponent::Outgoing(FBitWriter& Packet, FOutPacketTraits& Traits)
|
2015-07-08 23:03:46 -04:00
|
|
|
{
|
|
|
|
|
switch (State)
|
|
|
|
|
{
|
|
|
|
|
case Handler::Component::State::Initialized:
|
|
|
|
|
{
|
2017-06-16 14:10:35 -04:00
|
|
|
check(IsActive() && IsValid());
|
|
|
|
|
|
2015-07-08 23:03:46 -04:00
|
|
|
FBitWriter Local;
|
|
|
|
|
Local.AllowAppend(true);
|
|
|
|
|
Local.SetAllowResize(true);
|
|
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
check(Packet.GetNumBytes() > 0);
|
2015-07-08 23:03:46 -04:00
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
Local.SerializeIntPacked(RemotePacketID);
|
|
|
|
|
Local.SerializeIntPacked(LocalPacketID);
|
|
|
|
|
Local.SerializeBits(Packet.GetData(), Packet.GetNumBits());
|
2015-07-08 23:03:46 -04:00
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
Packet = Local;
|
2015-07-08 23:03:46 -04:00
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
FPacketAudit::AddStage(TEXT("PostReliability"), Packet);
|
2015-07-08 23:03:46 -04:00
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
break;
|
2015-07-08 23:03:46 -04:00
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ReliabilityHandlerComponent::Incoming(FBitReader& Packet)
|
|
|
|
|
{
|
|
|
|
|
switch (State)
|
|
|
|
|
{
|
|
|
|
|
case Handler::Component::State::Initialized:
|
|
|
|
|
{
|
|
|
|
|
if (IsActive() && IsValid())
|
|
|
|
|
{
|
2017-06-16 14:10:35 -04:00
|
|
|
FPacketAudit::CheckStage(TEXT("PostReliability"), Packet);
|
2015-07-08 23:03:46 -04:00
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
// Read ACK
|
2015-07-08 23:03:46 -04:00
|
|
|
uint32 IncomingLocalPacketIDACK;
|
|
|
|
|
Packet.SerializeIntPacked(IncomingLocalPacketIDACK);
|
|
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
// Read Remote ID
|
|
|
|
|
uint32 IncomingRemotePacketID;
|
|
|
|
|
Packet.SerializeIntPacked(IncomingRemotePacketID);
|
|
|
|
|
|
|
|
|
|
// Out of sequence or duplicate packet, ignore
|
|
|
|
|
if (RemotePacketID + 1 != IncomingRemotePacketID)
|
2015-07-08 23:03:46 -04:00
|
|
|
{
|
2018-09-25 10:11:35 -04:00
|
|
|
Packet.SetData(nullptr, 0);
|
2017-06-16 14:10:35 -04:00
|
|
|
return;
|
2015-07-08 23:03:46 -04:00
|
|
|
}
|
|
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
// Set latest ID
|
|
|
|
|
RemotePacketID = IncomingRemotePacketID;
|
|
|
|
|
|
|
|
|
|
check(IncomingLocalPacketIDACK >= LocalPacketIDACKED);
|
|
|
|
|
|
|
|
|
|
// We don't record the latest ACK unless this packet is in-order, since we can't trust the ACK without further modifications
|
2015-07-08 23:03:46 -04:00
|
|
|
LocalPacketIDACKED = IncomingLocalPacketIDACK;
|
|
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
// Do not realign the remaining packet here, let the PacketHandler do that.
|
|
|
|
|
// Previous code from here, had a bug that added an extra byte in some circumstances.
|
2015-07-08 23:03:46 -04:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ReliabilityHandlerComponent::Tick(float DeltaTime)
|
|
|
|
|
{
|
2018-09-25 10:11:35 -04:00
|
|
|
const double CurrentTime = FPlatformTime::Seconds();
|
2015-07-08 23:03:46 -04:00
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
if (CurrentTime - LastResendTime < ResendResolutionTime)
|
2015-07-08 23:03:46 -04:00
|
|
|
{
|
2017-06-16 14:10:35 -04:00
|
|
|
return;
|
2015-07-08 23:03:46 -04:00
|
|
|
}
|
|
|
|
|
|
2017-06-16 14:10:35 -04:00
|
|
|
LastResendTime = CurrentTime;
|
|
|
|
|
|
|
|
|
|
// Resend UNACKED packets
|
|
|
|
|
// We resend all packets just to make sure
|
|
|
|
|
// This is very inefficient and wastes bandwidth, we will want to implement NAK version at some point
|
|
|
|
|
for (int i = 0; i < BufferedPackets.Num(); i++)
|
2015-07-08 23:03:46 -04:00
|
|
|
{
|
2017-06-16 14:10:35 -04:00
|
|
|
BufferedPacket* Packet = BufferedPackets[i];
|
|
|
|
|
|
|
|
|
|
check(Packet->Id >= 1);
|
|
|
|
|
|
|
|
|
|
if (LocalPacketIDACKED < Packet->Id)
|
|
|
|
|
{
|
|
|
|
|
// Send this as a raw packet, since it's already been processed
|
|
|
|
|
Handler->QueuePacketForRawSending(Packet);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// This packet was ACK'd, we can remove
|
|
|
|
|
check(i == 0);
|
|
|
|
|
BufferedPackets.RemoveAt(i);
|
|
|
|
|
i--;
|
|
|
|
|
delete Packet;
|
|
|
|
|
}
|
2015-07-08 23:03:46 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-25 10:11:35 -04:00
|
|
|
void ReliabilityHandlerComponent::QueuePacketForResending(uint8* Packet, int32 CountBits, FOutPacketTraits& Traits)
|
2015-07-08 23:03:46 -04:00
|
|
|
{
|
2018-09-25 10:11:35 -04:00
|
|
|
BufferedPackets.Add(new BufferedPacket(Packet, CountBits, Traits, FPlatformTime::Seconds() + ResendResolutionTime, LocalPacketID++));
|
2017-06-16 14:10:35 -04:00
|
|
|
}
|
|
|
|
|
|
2018-09-25 10:11:35 -04:00
|
|
|
int32 ReliabilityHandlerComponent::GetReservedPacketBits() const
|
2017-06-16 14:10:35 -04:00
|
|
|
{
|
|
|
|
|
return 64;
|
2015-07-08 23:03:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MODULE INTERFACE
|
2015-09-30 16:14:25 -04:00
|
|
|
TSharedPtr<HandlerComponent> FReliabilityHandlerComponentModuleInterface::CreateComponentInstance(FString& Options)
|
2015-07-08 23:03:46 -04:00
|
|
|
{
|
2015-09-30 16:14:25 -04:00
|
|
|
return MakeShareable(new ReliabilityHandlerComponent);
|
2016-11-23 15:48:37 -05:00
|
|
|
}
|