Started on UE4 server, semi working handshake

This commit is contained in:
AeonLucid
2022-01-09 06:29:02 +01:00
parent e9091d7ac3
commit ed0f771df6
34 changed files with 2931 additions and 9 deletions
+265
View File
@@ -0,0 +1,265 @@
using System.Net;
using Prospect.Unreal.Serialization;
using Serilog;
namespace Prospect.Unreal.Net;
public record FIncomingPacketRef(FBitReader Packet, IPEndPoint Address, FInPacketTraits Traits);
public record ProcessedPacket(byte[] Data, int CountBits, bool Error = false);
public class PacketHandler
{
private static readonly ILogger Logger = Log.ForContext<PacketHandler>();
private readonly List<HandlerComponent> _handlerComponents;
private bool _bConnectionlessHandler;
private bool _bRawSend;
private HandlerState _state;
private ReliabilityHandlerComponent? _reliabilityComponent;
private FBitWriter _outgoingPacket;
private FBitReader _incomingPacket;
public PacketHandler()
{
_bConnectionlessHandler = false;
_state = HandlerState.Uninitialized;
_handlerComponents = new List<HandlerComponent>();
_reliabilityComponent = null;
_outgoingPacket = new FBitWriter(0);
_incomingPacket = new FBitReader(Array.Empty<byte>());
Mode = HandlerMode.Server;
}
public HandlerMode Mode { get; }
public void Tick(float deltaTime)
{
foreach (var component in _handlerComponents)
{
component.Tick(deltaTime);
}
}
public void Initialize(bool bConnectionlessOnly)
{
_bConnectionlessHandler = bConnectionlessOnly;
if (!_bConnectionlessHandler)
{
throw new NotImplementedException();
}
// TODO: FEncryptionComponent.
// TODO: ReliabilityHandlerComponent.
}
public void InitializeComponents()
{
if (_state == HandlerState.Uninitialized)
{
if (_handlerComponents.Count > 0)
{
SetState(HandlerState.InitializingComponents);
}
else
{
HandlerInitialized();
}
}
foreach (var component in _handlerComponents)
{
if (component.IsValid() && !component.IsInitialized())
{
component.Initialize();
}
}
}
public bool IncomingConnectionless(FReceivedPacketView packetView)
{
packetView.Traits.ConnectionlessPacket = true;
return Incoming_Internal(packetView);
}
public ProcessedPacket OutgoingConnectionless(IPEndPoint address, byte[] packet, int countBits, FOutPacketTraits traits)
{
return Outgoing_Internal(packet, countBits, traits, true, address);
}
public HandlerComponent AddHandler<T>() where T : HandlerComponent
{
var result = (HandlerComponent) Activator.CreateInstance(typeof(T), this)!;
_handlerComponents.Add(result);
return result;
}
private bool Incoming_Internal(FReceivedPacketView packetView)
{
var returnVal = true;
var dataView = packetView.DataView;
var countBits = dataView.NumBits();
if (_handlerComponents.Count > 0)
{
var data = dataView.GetData();
var lastByte = data[dataView.NumBytes() - 1];
if (lastByte != 0)
{
countBits--;
while ((lastByte & 0x80) == 0)
{
lastByte *= 2;
countBits--;
}
}
else
{
returnVal = false;
}
}
if (returnVal)
{
var processPacketReader = new FBitReader(dataView.GetData(), countBits);
var packetRef = new FIncomingPacketRef(processPacketReader, packetView.Address, packetView.Traits);
if (_state == HandlerState.Uninitialized)
{
UpdateInitialState();
}
foreach (var component in _handlerComponents)
{
if (processPacketReader.GetPosBits() != 0 && !component.CanReadUnaligned())
{
RealignPacket(processPacketReader);
}
if (packetView.Traits.ConnectionlessPacket)
{
component.IncomingConnectionless(packetRef);
}
else
{
component.Incoming(processPacketReader);
}
}
if (!processPacketReader.IsError())
{
ReplaceIncomingPacket(processPacketReader);
packetView.DataView = new FPacketDataView(_incomingPacket.GetBuffer(), _incomingPacket.GetBitsLeft());
}
else
{
returnVal = false;
}
}
return returnVal;
}
private ProcessedPacket Outgoing_Internal(byte[] packet, int countBits, FOutPacketTraits traits, bool bConnectionLess, IPEndPoint address)
{
if (!_bRawSend)
{
throw new NotImplementedException();
}
else
{
return new ProcessedPacket(packet, countBits);
}
}
private void SetState(HandlerState state)
{
if (state == _state)
{
Logger.Fatal("Set PacketHandler state to the state it is currently in ({State})", state);
}
else
{
_state = state;
}
}
private void UpdateInitialState()
{
if (_state == HandlerState.Uninitialized)
{
if (_handlerComponents.Count > 0)
{
InitializeComponents();
}
else
{
HandlerInitialized();
}
}
}
private void HandlerInitialized()
{
if (_reliabilityComponent != null)
{
throw new NotImplementedException();
}
SetState(HandlerState.Initialized);
}
private void ReplaceIncomingPacket(FBitReader replacementPacket)
{
if (replacementPacket.GetPosBits() == 0 || replacementPacket.GetBitsLeft() == 0)
{
_incomingPacket = replacementPacket;
}
else
{
var tempPacketData = new byte[replacementPacket.GetBytesLeft()];
var newPacketSizeBits = replacementPacket.GetBitsLeft();
replacementPacket.SerializeBits(tempPacketData, newPacketSizeBits);
_incomingPacket = new FBitReader(tempPacketData, newPacketSizeBits);
}
}
private void RealignPacket(FBitReader packet)
{
Logger.Warning("Realigning packet, which is untested");
if (packet.GetPosBits() != 0)
{
var bitsLeft = packet.GetBitsLeft();
if (bitsLeft > 0)
{
var tempPacketData = new byte[packet.GetBytesLeft()];
packet.SerializeBits(tempPacketData, bitsLeft);
packet.SetData(tempPacketData, bitsLeft);
}
}
}
public void SetRawSend(bool enabled)
{
_bRawSend = enabled;
}
public bool GetRawSend()
{
return _bRawSend;
}
}