132 lines
4.4 KiB
C#
132 lines
4.4 KiB
C#
using System.Net;
|
|
using System.Net.Sockets;
|
|
using Prospect.Unreal.Core;
|
|
using Prospect.Unreal.Exceptions;
|
|
using Prospect.Unreal.Net.Packets.Control;
|
|
|
|
namespace Prospect.Unreal.Net;
|
|
|
|
public class UIpConnection : UNetConnection
|
|
{
|
|
public const int IpHeaderSize = 20;
|
|
public const int UdpHeaderSize = IpHeaderSize + 8;
|
|
|
|
/// <summary>
|
|
/// Cached time of the first send socket error that will be used to compute disconnect delay.
|
|
/// </summary>
|
|
private double _socketErrorSendDelayStartTime;
|
|
|
|
/// <summary>
|
|
/// Cached time of the first recv socket error that will be used to compute disconnect delay.
|
|
/// </summary>
|
|
private double _socketErrorRecvDelayStartTime;
|
|
|
|
public UdpClient? Socket { get; private set; }
|
|
|
|
public override void InitBase(UNetDriver inDriver, UdpClient inSocket, FUrl inURL, EConnectionState inState, int inMaxPacket = 0, int inPacketOverhead = 0)
|
|
{
|
|
base.InitBase(inDriver, inSocket, inURL, inState,
|
|
(inMaxPacket == 0 || inMaxPacket > MaxPacketSize) ? MaxPacketSize : inMaxPacket,
|
|
inPacketOverhead == 0 ? UdpHeaderSize : inPacketOverhead);
|
|
|
|
Socket = inSocket;
|
|
}
|
|
|
|
public override void InitRemoteConnection(UNetDriver inDriver, UdpClient inSocket, FUrl inURL, IPEndPoint inRemoteAddr, EConnectionState inState, int inMaxPacket = 0, int inPacketOverhead = 0)
|
|
{
|
|
InitBase(inDriver, inSocket, inURL, inState,
|
|
(inMaxPacket == 0 || inMaxPacket > MaxPacketSize) ? MaxPacketSize : inMaxPacket,
|
|
inPacketOverhead == 0 ? UdpHeaderSize : inPacketOverhead);
|
|
|
|
RemoteAddr = inRemoteAddr;
|
|
Url.Host = RemoteAddr.Address;
|
|
|
|
// Initialize our send bunch
|
|
InitSendBuffer();
|
|
|
|
// This is for a client that needs to log in, setup ClientLoginState and ExpectedClientLoginMsgType to reflect that
|
|
SetClientLoginState(EClientLoginState.LoggingIn);
|
|
SetExpectedClientLoginMsgType(NMT.Hello); // TODO: NMT_HELLO
|
|
}
|
|
|
|
public override void InitLocalConnection(UNetDriver inDriver, UdpClient inSocket, FUrl inURL, EConnectionState inState, int inMaxPacket = 0, int inPacketOverhead = 0)
|
|
{
|
|
InitBase(inDriver, inSocket, inURL, inState,
|
|
// Use the default packet size/overhead unless overridden by a child class
|
|
(inMaxPacket == 0 || inMaxPacket > MaxPacketSize) ? MaxPacketSize : inMaxPacket,
|
|
inPacketOverhead == 0 ? inMaxPacket : inPacketOverhead);
|
|
//RemoteAddr = new IPEndPoint(inURL.Host, inURL.Port);
|
|
InitSendBuffer();
|
|
}
|
|
|
|
public override void LowLevelSend(byte[] data, int countBits, FOutPacketTraits traits)
|
|
{
|
|
// TODO: Improve according to UE4
|
|
|
|
var dataToSend = data;
|
|
|
|
// Process any packet modifiers
|
|
if (Handler != null && !Handler.GetRawSend())
|
|
{
|
|
var processedData = Handler.Outgoing(data, countBits, traits);
|
|
if (!processedData.Error)
|
|
{
|
|
dataToSend = processedData.Data;
|
|
countBits = processedData.CountBits;
|
|
}
|
|
else
|
|
{
|
|
countBits = 0;
|
|
}
|
|
}
|
|
|
|
var countBytes = FMath.DivideAndRoundUp(countBits, 8);
|
|
if (countBits > 0)
|
|
{
|
|
if (Socket == null)
|
|
{
|
|
throw new UnrealNetException();
|
|
}
|
|
|
|
// can't send remote addr if client is already set. receive is called before now too, so need to establish socket before then.
|
|
if (RemoteAddr.Address.GetAddressBytes().All(a => a == 0xff))
|
|
Socket.Send(dataToSend, countBytes);
|
|
|
|
else
|
|
Socket.Send(dataToSend, countBytes, RemoteAddr);
|
|
}
|
|
}
|
|
|
|
public override string LowLevelGetRemoteAddress(bool bAppendPort = false)
|
|
{
|
|
if (RemoteAddr != null)
|
|
{
|
|
// TODO: Remove port
|
|
return RemoteAddr.ToString();
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
public override string LowLevelDescribe()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override void CleanUp()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override void ReceivedRawPacket(FReceivedPacketView packetView)
|
|
{
|
|
_socketErrorRecvDelayStartTime = 0;
|
|
|
|
base.ReceivedRawPacket(packetView);
|
|
}
|
|
|
|
public override float GetTimeoutValue()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
} |