Files
2025-03-12 12:56:27 +00:00

140 lines
5.3 KiB
C#

#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Barotrauma.Extensions;
using Barotrauma.Steam;
namespace Barotrauma.Networking;
readonly record struct ConnectCommand(
Option<ConnectCommand.NameAndP2PEndpoints> NameAndP2PEndpointsOption,
Option<ConnectCommand.NameAndLidgrenEndpoint> NameAndLidgrenEndpointOption,
Option<ConnectCommand.SteamLobbyId> SteamLobbyIdOption)
{
public bool IsClientConnectedToEndpoint()
{
if (GameMain.Client?.ClientPeer == null) { return false; }
if (NameAndP2PEndpointsOption.TryUnwrap(out var nameAndP2PEndpoints))
{
if (nameAndP2PEndpoints.Endpoints.Any(e => e.Equals(GameMain.Client.ClientPeer.ServerEndpoint))) { return true; }
}
if (NameAndLidgrenEndpointOption.TryUnwrap(out var nameAndLidgrenEndpoint))
{
if (nameAndLidgrenEndpoint.Endpoint.Equals(GameMain.Client.ClientPeer.ServerEndpoint)) { return true; }
}
if (SteamLobbyIdOption.TryUnwrap(out var steamLobbyId))
{
if (SteamManager.CurrentLobbyID == steamLobbyId.Value) { return true; }
}
return false;
}
public readonly record struct NameAndP2PEndpoints(
string ServerName,
ImmutableArray<P2PEndpoint> Endpoints);
public readonly record struct NameAndLidgrenEndpoint(
string ServerName,
LidgrenEndpoint Endpoint);
public readonly record struct SteamLobbyId(ulong Value);
public ConnectCommand(string serverName, Endpoint endpoint)
: this(
NameAndP2PEndpointsOption: endpoint is P2PEndpoint p2pEndpoint
? Option.Some(new NameAndP2PEndpoints(ServerName: serverName, p2pEndpoint.ToEnumerable().ToImmutableArray()))
: Option.None,
NameAndLidgrenEndpointOption: endpoint is LidgrenEndpoint lidgrenEndpoint
? Option.Some(new NameAndLidgrenEndpoint(ServerName: serverName, lidgrenEndpoint))
: Option.None,
SteamLobbyIdOption: Option.None)
{ }
public ConnectCommand(string serverName, ImmutableArray<P2PEndpoint> endpoints)
: this(
NameAndP2PEndpointsOption: Option.Some(new NameAndP2PEndpoints(ServerName: serverName, Endpoints: endpoints)),
NameAndLidgrenEndpointOption: Option.None,
SteamLobbyIdOption: Option.None)
{ }
public ConnectCommand(string serverName, LidgrenEndpoint endpoint)
: this(
NameAndP2PEndpointsOption: Option.None,
NameAndLidgrenEndpointOption: Option.Some(new NameAndLidgrenEndpoint(ServerName: serverName, Endpoint: endpoint)),
SteamLobbyIdOption: Option.None)
{ }
public ConnectCommand(SteamLobbyId lobbyId)
: this(
NameAndP2PEndpointsOption: Option.None,
NameAndLidgrenEndpointOption: Option.None,
SteamLobbyIdOption: Option.Some(lobbyId))
{ }
public static Option<ConnectCommand> Parse(string str)
=> Parse(ToolBox.SplitCommand(str));
public static Option<ConnectCommand> Parse(IReadOnlyList<string>? args)
{
if (args == null || args.Count < 2) { return Option.None; }
if (args[0].Equals("-connect", StringComparison.OrdinalIgnoreCase))
{
if (args.Count < 3) { return Option.None; }
var serverName = args[1];
var endpointStrs = args[2].Split(",");
var endpoints = endpointStrs.Select(Endpoint.Parse).NotNone().ToImmutableArray();
if (endpoints.Length != endpointStrs.Length) { return Option.None; }
if (endpoints.All(e => e is P2PEndpoint))
{
return Option.Some(
new ConnectCommand(serverName, endpoints.Cast<P2PEndpoint>().ToImmutableArray()));
}
else if (endpoints.Length == 1 && endpoints[0] is LidgrenEndpoint lidgrenEndpoint)
{
return Option.Some(
new ConnectCommand(serverName, lidgrenEndpoint));
}
return Option.None;
}
else if (args[0].Equals("+connect_lobby", StringComparison.OrdinalIgnoreCase))
{
return UInt64.TryParse(args[1], out var lobbyId)
? Option.Some(new ConnectCommand(new SteamLobbyId(lobbyId)))
: Option.None;
}
return Option.None;
}
public override string ToString()
{
if (SteamLobbyIdOption.TryUnwrap(out var steamLobbyId))
{
return $"+connect_lobby {steamLobbyId.Value}";
}
if (NameAndP2PEndpointsOption.TryUnwrap(out var nameAndP2PEndpoints))
{
var escapedName = nameAndP2PEndpoints.ServerName.Replace("\"", "\\\"");
var escapedEndpoints = nameAndP2PEndpoints.Endpoints.Select(e => e.StringRepresentation).JoinEscaped(',');
return $"-connect \"{escapedName}\" {escapedEndpoints}";
}
if (NameAndLidgrenEndpointOption.TryUnwrap(out var nameAndLidgrenEndpoint))
{
var escapedName = nameAndLidgrenEndpoint.ServerName.Replace("\"", "\\\"");
var endpoint = nameAndLidgrenEndpoint.Endpoint.StringRepresentation;
return $"-connect \"{escapedName}\" {endpoint}";
}
return "";
}
}