106 lines
4.8 KiB
C#
106 lines
4.8 KiB
C#
#nullable enable
|
|
|
|
namespace Barotrauma.Networking;
|
|
|
|
sealed class EosP2PSocket : P2PSocket
|
|
{
|
|
private readonly EosInterface.P2PSocket eosSocket;
|
|
|
|
private EosP2PSocket(
|
|
Callbacks callbacks,
|
|
EosInterface.P2PSocket eosSocket,
|
|
OwnerOrClient type)
|
|
: base(callbacks, type)
|
|
{
|
|
this.eosSocket = eosSocket;
|
|
}
|
|
|
|
public static Result<P2PSocket, Error> Create(Callbacks callbacks, OwnerOrClient type)
|
|
{
|
|
if (!EosInterface.Core.IsInitialized) { return Result.Failure(new Error(ErrorCode.EosNotInitialized)); }
|
|
|
|
var eosSocketId = new EosInterface.SocketId { SocketName = EosP2PEndpoint.SocketName };
|
|
if (EosInterface.IdQueries.GetLoggedInPuids() is not { Length: > 0 } puids)
|
|
{
|
|
return Result.Failure(new Error(ErrorCode.EosNotLoggedIn));
|
|
}
|
|
var socketCreateResult = EosInterface.P2PSocket.Create(puids[0], eosSocketId);
|
|
|
|
if (!socketCreateResult.TryUnwrapSuccess(out var eosSocket)) { return Result.Failure(new Error(ErrorCode.FailedToCreateEosP2PSocket, socketCreateResult.ToString())); }
|
|
var retVal = new EosP2PSocket(callbacks, eosSocket, type);
|
|
|
|
eosSocket.HandleIncomingConnection.Register("Event".ToIdentifier(), retVal.OnIncomingConnection);
|
|
eosSocket.HandleClosedConnection.Register("Event".ToIdentifier(), retVal.OnConnectionClosed);
|
|
|
|
return Result.Success<P2PSocket>(retVal);
|
|
}
|
|
|
|
public override void ProcessIncomingMessages()
|
|
{
|
|
foreach (var msg in eosSocket.GetMessageBatch())
|
|
{
|
|
EosP2PEndpoint endpoint = new EosP2PEndpoint(msg.Sender);
|
|
callbacks.OnData(endpoint, new ReadWriteMessage(msg.Buffer, 0, msg.ByteLength * 8, false));
|
|
|
|
if (Type is OwnerOrClient.Owner)
|
|
{
|
|
dosProtection.OnPacket(endpoint);
|
|
}
|
|
}
|
|
}
|
|
|
|
public override bool SendMessage(P2PEndpoint endpoint, IWriteMessage outMsg, DeliveryMethod deliveryMethod)
|
|
{
|
|
if (endpoint is not EosP2PEndpoint { ProductUserId: var puid }) { return false; }
|
|
var sendResult = eosSocket.SendMessage(new EosInterface.P2PSocket.OutgoingMessage(
|
|
Buffer: outMsg.Buffer,
|
|
ByteLength: outMsg.LengthBytes,
|
|
Destination: puid,
|
|
DeliveryMethod: deliveryMethod));
|
|
return sendResult.IsSuccess;
|
|
}
|
|
|
|
private void OnIncomingConnection(EosInterface.P2PSocket.IncomingConnectionRequest request)
|
|
{
|
|
var remoteEndpoint = new EosP2PEndpoint(request.RemoteUserId);
|
|
|
|
if (callbacks.OnIncomingConnection(remoteEndpoint))
|
|
{
|
|
request.Accept();
|
|
}
|
|
}
|
|
|
|
private void OnConnectionClosed(EosInterface.P2PSocket.RemoteConnectionClosed data)
|
|
{
|
|
var remoteEndpoint = new EosP2PEndpoint(data.RemoteUserId);
|
|
|
|
var peerDisconnectPacket = PeerDisconnectPacket.WithReason(data.Reason switch
|
|
{
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.Unknown => DisconnectReason.Unknown,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.ClosedByLocalUser => DisconnectReason.Disconnected,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.ClosedByPeer => DisconnectReason.Disconnected,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.TimedOut => DisconnectReason.Timeout,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.TooManyConnections => DisconnectReason.ServerFull,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.InvalidMessage => DisconnectReason.Unknown,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.InvalidData => DisconnectReason.Unknown,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.ConnectionFailed => DisconnectReason.AuthenticationFailed,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.ConnectionClosed => DisconnectReason.Disconnected,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.NegotiationFailed => DisconnectReason.AuthenticationFailed,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.UnexpectedError => DisconnectReason.Unknown,
|
|
EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.Unhandled => DisconnectReason.Unknown,
|
|
_ => DisconnectReason.Unknown
|
|
});
|
|
callbacks.OnConnectionClosed(remoteEndpoint, peerDisconnectPacket);
|
|
}
|
|
|
|
public override void CloseConnection(P2PEndpoint endpoint)
|
|
{
|
|
if (endpoint is not EosP2PEndpoint { ProductUserId: var puid }) { return; }
|
|
eosSocket.CloseConnection(puid);
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
eosSocket.Dispose();
|
|
}
|
|
} |