From 85fab17d36795499b725802ae15bd0a74e9e59d4 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Fri, 31 Jan 2025 15:57:53 -0800 Subject: [PATCH 01/12] check launcher data dir --- MSBuild/Robust.Engine.Version.props | 10 ++++++---- Robust.Client/GameControllerOptions.cs | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/MSBuild/Robust.Engine.Version.props b/MSBuild/Robust.Engine.Version.props index 8724685672..862edc0c6f 100644 --- a/MSBuild/Robust.Engine.Version.props +++ b/MSBuild/Robust.Engine.Version.props @@ -1,4 +1,6 @@ - - - 240.1.2 - + + + + 0.0.1 + + diff --git a/Robust.Client/GameControllerOptions.cs b/Robust.Client/GameControllerOptions.cs index d386b39066..fdb0b2b2da 100644 --- a/Robust.Client/GameControllerOptions.cs +++ b/Robust.Client/GameControllerOptions.cs @@ -1,3 +1,4 @@ +using System; using Robust.Shared; using Robust.Shared.Utility; @@ -19,7 +20,7 @@ public sealed class GameControllerOptions /// /// Name the userdata directory will have. /// - public string UserDataDirectoryName { get; init; } = "Space Station 14"; + public string UserDataDirectoryName { get; init; } = Environment.GetEnvironmentVariable("SS14_LAUNCHER_DATADIR") ?? "SimpleStation14"; /// /// Name of the configuration file in the user data directory. From d418c66eb9fa139296513edff14068fed9c6d968 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sat, 22 Feb 2025 17:19:17 -0800 Subject: [PATCH 02/12] allow connecting with multiple of whitelisted auth servers --- .../Console/Commands/LauncherAuthCommand.cs | 51 ++++++++++++--- Robust.Shared/CVars.cs | 8 +-- Robust.Shared/Network/AuthManager.cs | 62 ++++++++++++++----- .../Messages/Handshake/MsgLoginStart.cs | 3 + .../Network/NetManager.ClientConnect.cs | 7 ++- .../Network/NetManager.ServerAuth.cs | 11 +++- 6 files changed, 109 insertions(+), 33 deletions(-) diff --git a/Robust.Client/Console/Commands/LauncherAuthCommand.cs b/Robust.Client/Console/Commands/LauncherAuthCommand.cs index 5fa5c51925..88c1fb1edb 100644 --- a/Robust.Client/Console/Commands/LauncherAuthCommand.cs +++ b/Robust.Client/Console/Commands/LauncherAuthCommand.cs @@ -5,6 +5,7 @@ using Robust.Client.Utility; using Robust.Shared.Console; using Robust.Shared.IoC; +using Robust.Shared.Log; using Robust.Shared.Network; namespace Robust.Client.Console.Commands @@ -15,31 +16,61 @@ internal sealed class LauncherAuthCommand : LocalizedCommands [Dependency] private readonly IGameControllerInternal _gameController = default!; public override string Command => "launchauth"; + public override string Help => "Usage: launchauth "; public override void Execute(IConsoleShell shell, string argStr, string[] args) { - var wantName = args.Length > 0 ? args[0] : null; + string? username = null; + string? serverId = null; + string? serverUrl = null; + if (args.Length > 0) + username = args[0]; + if (args.Length > 1) + serverId = args[1]; + if (args.Length > 2) + serverUrl = args[2]; var basePath = UserDataDir.GetRootUserDataDir(_gameController); var launcherDirName = Environment.GetEnvironmentVariable("SS14_LAUNCHER_APPDATA_NAME") ?? "launcher"; var dbPath = Path.Combine(basePath, launcherDirName, "settings.db"); -#if USE_SYSTEM_SQLITE - SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlite3()); -#endif + #if USE_SYSTEM_SQLITE + SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlite3()); + #endif using var con = new SqliteConnection($"Data Source={dbPath};Mode=ReadOnly"); con.Open(); using var cmd = con.CreateCommand(); - cmd.CommandText = "SELECT UserId, UserName, Token FROM Login WHERE Expires > datetime('NOW')"; + cmd.CommandText = "SELECT UserId, UserName, Token, Server, ServerUrl FROM Login WHERE Expires > datetime('NOW')"; - if (wantName != null) + if (username != null) { cmd.CommandText += " AND UserName = @userName"; - cmd.Parameters.AddWithValue("@userName", wantName); + cmd.Parameters.AddWithValue("@userName", username); } - cmd.CommandText += " LIMIT 1;"; + if (serverId != null) + { + cmd.CommandText += " AND Server = @serverId"; + cmd.Parameters.AddWithValue("@serverId", serverId); + if (serverId == IAuthManager.CustomServerId) + { + if (serverUrl == null) + { + shell.WriteLine("Custom server requires a URL"); + return; + } + cmd.CommandText += " AND ServerUrl = @serverUrl"; + cmd.Parameters.AddWithValue("@serverUrl", serverUrl); + } + else if (serverUrl != null) + { + shell.WriteLine("Server URL is only valid for custom servers"); + return; + } + } + + cmd.CommandText += " LIMIT 1;"; using var reader = cmd.ExecuteReader(); if (!reader.Read()) @@ -51,11 +82,13 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) var userId = Guid.Parse(reader.GetString(0)); var userName = reader.GetString(1); var token = reader.GetString(2); + serverUrl = reader.GetString(4); _auth.Token = token; _auth.UserId = new NetUserId(userId); + _auth.UserServer = new("unset", new(serverUrl)); - shell.WriteLine($"Logged into account {userName}"); + shell.WriteLine($"Logged into account {userName}@{reader.GetString(3)} ({serverUrl})"); } } } diff --git a/Robust.Shared/CVars.cs b/Robust.Shared/CVars.cs index 0a0f0d4fc5..8111a0ca18 100644 --- a/Robust.Shared/CVars.cs +++ b/Robust.Shared/CVars.cs @@ -942,12 +942,12 @@ protected CVars() public static readonly CVarDef AuthAllowLocal = CVarDef.Create("auth.allowlocal", true, CVar.SERVERONLY); - // Only respected on server, client goes through IAuthManager for security. /// - /// Authentication server address. + /// List of comma separated URLs to use as whitelisted authentication servers /// - public static readonly CVarDef AuthServer = - CVarDef.Create("auth.server", AuthManager.DefaultAuthServer, CVar.SERVERONLY); + /// "Space-Wizards:https://auth.spacestation14.com/,SimpleStation:https://auth.simplestation.org/" + public static readonly CVarDef AuthServers = + CVarDef.Create("auth.servers", AuthServer.ToStringList(AuthManager.DefaultAuthServers), CVar.SERVERONLY); /* * RENDERING diff --git a/Robust.Shared/Network/AuthManager.cs b/Robust.Shared/Network/AuthManager.cs index ea2250e891..e81c38d804 100644 --- a/Robust.Shared/Network/AuthManager.cs +++ b/Robust.Shared/Network/AuthManager.cs @@ -1,5 +1,9 @@ using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Robust.Shared.Serialization; + namespace Robust.Shared.Network { @@ -10,8 +14,11 @@ namespace Robust.Shared.Network /// internal interface IAuthManager { + public const string CustomServerId = "Custom"; + NetUserId? UserId { get; set; } - string? Server { get; set; } + AuthServer UserServer { get; set; } + HashSet Servers { get; set; } string? Token { get; set; } string? PubKey { get; set; } @@ -23,42 +30,67 @@ internal interface IAuthManager void LoadFromEnv(); } + public sealed class AuthServer(string id, Uri authUrl) + { + public string Id { get; } = id; + public Uri AuthUrl { get; } = authUrl; + + /// Returns a string representation of the auth server + /// "Space-Wizards:https://auth.spacestation14.com/" + public override string ToString() => $"{Id}:{AuthUrl}"; + + /// Returns a string representation of a list of auth servers + /// "Space-Wizards:https://auth.spacestation14.com/,SimpleStation:https://auth.simplestation.org/" + public static string ToStringList(HashSet servers) => string.Join(',', servers.Select(s => s.ToString())); + + /// Takes a representation of an auth server and returns an AuthServer object + /// "Space-Wizards:https://auth.spacestation14.com/" + public static AuthServer FromString(string str) + { + var parts = str.Split(':'); + if (parts.Length != 2) + throw new ArgumentException($"Invalid auth server string: {str}"); + + return new(parts[0], new(parts[1])); + } + + /// Takes a list of auth server representations and returns a HashSet of AuthServer objects + /// "Space-Wizards:https://auth.spacestation14.com/,SimpleStation:https://auth.simplestation.org/" + public static HashSet FromStringList(string str) => new(str.Split(',').Select(FromString)); + } + internal sealed class AuthManager : IAuthManager { - public const string DefaultAuthServer = "https://auth.spacestation14.com/"; + public static readonly AuthServer FallbackAuthServer = new("Space-Wizards", new("https://auth.spacestation14.com/")); + public static readonly HashSet DefaultAuthServers = new() + { + FallbackAuthServer, + new("SimpleStation", new("https://auth.simplestation.org/")), + }; public NetUserId? UserId { get; set; } - public string? Server { get; set; } = DefaultAuthServer; + public AuthServer UserServer { get; set; } = FallbackAuthServer; + public HashSet Servers { get; set; } = DefaultAuthServers; public string? Token { get; set; } public string? PubKey { get; set; } public bool AllowHwid { get; set; } = true; public void LoadFromEnv() { - if (TryGetVar("ROBUST_AUTH_SERVER", out var server)) - { - Server = server; - } + if (TryGetVar("ROBUST_AUTH_SERVERS", out var servers)) + Servers = AuthServer.FromStringList(servers); if (TryGetVar("ROBUST_AUTH_USERID", out var userId)) - { UserId = new NetUserId(Guid.Parse(userId)); - } if (TryGetVar("ROBUST_AUTH_PUBKEY", out var pubKey)) - { PubKey = pubKey; - } if (TryGetVar("ROBUST_AUTH_TOKEN", out var token)) - { Token = token; - } if (TryGetVar("ROBUST_AUTH_ALLOW_HWID", out var allowHwid)) - { AllowHwid = allowHwid.Trim() == "1"; - } static bool TryGetVar(string var, [NotNullWhen(true)] out string? val) { diff --git a/Robust.Shared/Network/Messages/Handshake/MsgLoginStart.cs b/Robust.Shared/Network/Messages/Handshake/MsgLoginStart.cs index ca8d39755f..a29bd20474 100644 --- a/Robust.Shared/Network/Messages/Handshake/MsgLoginStart.cs +++ b/Robust.Shared/Network/Messages/Handshake/MsgLoginStart.cs @@ -16,6 +16,7 @@ internal sealed class MsgLoginStart : NetMessage public override MsgGroups MsgGroup => MsgGroups.Core; public string UserName; + public string AuthServer; public bool CanAuth; public bool NeedPubKey; public bool Encrypt; @@ -23,6 +24,7 @@ internal sealed class MsgLoginStart : NetMessage public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer) { UserName = buffer.ReadString(); + AuthServer = buffer.ReadString(); CanAuth = buffer.ReadBoolean(); NeedPubKey = buffer.ReadBoolean(); Encrypt = buffer.ReadBoolean(); @@ -31,6 +33,7 @@ public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer) { buffer.Write(UserName); + buffer.Write(AuthServer); buffer.Write(CanAuth); buffer.Write(NeedPubKey); buffer.Write(Encrypt); diff --git a/Robust.Shared/Network/NetManager.ClientConnect.cs b/Robust.Shared/Network/NetManager.ClientConnect.cs index 7e8a4d3c9c..221343c58d 100644 --- a/Robust.Shared/Network/NetManager.ClientConnect.cs +++ b/Robust.Shared/Network/NetManager.ClientConnect.cs @@ -126,7 +126,7 @@ private async Task CCDoHandshake(NetPeerData peer, NetConnection connection, str var encrypt = _config.GetCVar(CVars.NetEncrypt); var authToken = _authManager.Token; var pubKey = _authManager.PubKey; - var authServer = _authManager.Server; + var authServer = _authManager.UserServer; var userId = _authManager.UserId; var hasPubKey = !string.IsNullOrEmpty(pubKey); @@ -137,9 +137,10 @@ private async Task CCDoHandshake(NetPeerData peer, NetConnection connection, str var msgLogin = new MsgLoginStart { UserName = userNameRequest, + AuthServer = authServer.AuthUrl.ToString(), CanAuth = authenticate, NeedPubKey = !hasPubKey, - Encrypt = encrypt + Encrypt = encrypt, }; var outLoginMsg = peer.Peer.CreateMessage(); @@ -199,7 +200,7 @@ private async Task CCDoHandshake(NetPeerData peer, NetConnection connection, str } var joinReq = new JoinRequest(authHash, Base64Helpers.ToBase64Nullable(modernHwid)); - var request = new HttpRequestMessage(HttpMethod.Post, authServer + "api/session/join"); + var request = new HttpRequestMessage(HttpMethod.Post, authServer.AuthUrl + "api/session/join"); request.Content = JsonContent.Create(joinReq); request.Headers.Authorization = new AuthenticationHeaderValue("SS14Auth", authToken); var joinResp = await _http.Client.SendAsync(request, cancel); diff --git a/Robust.Shared/Network/NetManager.ServerAuth.cs b/Robust.Shared/Network/NetManager.ServerAuth.cs index a8eda20dc8..14c8d1db47 100644 --- a/Robust.Shared/Network/NetManager.ServerAuth.cs +++ b/Robust.Shared/Network/NetManager.ServerAuth.cs @@ -50,11 +50,11 @@ private async void HandleHandshake(NetPeerData peer, NetConnection connection) var isLocal = IPAddress.IsLoopback(ip) && _config.GetCVar(CVars.AuthAllowLocal); var canAuth = msgLogin.CanAuth; var needPk = msgLogin.NeedPubKey; - var authServer = _config.GetCVar(CVars.AuthServer); + var authServer = msgLogin.AuthServer; _logger.Verbose( $"{connection.RemoteEndPoint}: Received MsgLoginStart. " + - $"canAuth: {canAuth}, needPk: {needPk}, username: {msgLogin.UserName}, encrypt: {msgLogin.Encrypt}"); + $"canAuth: {canAuth}, needPk: {needPk}, username: {msgLogin.UserName}, auth server: {msgLogin.AuthServer}, encrypt: {msgLogin.Encrypt}"); _logger.Verbose( $"{connection.RemoteEndPoint}: Connection is specialized local? {isLocal} "); @@ -78,6 +78,13 @@ private async void HandleHandshake(NetPeerData peer, NetConnection connection) _logger.Verbose( $"{connection.RemoteEndPoint}: Initiating authentication"); + var servers = _authManager.Servers.Select(s => s.AuthUrl.ToString()).ToArray(); + if (!servers.Contains(authServer)) + { + connection.Disconnect($"Invalid or disallowed auth server {authServer}, needs to be one of {string.Join(", ", servers)}"); + return; + } + var verifyToken = new byte[4]; RandomNumberGenerator.Fill(verifyToken); var wantHwid = _config.GetCVar(CVars.NetHWId); From 92d34700f5621fe3fedc0996c18f5da066e931c5 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sat, 22 Feb 2025 18:31:56 -0800 Subject: [PATCH 03/12] readme --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a8d9fc8c08..20410395f2 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,10 @@ -![Robust Toolbox](https://raw.githubusercontent.com/space-wizards/asset-dump/3dd3078e49e3a7e06709a6e0fc6e3223d8d44ca2/robust.png) +Supermatter Engine is a game engine primarily being developed for [Space Station 14](https://github.com/Simple-Station/Einstein-Engines). -Robust Toolbox is an engine primarily being developed for [Space Station 14](https://github.com/space-wizards/space-station-14), although we're working on making it usable for both [singleplayer](https://github.com/space-wizards/RobustToolboxTemplateSingleplayer) and [multiplayer](https://github.com/space-wizards/RobustToolboxTemplate) projects. - -Use the [content repo](https://github.com/space-wizards/space-station-14) for actual development, even if you're modifying the engine itself. +Use the [content repo](https://github.com/Simple-Station/Einstein-Engines) for actual development, even if you're modifying the engine itself. ## Project Links -[Website](https://spacestation14.io/) | [Discord](https://discord.gg/t2jac3p) | [Forum](https://forum.spacestation14.io/) | [Steam](https://store.steampowered.com/app/1255460/Space_Station_14/) | [Standalone Download](https://spacestation14.io/about/nightlies/) +[Website](https://simplestation.org/) | [Discord](https://discord.gg/X4QEXxUrsJ) | [Steam](https://store.steampowered.com/app/1255460/Space_Station_14/) | [Standalone Download](https://spacestation14.io/about/nightlies/) ## Documentation/Wiki @@ -14,12 +12,12 @@ The [wiki](https://docs.spacestation14.io/) has documentation on SS14s content, ## Contributing -We are happy to accept contributions from anybody. Get in Discord or IRC if you want to help. We've got a [list of issues](https://github.com/space-wizards/RobustToolbox/issues) that need to be done and anybody can pick them up. Don't be afraid to ask for help either! +We are happy to accept contributions from anybody. It is recommended to join our Discord if you want to help. We've got a [list of issues](https://github.com/Simple-Station/SupermatterEngine/issues) that need to be done and anybody can pick them up. Don't be afraid to ask for help either! ## Building -This repository is the **engine** part of SS14. It's the base engine all SS14 servers will be built on. As such, it does not start on its own: it needs the [content repo](https://github.com/space-wizards/space-station-14). Think of Robust Toolbox as BYOND in the context of Space Station 13. +This repository is the **engine** part of SS14. It's an engine SS14 servers are built on. As such, it does not start on its own: it needs the [content repo](https://github.com/Simple-Station/Einstein-Engines). Think of SME as BYOND in the context of Space Station 13. ## Legal Info -See [legal.md](https://github.com/space-wizards/RobustToolbox/blob/master/legal.md) for licenses and copyright. +See [legal.md](https://github.com/Simple-Station/SupermatterEngine/blob/master/legal.md) for licenses and copyright. From 284c897d4daa18652b687ed032dc98b84285d86f Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sat, 5 Apr 2025 16:07:37 -0700 Subject: [PATCH 04/12] fix server string rep, replicate auth servers, etc --- Robust.Shared/CVars.cs | 2 +- Robust.Shared/Network/AuthManager.cs | 21 +++++++++++++------ .../Messages/Handshake/MsgLoginSuccess.cs | 4 +++- .../Network/NetManager.ServerAuth.cs | 4 ++-- Robust.Shared/Network/NetUserData.cs | 17 ++++----------- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/Robust.Shared/CVars.cs b/Robust.Shared/CVars.cs index 27df1fd757..b19373bb76 100644 --- a/Robust.Shared/CVars.cs +++ b/Robust.Shared/CVars.cs @@ -947,7 +947,7 @@ protected CVars() /// /// "Space-Wizards:https://auth.spacestation14.com/,SimpleStation:https://auth.simplestation.org/" public static readonly CVarDef AuthServers = - CVarDef.Create("auth.servers", AuthServer.ToStringList(AuthManager.DefaultAuthServers), CVar.SERVERONLY); + CVarDef.Create("auth.servers", AuthServer.ToStringList(AuthManager.DefaultAuthServers), CVar.REPLICATED); /* * RENDERING diff --git a/Robust.Shared/Network/AuthManager.cs b/Robust.Shared/Network/AuthManager.cs index e81c38d804..0bcc90fe77 100644 --- a/Robust.Shared/Network/AuthManager.cs +++ b/Robust.Shared/Network/AuthManager.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Robust.Shared.Configuration; using Robust.Shared.Serialization; @@ -15,6 +16,7 @@ namespace Robust.Shared.Network internal interface IAuthManager { public const string CustomServerId = "Custom"; + public const string DefaultServerUrl = "https://auth.spacestation14.com/"; NetUserId? UserId { get; set; } AuthServer UserServer { get; set; } @@ -36,18 +38,19 @@ public sealed class AuthServer(string id, Uri authUrl) public Uri AuthUrl { get; } = authUrl; /// Returns a string representation of the auth server - /// "Space-Wizards:https://auth.spacestation14.com/" - public override string ToString() => $"{Id}:{AuthUrl}"; + /// "Space-Wizards@https://auth.spacestation14.com/" + public override string ToString() => $"{Id}@{AuthUrl}"; + /// Returns a string representation of a list of auth servers - /// "Space-Wizards:https://auth.spacestation14.com/,SimpleStation:https://auth.simplestation.org/" + /// "Space-Wizards@https://auth.spacestation14.com/,SimpleStation@https://auth.simplestation.org/" public static string ToStringList(HashSet servers) => string.Join(',', servers.Select(s => s.ToString())); /// Takes a representation of an auth server and returns an AuthServer object - /// "Space-Wizards:https://auth.spacestation14.com/" + /// "Space-Wizards@https://auth.spacestation14.com/" public static AuthServer FromString(string str) { - var parts = str.Split(':'); + var parts = str.Split('@'); if (parts.Length != 2) throw new ArgumentException($"Invalid auth server string: {str}"); @@ -55,8 +58,14 @@ public static AuthServer FromString(string str) } /// Takes a list of auth server representations and returns a HashSet of AuthServer objects - /// "Space-Wizards:https://auth.spacestation14.com/,SimpleStation:https://auth.simplestation.org/" + /// "Space-Wizards@https://auth.spacestation14.com/,SimpleStation@https://auth.simplestation.org/" public static HashSet FromStringList(string str) => new(str.Split(',').Select(FromString)); + + public static HashSet FromCVarList(IConfigurationManager config) => FromStringList(config.GetCVar(CVars.AuthServers)); + + public static AuthServer? GetServerFromCVarListById(IConfigurationManager config, string id) => FromCVarList(config).FirstOrDefault(s => s.Id == id); + public static AuthServer? GetServerFromCVarListByUrl(IConfigurationManager config, Uri url) => FromCVarList(config).FirstOrDefault(s => s.AuthUrl == url); + public static AuthServer? GetServerFromCVarListByUrl(IConfigurationManager config, string url) => FromCVarList(config).FirstOrDefault(s => s.AuthUrl.ToString() == url); } internal sealed class AuthManager : IAuthManager diff --git a/Robust.Shared/Network/Messages/Handshake/MsgLoginSuccess.cs b/Robust.Shared/Network/Messages/Handshake/MsgLoginSuccess.cs index 81a185e995..d815a56331 100644 --- a/Robust.Shared/Network/Messages/Handshake/MsgLoginSuccess.cs +++ b/Robust.Shared/Network/Messages/Handshake/MsgLoginSuccess.cs @@ -19,11 +19,12 @@ public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer { var name = buffer.ReadString(); var id = buffer.ReadGuid(); + var authServer = buffer.ReadString(); var patreonTier = buffer.ReadString(); if (patreonTier.Length == 0) patreonTier = null; - UserData = new NetUserData(new NetUserId(id), name) {PatronTier = patreonTier}; + UserData = new(new(id), name, authServer) {PatronTier = patreonTier}; Type = (LoginType) buffer.ReadByte(); } @@ -31,6 +32,7 @@ public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer { buffer.Write(UserData.UserName); buffer.Write(UserData.UserId); + buffer.Write(UserData.AuthServer); buffer.Write(UserData.PatronTier); buffer.Write((byte) Type); buffer.Write(new byte[100]); diff --git a/Robust.Shared/Network/NetManager.ServerAuth.cs b/Robust.Shared/Network/NetManager.ServerAuth.cs index 14c8d1db47..687fa46145 100644 --- a/Robust.Shared/Network/NetManager.ServerAuth.cs +++ b/Robust.Shared/Network/NetManager.ServerAuth.cs @@ -175,7 +175,7 @@ private async void HandleHandshake(NetPeerData peer, NetConnection connection) legacyHwid = []; } - userData = new NetUserData(userId, joinedRespJson.UserData.UserName) + userData = new(userId, joinedRespJson.UserData.UserName, authServer) { PatronTier = joinedRespJson.UserData.PatronTier, HWId = legacyHwid, @@ -221,7 +221,7 @@ private async void HandleHandshake(NetPeerData peer, NetConnection connection) _logger.Verbose( $"{connection.RemoteEndPoint}: Assigned user ID: {userId}"); - userData = new NetUserData(userId, name) + userData = new(userId, name, authServer) { HWId = [], ModernHWIds = [] diff --git a/Robust.Shared/Network/NetUserData.cs b/Robust.Shared/Network/NetUserData.cs index 428ea3d96a..a76ea17aef 100644 --- a/Robust.Shared/Network/NetUserData.cs +++ b/Robust.Shared/Network/NetUserData.cs @@ -7,14 +7,11 @@ namespace Robust.Shared.Network /// /// Contains data about players returned from auth server. /// - public sealed record NetUserData + public sealed record NetUserData( + [property: ViewVariables] NetUserId UserId, + [property: ViewVariables] string UserName, + [property: ViewVariables] string AuthServer = IAuthManager.DefaultServerUrl) { - [ViewVariables] - public NetUserId UserId { get; } - - [ViewVariables] - public string UserName { get; } - [ViewVariables] public string? PatronTier { get; init; } @@ -37,12 +34,6 @@ public sealed record NetUserData /// public float Trust { get; init; } - public NetUserData(NetUserId userId, string userName) - { - UserId = userId; - UserName = userName; - } - public sealed override string ToString() { var stringBuilder = new StringBuilder(); From 0afd1777aff66f327bf4fefb7c22574ca7d12333 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sat, 5 Apr 2025 16:24:57 -0700 Subject: [PATCH 05/12] add auth server to listplayers --- Robust.Server/Console/Commands/PlayerCommands.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Robust.Server/Console/Commands/PlayerCommands.cs b/Robust.Server/Console/Commands/PlayerCommands.cs index 6f504d844b..f13e8193d8 100644 --- a/Robust.Server/Console/Commands/PlayerCommands.cs +++ b/Robust.Server/Console/Commands/PlayerCommands.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Text; using Robust.Server.Player; +using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.IoC; using Robust.Shared.Network; @@ -11,6 +12,7 @@ namespace Robust.Server.Console.Commands public sealed class ListPlayers : LocalizedCommands { [Dependency] private readonly IPlayerManager _players = default!; + [Dependency] private readonly IConfigurationManager _config = default!; public override string Command => "listplayers"; public override void Execute(IConsoleShell shell, string argStr, string[] args) @@ -22,17 +24,18 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) var sb = new StringBuilder(); var players = _players.Sessions; - sb.AppendLine($"{"Player Name",20} {"Status",12} {"Playing Time",14} {"Ping",9} {"IP EndPoint",20}"); - sb.AppendLine("-------------------------------------------------------------------------------"); + sb.AppendLine($"{"Player Name",20} {"Auth Server",16} {"Status",12} {"Playing Time",14} {"Ping",9} {"IP EndPoint",20}"); + sb.AppendLine("-------------------------------------------------------------------------------------------------"); foreach (var p in players) { - sb.AppendLine(string.Format("{4,20} {1,12} {2,14:hh\\:mm\\:ss} {3,9} {0,20}", - p.Channel.RemoteEndPoint, + sb.AppendLine(string.Format("{0,20} {1,16} {2,12} {3,14:hh\\:mm\\:ss} {4,9} {5,20}", + p.Name, + AuthServer.GetServerFromCVarListByUrl(_config, p.Channel.UserData.AuthServer)?.Id, p.Status.ToString(), DateTime.UtcNow - p.ConnectedTime, p.Channel.Ping + "ms", - p.Name)); + p.Channel.RemoteEndPoint)); } shell.WriteLine(sb.ToString()); From 143501f0a8429c21200f7047c043ddf64c5b77fb Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Thu, 10 Jul 2025 14:46:35 -0700 Subject: [PATCH 06/12] advertise auths --- Robust.Server/ServerStatus/StatusHost.Handlers.cs | 8 +++++++- Robust.Shared/CVars.cs | 6 ++++++ Robust.Shared/Utility/GameBuildInformation.cs | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Robust.Server/ServerStatus/StatusHost.Handlers.cs b/Robust.Server/ServerStatus/StatusHost.Handlers.cs index 5641586cb0..cc1718c221 100644 --- a/Robust.Server/ServerStatus/StatusHost.Handlers.cs +++ b/Robust.Server/ServerStatus/StatusHost.Handlers.cs @@ -39,13 +39,17 @@ private async Task HandleStatus(IStatusHandlerContext context) return false; } + var buildInfo = GameBuildInformation.GetBuildInfoFromConfig(_cfg); + var jObject = new JsonObject { // We need to send at LEAST name and player count to have the launcher work with us. // Tags is optional technically but will be necessary practically for future organization. // Content can override these if it wants (e.g. stealthmins). ["name"] = _serverNameCache, - ["players"] = _playerManager.PlayerCount + ["players"] = _playerManager.PlayerCount, + ["engine_type"] = buildInfo.EngineType, + ["engine"] = buildInfo.EngineVersion, }; var tagsCache = _serverTagsCache; @@ -132,6 +136,7 @@ private JsonObject GetExternalBuildInfo() return new JsonObject { + ["engine_type"] = buildInfo.EngineType, ["engine_version"] = buildInfo.EngineVersion, ["fork_id"] = buildInfo.ForkId, ["version"] = buildInfo.Version, @@ -158,6 +163,7 @@ private JsonObject GetExternalBuildInfo() } return new JsonObject { + ["engine_type"] = _cfg.GetCVar(CVars.BuildEngineType), ["engine_version"] = _cfg.GetCVar(CVars.BuildEngineVersion), ["fork_id"] = fork, ["version"] = acm.ManifestHash, diff --git a/Robust.Shared/CVars.cs b/Robust.Shared/CVars.cs index b19373bb76..a3d384dc11 100644 --- a/Robust.Shared/CVars.cs +++ b/Robust.Shared/CVars.cs @@ -669,6 +669,12 @@ protected CVars() * BUILD */ + /// + /// Engine type the launcher needs to connect to this server. + /// + public static readonly CVarDef BuildEngineType = + CVarDef.Create("build.engine_type", "Supermatter"); + /// /// Engine version that launcher needs to connect to this server. /// diff --git a/Robust.Shared/Utility/GameBuildInformation.cs b/Robust.Shared/Utility/GameBuildInformation.cs index cd533b1cad..4bf766302d 100644 --- a/Robust.Shared/Utility/GameBuildInformation.cs +++ b/Robust.Shared/Utility/GameBuildInformation.cs @@ -7,6 +7,7 @@ internal sealed record GameBuildInformation( string? ZipHash, string? ZipDownload, string ForkId, + string EngineType, string Version, string? ManifestHash, string? ManifestUrl, @@ -18,6 +19,7 @@ public static GameBuildInformation GetBuildInfoFromConfig(IConfigurationManager var zipHash = cfg.GetCVar(CVars.BuildHash); var manifestHash = cfg.GetCVar(CVars.BuildManifestHash); var forkId = cfg.GetCVar(CVars.BuildForkId); + var engineType = cfg.GetCVar(CVars.BuildEngineType); var forkVersion = cfg.GetCVar(CVars.BuildVersion); var manifestDownloadUrl = Interpolate(cfg.GetCVar(CVars.BuildManifestDownloadUrl)); @@ -44,6 +46,7 @@ public static GameBuildInformation GetBuildInfoFromConfig(IConfigurationManager zipHash, zipDownload, forkId, + engineType, forkVersion, manifestHash, manifestUrl, From 28eb8c868db241aa03cc225b411fa442318e687e Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Thu, 10 Jul 2025 16:39:26 -0700 Subject: [PATCH 07/12] actually advertise auths the last was engine version --- .../ServerStatus/StatusHost.Handlers.cs | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/Robust.Server/ServerStatus/StatusHost.Handlers.cs b/Robust.Server/ServerStatus/StatusHost.Handlers.cs index cc1718c221..acf761dce9 100644 --- a/Robust.Server/ServerStatus/StatusHost.Handlers.cs +++ b/Robust.Server/ServerStatus/StatusHost.Handlers.cs @@ -5,6 +5,7 @@ using System.Text.Json.Nodes; using System.Web; using Robust.Shared; +using Robust.Shared.Network; using Robust.Shared.Utility; namespace Robust.Server.ServerStatus @@ -52,16 +53,16 @@ private async Task HandleStatus(IStatusHandlerContext context) ["engine"] = buildInfo.EngineVersion, }; - var tagsCache = _serverTagsCache; - if (tagsCache != null) - { - var tags = new JsonArray(); - foreach (var tag in tagsCache) - { - tags.Add(tag); - } - jObject["tags"] = tags; - } + var tags = new JsonArray(); + foreach (var tag in _serverTagsCache) + tags.Add(tag); + jObject["tags"] = tags; + + // Can't cast :( + var auths = new JsonArray(); + foreach (var auth in AuthServer.FromCVarList(_cfg).Select(s => s.AuthUrl.AbsoluteUri)) + auths.Add(auth); + jObject["auth_methods"] = auths; OnStatusRequest?.Invoke(jObject); @@ -91,12 +92,16 @@ private async Task HandleInfo(IStatusHandlerContext context) buildInfo = GetExternalBuildInfo(); } + var logins = new JsonArray(); + foreach (var authServer in AuthServer.FromCVarList(_cfg)) + logins.Add(authServer.AuthUrl); var authInfo = new JsonObject { ["mode"] = _netManager.Auth.ToString(), ["public_key"] = _netManager.CryptoPublicKey != null ? Convert.ToBase64String(_netManager.CryptoPublicKey) - : null + : null, + ["login_urls"] = logins, }; var jObject = new JsonObject From 196ac47f567fd6baf0d607dc9d56f14d73ca853e Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Fri, 11 Jul 2025 00:27:42 -0700 Subject: [PATCH 08/12] fixed it fixed it fixed it fixed it fixed it fixed it fixed it fixed it fixed it EIGHT HOURS --- Robust.Server/Console/Commands/PlayerCommands.cs | 6 +++--- Robust.Shared/Network/AuthManager.cs | 4 +++- Tools/package_client_build.py | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Robust.Server/Console/Commands/PlayerCommands.cs b/Robust.Server/Console/Commands/PlayerCommands.cs index f13e8193d8..623cdec53b 100644 --- a/Robust.Server/Console/Commands/PlayerCommands.cs +++ b/Robust.Server/Console/Commands/PlayerCommands.cs @@ -24,12 +24,12 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) var sb = new StringBuilder(); var players = _players.Sessions; - sb.AppendLine($"{"Player Name",20} {"Auth Server",16} {"Status",12} {"Playing Time",14} {"Ping",9} {"IP EndPoint",20}"); - sb.AppendLine("-------------------------------------------------------------------------------------------------"); + sb.AppendLine($"{"Player Name",26} {"Auth Server",16} {"Status",12} {"Playing Time",14} {"Ping",9} {"IP EndPoint",20}"); + sb.AppendLine(new('-', 26 + 16 + 12 + 14 + 9 + 20)); foreach (var p in players) { - sb.AppendLine(string.Format("{0,20} {1,16} {2,12} {3,14:hh\\:mm\\:ss} {4,9} {5,20}", + sb.AppendLine(string.Format("{0,26} {1,16} {2,12} {3,14:hh\\:mm\\:ss} {4,9} {5,20}", p.Name, AuthServer.GetServerFromCVarListByUrl(_config, p.Channel.UserData.AuthServer)?.Id, p.Status.ToString(), diff --git a/Robust.Shared/Network/AuthManager.cs b/Robust.Shared/Network/AuthManager.cs index 0bcc90fe77..7a1c1c5888 100644 --- a/Robust.Shared/Network/AuthManager.cs +++ b/Robust.Shared/Network/AuthManager.cs @@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Robust.Shared.Configuration; -using Robust.Shared.Serialization; namespace Robust.Shared.Network @@ -86,6 +85,9 @@ internal sealed class AuthManager : IAuthManager public void LoadFromEnv() { + if (TryGetVar("ROBUST_AUTH_SERVER", out var server)) + UserServer = AuthServer.FromString("unset@" + server); + if (TryGetVar("ROBUST_AUTH_SERVERS", out var servers)) Servers = AuthServer.FromStringList(servers); diff --git a/Tools/package_client_build.py b/Tools/package_client_build.py index 8acea51266..c58935d43a 100755 --- a/Tools/package_client_build.py +++ b/Tools/package_client_build.py @@ -196,7 +196,7 @@ def build_linux(skip_build: bool, platform, name) -> None: client_zip = zipfile.ZipFile( p("release", "Robust.Client_%s.zip" % rid), "w", - compression=zipfile.ZIP_DEFLATED) + compression=zipfile.ZIP_DEFLATED, strict_timestamps=False) copy_dir_into_zip(p("bin", "Client", rid, "publish"), "", client_zip, IGNORED_FILES_LINUX) copy_resources("Resources", client_zip) From 16cbf2ac3bcb72c11338eca3967a371c42a06695 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Mon, 14 Jul 2025 14:39:32 -0700 Subject: [PATCH 09/12] b --- Robust.Shared/CVars.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Robust.Shared/CVars.cs b/Robust.Shared/CVars.cs index cff0a9b6bc..c673b8f3c3 100644 --- a/Robust.Shared/CVars.cs +++ b/Robust.Shared/CVars.cs @@ -951,7 +951,7 @@ protected CVars() /// /// List of comma separated URLs to use as whitelisted authentication servers /// - /// "Space-Wizards:https://auth.spacestation14.com/,SimpleStation:https://auth.simplestation.org/" + /// "Space-Wizards@https://auth.spacestation14.com/,SimpleStation@https://auth.simplestation.org/" public static readonly CVarDef AuthServers = CVarDef.Create("auth.servers", AuthServer.ToStringList(AuthManager.DefaultAuthServers), CVar.REPLICATED); From ed399701468531a1365cec10175ee28558990a50 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sat, 29 Nov 2025 23:32:51 -0800 Subject: [PATCH 10/12] Version: 0.1.0 --- MSBuild/Robust.Engine.Version.props | 6 ++---- RELEASE-NOTES.md | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/MSBuild/Robust.Engine.Version.props b/MSBuild/Robust.Engine.Version.props index 862edc0c6f..8d3e53592c 100644 --- a/MSBuild/Robust.Engine.Version.props +++ b/MSBuild/Robust.Engine.Version.props @@ -1,6 +1,4 @@ - - - 0.0.1 - + + 0.1.0 diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 609dafe116..9c1c0481bd 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -54,6 +54,9 @@ END TEMPLATE--> *None yet* +## 0.1.0 + + ## 260.2.0 ### New features From b45e475fe0a1e16a516c98c60c30d54f8815cd1b Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sat, 29 Nov 2025 23:34:01 -0800 Subject: [PATCH 11/12] Version: 0.1.0 --- RELEASE-NOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 9c1c0481bd..9b455be845 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -57,6 +57,9 @@ END TEMPLATE--> ## 0.1.0 +## 0.1.0 + + ## 260.2.0 ### New features From d931eeb0f12dd9c4ab989980f729ddccb5365ee5 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Sat, 29 Nov 2025 23:39:47 -0800 Subject: [PATCH 12/12] Version: 0.2.0 --- MSBuild/Robust.Engine.Version.props | 2 +- RELEASE-NOTES.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/MSBuild/Robust.Engine.Version.props b/MSBuild/Robust.Engine.Version.props index 8d3e53592c..affd67b860 100644 --- a/MSBuild/Robust.Engine.Version.props +++ b/MSBuild/Robust.Engine.Version.props @@ -1,4 +1,4 @@ - 0.1.0 + 0.2.0 diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 9b455be845..39b0727d6a 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -54,6 +54,9 @@ END TEMPLATE--> *None yet* +## 0.2.0 + + ## 0.1.0