From a3fcea242ae7d76397ffd26e38a242288e178ab3 Mon Sep 17 00:00:00 2001
From: Checkraze <71046427+Cheackraze@users.noreply.github.com>
Date: Mon, 3 Jun 2024 17:32:14 -0400
Subject: [PATCH] cleanup
---
Content.Server/Administration/ServerApi.cs | 2 +-
.../Connection/ConnectionManager.cs | 3 ++
Content.Server/_NF/Auth/Auth.cs | 48 ++++++++++---------
3 files changed, 29 insertions(+), 24 deletions(-)
diff --git a/Content.Server/Administration/ServerApi.cs b/Content.Server/Administration/ServerApi.cs
index ae9cf27d6b7..2f7bcbe48e2 100644
--- a/Content.Server/Administration/ServerApi.cs
+++ b/Content.Server/Administration/ServerApi.cs
@@ -666,7 +666,7 @@ private enum ErrorCode
///
/// Record used to send the response for the info endpoint.
///
- public sealed class InfoResponse //frontier - public to maybe reuse
+ private sealed class InfoResponse
{
public required int RoundId { get; init; }
public required List Players { get; init; }
diff --git a/Content.Server/Connection/ConnectionManager.cs b/Content.Server/Connection/ConnectionManager.cs
index 05e32a7fa74..e14f5106512 100644
--- a/Content.Server/Connection/ConnectionManager.cs
+++ b/Content.Server/Connection/ConnectionManager.cs
@@ -234,6 +234,9 @@ private async Task NetMgrOnConnecting(NetConnectingArgs e)
}
//Frontier
+ //This is our little chunk that serves as a dAuth. It takes in a comma seperated list of IP:PORT, and chekcs
+ //the requesting player against the list of players logged in to other servers. It is intended to be failsafe.
+ //In the case of Admins, it shares the same bypass setting as the soft_max_player_limit
if (!_cfg.GetCVar(CCVars.AllowMultiConnect) && !adminBypass)
{
var serverListString = _cfg.GetCVar(CCVars.ServerAuthList);
diff --git a/Content.Server/_NF/Auth/Auth.cs b/Content.Server/_NF/Auth/Auth.cs
index 21e04940160..6bb26df02bb 100644
--- a/Content.Server/_NF/Auth/Auth.cs
+++ b/Content.Server/_NF/Auth/Auth.cs
@@ -1,15 +1,12 @@
-using System.Collections.Immutable;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Json;
-//using System.IO;
using System.Net.Http.Headers;
-using System.Text.Json;
using Content.Shared.CCVar;
-using JetBrains.Annotations;
using Robust.Shared.Configuration;
+using JetBrains.Annotations;
namespace Content.Server._NF.Auth;
@@ -19,20 +16,22 @@ public sealed class MiniAuthManager
private readonly HttpClient _http = new();
private readonly ISawmill _sawmill = default!;
+ ///
+ /// Frontier function to ping a server and check to see if the given player is currently connected to the given server.
+ /// Servers using this function must share an admin_api token as defined in their respective server_config.toml
+ ///
+ /// The address of the server to ping.
+ /// the GUID of the player to check for connection.
+ /// True if the response from the server is successful and the player is connected. False in any case of error, timeout, or failure.
public async Task IsPlayerConnected(string address, Guid player)
{
var connected = false;
var statusAddress = "http://" + address + "/admin/info";
var cancel = new CancellationToken();
-
var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancel);
linkedToken.CancelAfter(TimeSpan.FromSeconds(10));
- var actor = new Actor()
- {
- Guid = player,
- Name = player.ToString()
- };
+
_http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("SS14Token", _cfg.GetCVar(CCVars.AdminApiToken));
using var response = await _http.GetAsync(statusAddress, linkedToken.Token);
@@ -41,25 +40,35 @@ public async Task IsPlayerConnected(string address, Guid player)
if (response.IsSuccessStatusCode)
{
- var status = await response.Content.ReadFromJsonAsync(linkedToken.Token);
- foreach (var connectedPlayer in status!.Players)
+ //We need to do a try catch here because theres essentially no way to guarantee our json response is proper.
+ //Throughout all of this, we want it to fail to deny, not fail to allow, so if any step of our auth goes wrong,
+ //people can still connect.
+ try
{
- if (connectedPlayer.UserId == player)
- connected = true;
+ var status = await response.Content.ReadFromJsonAsync(linkedToken.Token);
+ foreach (var connectedPlayer in status!.Players)
+ {
+ if (connectedPlayer.UserId == player)
+ connected = true;
+ }
+ }
+ catch (Exception)
+ {
+ _sawmill.Error("Bad data received from auth server", response.StatusCode);
}
}
else
{
_sawmill.Error("Auth server returned bad response {StatusCode}!", response.StatusCode);
}
- //var status = await _http.GetFromJsonAsync(statusAddress, linkedToken.Token);
return connected;
}
///
/// Record used to send the response for the info endpoint.
+ /// Frontier - This is a direct copy of ServerAPI.InfoResponse to match the json format. they kept it private so i just copied it
///
[UsedImplicitly]
- private sealed record InfoResponse //frontier - public to maybe reuse
+ private sealed record InfoResponse
{
public required int RoundId { get; init; }
public required List Players { get; init; }
@@ -83,11 +92,4 @@ public sealed class MapInfo
public required string Name { get; init; }
}
}
-
- private sealed class Actor
- {
- public required Guid Guid { get; init; }
- public required string Name { get; init; }
- }
-
}