Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaClient/ClientSource/Networking/Primitives/P2PSocket/EosP2PSocket.cs
2025-09-17 13:44:21 +03:00

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();
}
}