Client LuaCsForBarotrauma
EosP2PSocket.cs
1 #nullable enable
2 
3 namespace Barotrauma.Networking;
4 
5 sealed class EosP2PSocket : P2PSocket
6 {
7  private readonly EosInterface.P2PSocket eosSocket;
8 
9  private EosP2PSocket(
11  EosInterface.P2PSocket eosSocket)
12  : base(callbacks)
13  {
14  this.eosSocket = eosSocket;
15  }
16 
17  public static Result<P2PSocket, Error> Create(Callbacks callbacks)
18  {
19  if (!EosInterface.Core.IsInitialized) { return Result.Failure(new Error(ErrorCode.EosNotInitialized)); }
20 
21  var eosSocketId = new EosInterface.SocketId { SocketName = EosP2PEndpoint.SocketName };
22  if (EosInterface.IdQueries.GetLoggedInPuids() is not { Length: > 0 } puids)
23  {
24  return Result.Failure(new Error(ErrorCode.EosNotLoggedIn));
25  }
26  var socketCreateResult = EosInterface.P2PSocket.Create(puids[0], eosSocketId);
27 
28  if (!socketCreateResult.TryUnwrapSuccess(out var eosSocket)) { return Result.Failure(new Error(ErrorCode.FailedToCreateEosP2PSocket, socketCreateResult.ToString())); }
29  var retVal = new EosP2PSocket(callbacks, eosSocket);
30 
31  eosSocket.HandleIncomingConnection.Register("Event".ToIdentifier(), retVal.OnIncomingConnection);
32  eosSocket.HandleClosedConnection.Register("Event".ToIdentifier(), retVal.OnConnectionClosed);
33 
34  return Result.Success((P2PSocket)retVal);
35  }
36 
37  public override void ProcessIncomingMessages()
38  {
39  foreach (var msg in eosSocket.GetMessageBatch())
40  {
41  callbacks.OnData(new EosP2PEndpoint(msg.Sender), new ReadWriteMessage(msg.Buffer, 0, msg.ByteLength * 8, false));
42  }
43  }
44 
45  public override bool SendMessage(P2PEndpoint endpoint, IWriteMessage outMsg, DeliveryMethod deliveryMethod)
46  {
47  if (endpoint is not EosP2PEndpoint { ProductUserId: var puid }) { return false; }
48  var sendResult = eosSocket.SendMessage(new EosInterface.P2PSocket.OutgoingMessage(
49  Buffer: outMsg.Buffer,
50  ByteLength: outMsg.LengthBytes,
51  Destination: puid,
52  DeliveryMethod: deliveryMethod));
53  return sendResult.IsSuccess;
54  }
55 
56  private void OnIncomingConnection(EosInterface.P2PSocket.IncomingConnectionRequest request)
57  {
58  var remoteEndpoint = new EosP2PEndpoint(request.RemoteUserId);
59 
60  if (callbacks.OnIncomingConnection(remoteEndpoint))
61  {
62  request.Accept();
63  }
64  }
65 
66  private void OnConnectionClosed(EosInterface.P2PSocket.RemoteConnectionClosed data)
67  {
68  var remoteEndpoint = new EosP2PEndpoint(data.RemoteUserId);
69 
70  var peerDisconnectPacket = PeerDisconnectPacket.WithReason(data.Reason switch
71  {
72  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.Unknown => DisconnectReason.Unknown,
73  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.ClosedByLocalUser => DisconnectReason.Disconnected,
74  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.ClosedByPeer => DisconnectReason.Disconnected,
75  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.TimedOut => DisconnectReason.Timeout,
76  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.TooManyConnections => DisconnectReason.ServerFull,
77  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.InvalidMessage => DisconnectReason.Unknown,
78  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.InvalidData => DisconnectReason.Unknown,
79  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.ConnectionFailed => DisconnectReason.AuthenticationFailed,
80  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.ConnectionClosed => DisconnectReason.Disconnected,
81  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.NegotiationFailed => DisconnectReason.AuthenticationFailed,
82  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.UnexpectedError => DisconnectReason.Unknown,
83  EosInterface.P2PSocket.RemoteConnectionClosed.ConnectionClosedReason.Unhandled => DisconnectReason.Unknown,
84  _ => DisconnectReason.Unknown
85  });
86  callbacks.OnConnectionClosed(remoteEndpoint, peerDisconnectPacket);
87  }
88 
89  public override void CloseConnection(P2PEndpoint endpoint)
90  {
91  if (endpoint is not EosP2PEndpoint { ProductUserId: var puid }) { return; }
92  eosSocket.CloseConnection(puid);
93  }
94 
95  public override void Dispose()
96  {
97  eosSocket.Dispose();
98  }
99 }
const string SocketName
override void Dispose()
Definition: EosP2PSocket.cs:95
override void ProcessIncomingMessages()
Definition: EosP2PSocket.cs:37
override void CloseConnection(P2PEndpoint endpoint)
Definition: EosP2PSocket.cs:89
override bool SendMessage(P2PEndpoint endpoint, IWriteMessage outMsg, DeliveryMethod deliveryMethod)
Definition: EosP2PSocket.cs:45
static Result< P2PSocket, Error > Create(Callbacks callbacks)
Definition: EosP2PSocket.cs:17
readonly record struct Error(ImmutableArray<(ErrorCode Code, string AdditionalInfo)> CodesAndInfo)
Definition: P2PSocket.cs:21
readonly record struct Callbacks(Predicate< P2PEndpoint > OnIncomingConnection, Action< P2PEndpoint, PeerDisconnectPacket > OnConnectionClosed, Action< P2PEndpoint, IReadMessage > OnData)
abstract bool SendMessage(P2PEndpoint endpoint, IWriteMessage outMsg, DeliveryMethod deliveryMethod)
readonly Callbacks callbacks
Definition: P2PSocket.cs:42
P2PSocket(Callbacks callbacks)
Definition: P2PSocket.cs:44
abstract void CloseConnection(P2PEndpoint endpoint)
abstract void Dispose()