Unstable v0.19.1.0

This commit is contained in:
Juan Pablo Arce
2022-08-19 13:59:08 -03:00
parent 6b55adcdd9
commit 1219615d64
192 changed files with 3875 additions and 2648 deletions
@@ -1,11 +1,9 @@
using Barotrauma.Extensions;
#nullable enable
using Barotrauma.Steam;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Barotrauma.Networking
{
@@ -18,7 +16,7 @@ namespace Barotrauma.Networking
public readonly UInt64 WorkshopId;
public readonly DateTime InstallTime;
public RegularPackage RegularPackage
public RegularPackage? RegularPackage
{
get
{
@@ -26,7 +24,7 @@ namespace Barotrauma.Networking
}
}
public CorePackage CorePackage
public CorePackage? CorePackage
{
get
{
@@ -34,8 +32,8 @@ namespace Barotrauma.Networking
}
}
public ContentPackage ContentPackage
=> (ContentPackage)RegularPackage ?? CorePackage;
public ContentPackage? ContentPackage
=> (ContentPackage?)RegularPackage ?? CorePackage;
public string GetPackageStr()
@@ -58,21 +56,44 @@ namespace Barotrauma.Networking
public delegate void DisconnectMessageCallback(string message);
public delegate void PasswordCallback(int salt, int retries);
public delegate void InitializationCompleteCallback();
[Obsolete("TODO: delete in nr3-layer-1-2-cleanup")]
public readonly struct Callbacks
{
public readonly MessageCallback OnMessageReceived;
public readonly DisconnectCallback OnDisconnect;
public readonly DisconnectMessageCallback OnDisconnectMessageReceived;
public readonly PasswordCallback OnRequestPassword;
public readonly InitializationCompleteCallback OnInitializationComplete;
public Callbacks(MessageCallback onMessageReceived, DisconnectCallback onDisconnect, DisconnectMessageCallback onDisconnectMessageReceived, PasswordCallback onRequestPassword, InitializationCompleteCallback onInitializationComplete)
{
OnMessageReceived = onMessageReceived;
OnDisconnect = onDisconnect;
OnDisconnectMessageReceived = onDisconnectMessageReceived;
OnRequestPassword = onRequestPassword;
OnInitializationComplete = onInitializationComplete;
}
}
protected readonly Callbacks callbacks;
public readonly Endpoint ServerEndpoint;
public NetworkConnection? ServerConnection { get; protected set; }
protected readonly bool isOwner;
protected readonly Option<int> ownerKey;
public ClientPeer(Endpoint serverEndpoint, Callbacks callbacks, Option<int> ownerKey)
{
ServerEndpoint = serverEndpoint;
this.callbacks = callbacks;
this.ownerKey = ownerKey;
isOwner = ownerKey.IsSome();
}
public MessageCallback OnMessageReceived;
public DisconnectCallback OnDisconnect;
public DisconnectMessageCallback OnDisconnectMessageReceived;
public PasswordCallback OnRequestPassword;
public InitializationCompleteCallback OnInitializationComplete;
public string Name;
public string Version { get; protected set; }
public NetworkConnection ServerConnection { get; protected set; }
public abstract void Start(object endPoint, int ownerKey);
public abstract void Close(string msg = null, bool disableReconnect = false);
public abstract void Start();
public abstract void Close(string? msg = null, bool disableReconnect = false);
public abstract void Update(float deltaTime);
public abstract void Send(IWriteMessage msg, DeliveryMethod deliveryMethod, bool compressPastThreshold = true);
public abstract void SendPassword(string password);
@@ -80,10 +101,9 @@ namespace Barotrauma.Networking
protected abstract void SendMsgInternal(DeliveryMethod deliveryMethod, IWriteMessage msg);
protected ConnectionInitialization initializationStep;
protected bool contentPackageOrderReceived;
protected int ownerKey = 0;
public bool ContentPackageOrderReceived { get; protected set; }
protected int passwordSalt;
protected Steamworks.AuthTicket steamAuthTicket;
protected Steamworks.AuthTicket? steamAuthTicket;
protected void ReadConnectionInitializationStep(IReadMessage inc)
{
ConnectionInitialization step = (ConnectionInitialization)inc.ReadByte();
@@ -97,9 +117,9 @@ namespace Barotrauma.Networking
outMsg = new WriteOnlyMessage();
outMsg.Write((byte)PacketHeader.IsConnectionInitializationStep);
outMsg.Write((byte)ConnectionInitialization.SteamTicketAndVersion);
outMsg.Write(Name);
outMsg.Write(ownerKey);
outMsg.Write(SteamManager.GetSteamID());
outMsg.Write(GameMain.Client.Name);
outMsg.Write(ownerKey.Fallback(0));
outMsg.Write(SteamManager.GetSteamId().Select(steamId => steamId.Value).Fallback(0));
if (steamAuthTicket == null)
{
outMsg.Write((UInt16)0);
@@ -122,8 +142,6 @@ namespace Barotrauma.Networking
outMsg.Write((byte)PacketHeader.IsConnectionInitializationStep);
outMsg.Write((byte)ConnectionInitialization.ContentPackageOrder);
string serverName = inc.ReadString();
UInt32 packageCount = inc.ReadVariableUInt32();
List<ServerContentPackage> serverPackages = new List<ServerContentPackage>();
for (int i = 0; i < packageCount; i++)
@@ -139,9 +157,16 @@ namespace Barotrauma.Networking
serverPackages.Add(pkg);
}
if (!contentPackageOrderReceived)
if (!ContentPackageOrderReceived)
{
ServerContentPackages = serverPackages.ToImmutableArray();
if (serverPackages.Count == 0)
{
string errorMsg = "Error in ContentPackageOrder message: list of content packages enabled on the server was empty.";
GameAnalyticsManager.AddErrorEventOnce("ClientPeer.ReadConnectionInitializationStep:NoContentPackages", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
DebugConsole.ThrowError(errorMsg);
}
ContentPackageOrderReceived = true;
SendMsgInternal(DeliveryMethod.Reliable, outMsg);
}
break;
@@ -158,7 +183,7 @@ namespace Barotrauma.Networking
{
retries = inc.ReadInt32();
}
OnRequestPassword?.Invoke(passwordSalt, retries);
callbacks.OnRequestPassword.Invoke(passwordSalt, retries);
break;
}
}
@@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using Barotrauma.Steam;
using Lidgren.Network;
using Barotrauma.Steam;
using System.Linq;
using System;
using System.Collections.Generic;
using System.Text;
namespace Barotrauma.Networking
{
@@ -16,39 +14,42 @@ namespace Barotrauma.Networking
List<NetIncomingMessage> incomingLidgrenMessages;
public LidgrenClientPeer(string name)
private LidgrenEndpoint lidgrenEndpoint
=> ServerConnection is LidgrenConnection { Endpoint: LidgrenEndpoint result }
? result
: throw new InvalidOperationException();
public LidgrenClientPeer(LidgrenEndpoint endpoint, Callbacks callbacks, Option<int> ownerKey) : base(endpoint, callbacks, ownerKey)
{
ServerConnection = null;
Name = name;
netClient = null;
isActive = false;
}
public override void Start(object endPoint, int ownerKey)
public override void Start()
{
if (isActive) { return; }
this.ownerKey = ownerKey;
contentPackageOrderReceived = false;
ContentPackageOrderReceived = false;
netPeerConfiguration = new NetPeerConfiguration("barotrauma")
{
UseDualModeSockets = GameSettings.CurrentConfig.UseDualModeSockets
};
netPeerConfiguration.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
| NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
netPeerConfiguration.DisableMessageType(
NetIncomingMessageType.DebugMessage
| NetIncomingMessageType.WarningMessage
| NetIncomingMessageType.Receipt
| NetIncomingMessageType.ErrorMessage
| NetIncomingMessageType.Error);
netClient = new NetClient(netPeerConfiguration);
if (SteamManager.IsInitialized)
{
steamAuthTicket = SteamManager.GetAuthSessionTicket();
//TODO: wait for GetAuthSessionTicketResponse_t
if (steamAuthTicket == null)
{
throw new Exception("GetAuthSessionTicket returned null");
@@ -59,7 +60,7 @@ namespace Barotrauma.Networking
initializationStep = ConnectionInitialization.SteamTicketAndVersion;
if (!(endPoint is IPEndPoint ipEndPoint))
if (!(ServerEndpoint is LidgrenEndpoint lidgrenEndpoint))
{
throw new InvalidCastException("endPoint is not IPEndPoint");
}
@@ -69,7 +70,10 @@ namespace Barotrauma.Networking
}
netClient.Start();
ServerConnection = new LidgrenConnection("Server", netClient.Connect(ipEndPoint), 0)
var netConnection = netClient.Connect(lidgrenEndpoint.NetEndpoint);
ServerConnection = new LidgrenConnection(netConnection)
{
Status = NetworkConnectionStatus.Connected
};
@@ -81,7 +85,7 @@ namespace Barotrauma.Networking
{
if (!isActive) { return; }
if (ownerKey != 0 && (ChildServerRelay.Process?.HasExited ?? true))
if (isOwner && !(ChildServerRelay.Process is { HasExited: false }))
{
Close();
var msgBox = new GUIMessageBox(TextManager.Get("ConnectionLost"), ChildServerRelay.CrashMessage);
@@ -97,7 +101,7 @@ namespace Barotrauma.Networking
foreach (NetIncomingMessage inc in incomingLidgrenMessages)
{
if (inc.SenderConnection != (ServerConnection as LidgrenConnection).NetConnection) { continue; }
if (!inc.SenderConnection.RemoteEndPoint.Equals(lidgrenEndpoint.NetEndpoint)) { continue; }
switch (inc.MessageType)
{
@@ -125,12 +129,12 @@ namespace Barotrauma.Networking
{
if (initializationStep != ConnectionInitialization.Success)
{
OnInitializationComplete?.Invoke();
callbacks.OnInitializationComplete.Invoke();
initializationStep = ConnectionInitialization.Success;
}
UInt16 length = inc.ReadUInt16();
IReadMessage msg = new ReadOnlyMessage(inc.Data, packetHeader.IsCompressed(), inc.PositionInBytes, length, ServerConnection);
OnMessageReceived?.Invoke(msg);
callbacks.OnMessageReceived.Invoke(msg);
}
}
@@ -144,7 +148,7 @@ namespace Barotrauma.Networking
case NetConnectionStatus.Disconnected:
string disconnectMsg = inc.ReadString();
Close(disconnectMsg);
OnDisconnectMessageReceived?.Invoke(disconnectMsg);
callbacks.OnDisconnectMessageReceived.Invoke(disconnectMsg);
break;
}
}
@@ -176,7 +180,7 @@ namespace Barotrauma.Networking
netClient.Shutdown(msg ?? TextManager.Get("Disconnecting").Value);
netClient = null;
steamAuthTicket?.Cancel(); steamAuthTicket = null;
OnDisconnect?.Invoke(disableReconnect);
callbacks.OnDisconnect.Invoke(disableReconnect);
}
public override void Send(IWriteMessage msg, DeliveryMethod deliveryMethod, bool compressPastThreshold = true)
@@ -1,17 +1,16 @@
using System;
using Barotrauma.Steam;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Barotrauma.Steam;
using System.Text;
using System.Threading;
using Barotrauma.Items.Components;
namespace Barotrauma.Networking
{
class SteamP2PClientPeer : ClientPeer
{
private bool isActive;
private UInt64 hostSteamId;
private readonly SteamId hostSteamId;
private double timeout;
private double heartbeatTimer;
private double connectionStatusTimer;
@@ -21,18 +20,23 @@ namespace Barotrauma.Networking
private List<IReadMessage> incomingInitializationMessages;
private List<IReadMessage> incomingDataMessages;
public SteamP2PClientPeer(string name)
public SteamP2PClientPeer(SteamP2PEndpoint endpoint, Callbacks callbacks) : base(endpoint, callbacks, Option<int>.None())
{
ServerConnection = null;
Name = name;
isActive = false;
if (!(ServerEndpoint is SteamP2PEndpoint steamIdEndpoint))
{
throw new InvalidCastException("endPoint is not SteamId");
}
hostSteamId = steamIdEndpoint.SteamId;
}
public override void Start(object endPoint, int ownerKey)
public override void Start()
{
contentPackageOrderReceived = false;
ContentPackageOrderReceived = false;
steamAuthTicket = SteamManager.GetAuthSessionTicket();
//TODO: wait for GetAuthSessionTicketResponse_t
@@ -42,21 +46,14 @@ namespace Barotrauma.Networking
throw new Exception("GetAuthSessionTicket returned null");
}
if (!(endPoint is UInt64 steamIdEndpoint))
{
throw new InvalidCastException("endPoint is not UInt64");
}
hostSteamId = steamIdEndpoint;
Steamworks.SteamNetworking.ResetActions();
Steamworks.SteamNetworking.OnP2PSessionRequest = OnIncomingConnection;
Steamworks.SteamNetworking.OnP2PConnectionFailed = OnConnectionFailed;
Steamworks.SteamNetworking.AllowP2PPacketRelay(true);
ServerConnection = new SteamP2PConnection("Server", hostSteamId);
ServerConnection.SetOwnerSteamIDIfUnknown(hostSteamId);
ServerConnection = new SteamP2PConnection(hostSteamId);
ServerConnection.SetAccountInfo(new AccountInfo(hostSteamId));
incomingInitializationMessages = new List<IReadMessage>();
incomingDataMessages = new List<IReadMessage>();
@@ -66,7 +63,7 @@ namespace Barotrauma.Networking
outMsg.Write((byte)PacketHeader.IsConnectionInitializationStep);
outMsg.Write((byte)ConnectionInitialization.ConnectionStarted);
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId.Value, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
sentBytes += outMsg.LengthBytes;
initializationStep = ConnectionInitialization.SteamTicketAndVersion;
@@ -81,7 +78,7 @@ namespace Barotrauma.Networking
private void OnIncomingConnection(Steamworks.SteamId steamId)
{
if (!isActive) { return; }
if (steamId == hostSteamId)
if (steamId == hostSteamId.Value)
{
Steamworks.SteamNetworking.AcceptP2PSessionWithUser(steamId);
}
@@ -90,23 +87,23 @@ namespace Barotrauma.Networking
initializationStep != ConnectionInitialization.Success)
{
DebugConsole.ThrowError($"Connection from incorrect SteamID was rejected: "+
$"expected {SteamManager.SteamIDUInt64ToString(hostSteamId)}," +
$"got {SteamManager.SteamIDUInt64ToString(steamId)}");
$"expected {hostSteamId}," +
$"got {new SteamId(steamId)}");
}
}
private void OnConnectionFailed(Steamworks.SteamId steamId, Steamworks.P2PSessionError error)
{
if (!isActive) { return; }
if (steamId != hostSteamId) { return; }
if (steamId != hostSteamId.Value) { return; }
Close($"SteamP2P connection failed: {error}");
OnDisconnectMessageReceived?.Invoke($"{DisconnectReason.SteamP2PError}/SteamP2P connection failed: {error}");
callbacks.OnDisconnectMessageReceived.Invoke($"{DisconnectReason.SteamP2PError}/SteamP2P connection failed: {error}");
}
private void OnP2PData(ulong steamId, byte[] data, int dataLength)
{
if (!isActive) { return; }
if (steamId != hostSteamId) { return; }
if (steamId != hostSteamId.Value) { return; }
timeout = Screen.Selected == GameMain.GameScreen ?
NetworkConnection.TimeoutThresholdInGame :
@@ -138,7 +135,7 @@ namespace Barotrauma.Networking
IReadMessage inc = new ReadOnlyMessage(data, false, 1, dataLength - 1, ServerConnection);
string msg = inc.ReadString();
Close(msg);
OnDisconnectMessageReceived?.Invoke(msg);
callbacks.OnDisconnectMessageReceived.Invoke(msg);
}
else
{
@@ -166,18 +163,18 @@ namespace Barotrauma.Networking
connectionStatusTimer -= deltaTime;
if (connectionStatusTimer <= 0.0)
{
var state = Steamworks.SteamNetworking.GetP2PSessionState(hostSteamId);
var state = Steamworks.SteamNetworking.GetP2PSessionState(hostSteamId.Value);
if (state == null)
{
Close("SteamP2P connection could not be established");
OnDisconnectMessageReceived?.Invoke(DisconnectReason.SteamP2PError.ToString());
callbacks.OnDisconnectMessageReceived.Invoke(DisconnectReason.SteamP2PError.ToString());
}
else
{
if (state?.P2PSessionError != Steamworks.P2PSessionError.None)
{
Close($"SteamP2P error code: {state?.P2PSessionError}");
OnDisconnectMessageReceived?.Invoke($"{DisconnectReason.SteamP2PError}/SteamP2P error code: {state?.P2PSessionError}");
callbacks.OnDisconnectMessageReceived.Invoke($"{DisconnectReason.SteamP2PError}/SteamP2P error code: {state?.P2PSessionError}");
}
}
connectionStatusTimer = 1.0f;
@@ -204,7 +201,7 @@ namespace Barotrauma.Networking
outMsg.Write((byte)DeliveryMethod.Unreliable);
outMsg.Write((byte)PacketHeader.IsHeartbeatMessage);
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Unreliable);
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId.Value, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Unreliable);
sentBytes += outMsg.LengthBytes;
heartbeatTimer = 5.0;
@@ -213,7 +210,7 @@ namespace Barotrauma.Networking
if (timeout < 0.0)
{
Close("Timed out");
OnDisconnectMessageReceived?.Invoke(DisconnectReason.SteamP2PTimeOut.ToString());
callbacks.OnDisconnectMessageReceived.Invoke(DisconnectReason.SteamP2PTimeOut.ToString());
return;
}
@@ -221,7 +218,22 @@ namespace Barotrauma.Networking
{
if (incomingDataMessages.Count > 0)
{
OnInitializationComplete?.Invoke();
var incomingMessage = incomingDataMessages.First();
byte incomingHeader = incomingMessage.LengthBytes > 0 ? incomingMessage.PeekByte() : (byte)0;
if (ContentPackageOrderReceived)
{
#warning: TODO: do not allow completing initialization until content package order has been received?
string errorMsg = $"Error during connection initialization: completed initialization before receiving content package order. Incoming header: {incomingHeader}";
GameAnalyticsManager.AddErrorEventOnce("SteamP2PClientPeer.OnInitializationComplete:ContentPackageOrderNotReceived", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
DebugConsole.ThrowError(errorMsg);
}
if (ServerContentPackages.Length == 0)
{
string errorMsg = $"Error during connection initialization: list of content packages enabled on the server was empty when completing initialization. Incoming header: {incomingHeader}";
GameAnalyticsManager.AddErrorEventOnce("SteamP2PClientPeer.OnInitializationComplete:NoContentPackages", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
DebugConsole.ThrowError(errorMsg);
}
callbacks.OnInitializationComplete.Invoke();
initializationStep = ConnectionInitialization.Success;
}
else
@@ -237,7 +249,7 @@ namespace Barotrauma.Networking
{
foreach (IReadMessage inc in incomingDataMessages)
{
OnMessageReceived?.Invoke(inc);
callbacks.OnMessageReceived.Invoke(inc);
}
}
@@ -303,7 +315,7 @@ namespace Barotrauma.Networking
private void Send(byte[] buf, int length, Steamworks.P2PSend sendType)
{
bool successSend = Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, buf, length + 4, 0, sendType);
bool successSend = Steamworks.SteamNetworking.SendP2PPacket(hostSteamId.Value, buf, length + 4, 0, sendType);
sentBytes += length + 4;
if (!successSend)
{
@@ -311,7 +323,7 @@ namespace Barotrauma.Networking
{
DebugConsole.Log("WARNING: message couldn't be sent unreliably, forcing reliable send (" + length.ToString() + " bytes)");
sendType = Steamworks.P2PSend.Reliable;
successSend = Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, buf, length + 4, 0, sendType);
successSend = Steamworks.SteamNetworking.SendP2PPacket(hostSteamId.Value, buf, length + 4, 0, sendType);
sentBytes += length + 4;
}
if (!successSend)
@@ -335,7 +347,7 @@ namespace Barotrauma.Networking
outMsg.Write(saltedPw, 0, saltedPw.Length);
heartbeatTimer = 5.0;
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId.Value, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
sentBytes += outMsg.LengthBytes;
}
@@ -354,7 +366,7 @@ namespace Barotrauma.Networking
try
{
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId.Value, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
sentBytes += outMsg.LengthBytes;
}
catch (Exception e)
@@ -365,12 +377,11 @@ namespace Barotrauma.Networking
Thread.Sleep(100);
Steamworks.SteamNetworking.ResetActions();
Steamworks.SteamNetworking.CloseP2PSessionWithUser(hostSteamId);
Steamworks.SteamNetworking.CloseP2PSessionWithUser(hostSteamId.Value);
steamAuthTicket?.Cancel(); steamAuthTicket = null;
hostSteamId = 0;
OnDisconnect?.Invoke(disableReconnect);
callbacks.OnDisconnect.Invoke(disableReconnect);
}
protected override void SendMsgInternal(DeliveryMethod deliveryMethod, IWriteMessage msg)
@@ -394,7 +405,7 @@ namespace Barotrauma.Networking
msgToSend.Write(msg.Buffer, 0, msg.LengthBytes);
heartbeatTimer = 5.0;
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, msgToSend.Buffer, msgToSend.LengthBytes, 0, sendType);
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId.Value, msgToSend.Buffer, msgToSend.LengthBytes, 0, sendType);
sentBytes += msg.LengthBytes;
}
@@ -1,7 +1,7 @@
using Barotrauma.Steam;
using Barotrauma.Extensions;
using Barotrauma.Steam;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace Barotrauma.Networking
@@ -10,20 +10,20 @@ namespace Barotrauma.Networking
{
private bool isActive;
private readonly UInt64 selfSteamID;
private UInt64 ownerKey64 => unchecked((UInt64)ownerKey);
private readonly SteamId selfSteamID;
private UInt64 ownerKey64 => unchecked((UInt64)ownerKey.Fallback(0));
private UInt64 ReadSteamId(IReadMessage inc)
=> inc.ReadUInt64() ^ ownerKey64;
private void WriteSteamId(IWriteMessage msg, UInt64 val)
=> msg.Write(val ^ ownerKey64);
private SteamId ReadSteamId(IReadMessage inc)
=> new SteamId(inc.ReadUInt64() ^ ownerKey64);
private void WriteSteamId(IWriteMessage msg, SteamId val)
=> msg.Write(val.Value ^ ownerKey64);
private long sentBytes, receivedBytes;
class RemotePeer
{
public UInt64 SteamID;
public UInt64 OwnerSteamID;
public SteamId SteamId;
public Option<SteamId> OwnerSteamId;
public double? DisconnectTime;
public bool Authenticating;
public bool Authenticated;
@@ -33,12 +33,12 @@ namespace Barotrauma.Networking
public DeliveryMethod DeliveryMethod;
public IWriteMessage Message;
}
public List<UnauthedMessage> UnauthedMessages;
public readonly List<UnauthedMessage> UnauthedMessages;
public RemotePeer(UInt64 steamId)
public RemotePeer(SteamId steamId)
{
SteamID = steamId;
OwnerSteamID = 0;
SteamId = steamId;
OwnerSteamId = Option<SteamId>.None();
DisconnectTime = null;
Authenticating = false;
Authenticated = false;
@@ -49,27 +49,27 @@ namespace Barotrauma.Networking
}
List<RemotePeer> remotePeers;
public SteamP2POwnerPeer(string name)
public SteamP2POwnerPeer(Callbacks callbacks, int ownerKey) : base(new PipeEndpoint(), callbacks, Option<int>.Some(ownerKey))
{
ServerConnection = null;
Name = name;
isActive = false;
selfSteamID = Steam.SteamManager.GetSteamID();
selfSteamID = SteamManager.GetSteamId().TryUnwrap(out var steamId)
? steamId
: throw new InvalidOperationException("Steamworks not initialized");
}
public override void Start(object endPoint, int ownerKey)
public override void Start()
{
if (isActive) { return; }
this.ownerKey = ownerKey;
initializationStep = ConnectionInitialization.SteamTicketAndVersion;
ServerConnection = new PipeConnection(selfSteamID);
ServerConnection.Status = NetworkConnectionStatus.Connected;
ServerConnection = new PipeConnection(selfSteamID)
{
Status = NetworkConnectionStatus.Connected
};
remotePeers = new List<RemotePeer>();
@@ -82,10 +82,10 @@ namespace Barotrauma.Networking
isActive = true;
}
private void OnAuthChange(Steamworks.SteamId steamID, Steamworks.SteamId ownerID, Steamworks.AuthResponse status)
private void OnAuthChange(Steamworks.SteamId steamId, Steamworks.SteamId ownerId, Steamworks.AuthResponse status)
{
RemotePeer remotePeer = remotePeers.Find(p => p.SteamID == steamID);
DebugConsole.Log(steamID + " validation: " + status + ", " + (remotePeer != null));
RemotePeer remotePeer = remotePeers.Find(p => p.SteamId.Value == steamId);
DebugConsole.Log(steamId + " validation: " + status + ", " + (remotePeer != null));
if (remotePeer == null) { return; }
@@ -100,7 +100,7 @@ namespace Barotrauma.Networking
if (status == Steamworks.AuthResponse.OK)
{
remotePeer.OwnerSteamID = ownerID;
remotePeer.OwnerSteamId = Option<SteamId>.Some(new SteamId(ownerId));
remotePeer.Authenticated = true;
remotePeer.Authenticating = false;
foreach (var msg in remotePeer.UnauthedMessages)
@@ -111,7 +111,7 @@ namespace Barotrauma.Networking
//known now
int prevBitPosition = msg.Message.BitPosition;
msg.Message.BitPosition = sizeof(ulong) * 8;
WriteSteamId(msg.Message, ownerID);
WriteSteamId(msg.Message, new SteamId(ownerId));
msg.Message.BitPosition = prevBitPosition;
byte[] msgToSend = (byte[])msg.Message.Buffer.Clone();
Array.Resize(ref msgToSend, msg.Message.LengthBytes);
@@ -130,34 +130,33 @@ namespace Barotrauma.Networking
{
if (!isActive) { return; }
if (!remotePeers.Any(p => p.SteamID == steamId))
if (remotePeers.None(p => p.SteamId.Value == steamId))
{
remotePeers.Add(new RemotePeer(steamId));
remotePeers.Add(new RemotePeer(new SteamId(steamId)));
}
Steamworks.SteamNetworking.AcceptP2PSessionWithUser(steamId); //accept all connections, the server will figure things out later
}
private void OnP2PData(ulong steamId, byte[] data, int dataLength, int channel)
private void OnP2PData(ulong steamId, byte[] data, int dataLength, int _)
{
if (!isActive) { return; }
RemotePeer remotePeer = remotePeers.Find(p => p.SteamID == steamId);
if (remotePeer == null || remotePeer.DisconnectTime != null)
{
return;
}
RemotePeer remotePeer = remotePeers.Find(p => p.SteamId.Value == steamId);
if (remotePeer == null) { return; }
if (remotePeer.DisconnectTime != null) { return; }
IWriteMessage outMsg = new WriteOnlyMessage();
WriteSteamId(outMsg, steamId);
WriteSteamId(outMsg, remotePeer.OwnerSteamID);
var steamUserId = new SteamId(steamId);
WriteSteamId(outMsg, steamUserId);
WriteSteamId(outMsg, remotePeer.OwnerSteamId.Fallback(steamUserId));
outMsg.Write(data, 1, dataLength - 1);
DeliveryMethod deliveryMethod = (DeliveryMethod)data[0];
PacketHeader packetHeader = (PacketHeader)data[1];
if (!remotePeer.Authenticated & !remotePeer.Authenticating && packetHeader.IsConnectionInitializationStep())
if (!remotePeer.Authenticated && !remotePeer.Authenticating && packetHeader.IsConnectionInitializationStep())
{
remotePeer.DisconnectTime = null;
@@ -240,7 +239,7 @@ namespace Barotrauma.Networking
{
if (!isActive) { return; }
UInt64 recipientSteamId = ReadSteamId(inc);
SteamId recipientSteamId = ReadSteamId(inc);
DeliveryMethod deliveryMethod = (DeliveryMethod)inc.ReadByte();
int p2pDataStart = inc.BytePosition;
@@ -255,7 +254,7 @@ namespace Barotrauma.Networking
return;
}
RemotePeer peer = remotePeers.Find(p => p.SteamID == recipientSteamId);
RemotePeer peer = remotePeers.Find(p => p.SteamId == recipientSteamId);
if (peer == null) { return; }
@@ -314,7 +313,7 @@ namespace Barotrauma.Networking
sendType = Steamworks.P2PSend.Reliable;
}
bool successSend = Steamworks.SteamNetworking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, 0, sendType);
bool successSend = Steamworks.SteamNetworking.SendP2PPacket(recipientSteamId.Value, p2pData, p2pData.Length, 0, sendType);
sentBytes += p2pData.Length;
if (!successSend)
@@ -323,7 +322,7 @@ namespace Barotrauma.Networking
{
DebugConsole.Log("WARNING: message couldn't be sent unreliably, forcing reliable send (" + p2pData.Length.ToString() + " bytes)");
sendType = Steamworks.P2PSend.Reliable;
successSend = Steamworks.SteamNetworking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, 0, sendType);
successSend = Steamworks.SteamNetworking.SendP2PPacket(recipientSteamId.Value, p2pData, p2pData.Length, 0, sendType);
sentBytes += p2pData.Length;
}
if (!successSend)
@@ -354,7 +353,7 @@ namespace Barotrauma.Networking
WriteSteamId(outMsg, selfSteamID);
WriteSteamId(outMsg, selfSteamID);
outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep));
outMsg.Write(Name);
outMsg.Write(GameMain.Client.Name);
byte[] msgToSend = (byte[])outMsg.Buffer.Clone();
Array.Resize(ref msgToSend, outMsg.LengthBytes);
@@ -365,12 +364,12 @@ namespace Barotrauma.Networking
{
if (initializationStep != ConnectionInitialization.Success)
{
OnInitializationComplete?.Invoke();
callbacks.OnInitializationComplete.Invoke();
initializationStep = ConnectionInitialization.Success;
}
UInt16 length = inc.ReadUInt16();
IReadMessage msg = new ReadOnlyMessage(inc.Buffer, packetHeader.IsCompressed(), inc.BytePosition, length, ServerConnection);
OnMessageReceived?.Invoke(msg);
callbacks.OnMessageReceived.Invoke(msg);
return;
}
@@ -390,7 +389,7 @@ namespace Barotrauma.Networking
outMsg.Write((byte)(PacketHeader.IsServerMessage | PacketHeader.IsDisconnectMessage));
outMsg.Write(msg);
Steamworks.SteamNetworking.SendP2PPacket(peer.SteamID, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
Steamworks.SteamNetworking.SendP2PPacket(peer.SteamId.Value, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
sentBytes += outMsg.LengthBytes;
}
else
@@ -401,7 +400,7 @@ namespace Barotrauma.Networking
private void ClosePeerSession(RemotePeer peer)
{
Steamworks.SteamNetworking.CloseP2PSessionWithUser(peer.SteamID);
Steamworks.SteamNetworking.CloseP2PSessionWithUser(peer.SteamId.Value);
remotePeers.Remove(peer);
}
@@ -430,7 +429,7 @@ namespace Barotrauma.Networking
ChildServerRelay.ClosePipes();
OnDisconnect?.Invoke(disableReconnect);
callbacks.OnDisconnect.Invoke(disableReconnect);
SteamManager.LeaveLobby();
Steamworks.SteamNetworking.ResetActions();