Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions MSBuild/Robust.Engine.Version.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<!-- This file automatically reset by Tools/version.py -->
<PropertyGroup><Version>260.2.0</Version></PropertyGroup>
</Project>
<Project>
<!-- This file automatically reset by Tools/version.py -->
<PropertyGroup><Version>0.2.0</Version></PropertyGroup>
</Project>
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
![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

The [wiki](https://docs.spacestation14.io/) has documentation on SS14s content, engine, game design and more. We also have lots of resources for new contributors to the project.

## 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.
9 changes: 9 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ END TEMPLATE-->
*None yet*


## 0.2.0


## 0.1.0


## 0.1.0


## 260.2.0

### New features
Expand Down
51 changes: 42 additions & 9 deletions Robust.Client/Console/Commands/LauncherAuthCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 <optional username> <optional server id> <optional server url>";

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())
Expand All @@ -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);

Comment on lines 82 to 86
Copy link

Copilot AI Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding the column index when retrieving the serverUrl makes the code fragile if the query order ever changes. Consider using named columns or defined constants to ensure the correct value is extracted even if the SQL query is updated.

Suggested change
var userId = Guid.Parse(reader.GetString(0));
var userName = reader.GetString(1);
var token = reader.GetString(2);
serverUrl = reader.GetString(4);
var userId = Guid.Parse(reader.GetString(reader.GetOrdinal("UserId")));
var userName = reader.GetString(reader.GetOrdinal("UserName"));
var token = reader.GetString(reader.GetOrdinal("Token"));
serverUrl = reader.GetString(reader.GetOrdinal("ServerUrl"));

Copilot uses AI. Check for mistakes.
_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})");
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion Robust.Client/GameControllerOptions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using Robust.Shared;
using Robust.Shared.Utility;

Expand All @@ -19,7 +20,7 @@ public sealed class GameControllerOptions
/// <summary>
/// Name the userdata directory will have.
/// </summary>
public string UserDataDirectoryName { get; init; } = "Space Station 14";
public string UserDataDirectoryName { get; init; } = Environment.GetEnvironmentVariable("SS14_LAUNCHER_DATADIR") ?? "SimpleStation14";

/// <summary>
/// Name of the configuration file in the user data directory.
Expand Down
13 changes: 8 additions & 5 deletions Robust.Server/Console/Commands/PlayerCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -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",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("{4,20} {1,12} {2,14:hh\\:mm\\:ss} {3,9} {0,20}",
p.Channel.RemoteEndPoint,
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(),
DateTime.UtcNow - p.ConnectedTime,
p.Channel.Ping + "ms",
p.Name));
p.Channel.RemoteEndPoint));
}

shell.WriteLine(sb.ToString());
Expand Down
35 changes: 23 additions & 12 deletions Robust.Server/ServerStatus/StatusHost.Handlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -39,25 +40,29 @@ private async Task<bool> 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;
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);

Expand Down Expand Up @@ -88,12 +93,16 @@ private async Task<bool> 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
Expand Down Expand Up @@ -134,6 +143,7 @@ private JsonObject GetExternalBuildInfo()

return new JsonObject
{
["engine_type"] = buildInfo.EngineType,
["engine_version"] = buildInfo.EngineVersion,
["fork_id"] = buildInfo.ForkId,
["version"] = buildInfo.Version,
Expand All @@ -160,6 +170,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,
Expand Down
14 changes: 10 additions & 4 deletions Robust.Shared/CVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,12 @@ protected CVars()
* BUILD
*/

/// <summary>
/// Engine type the launcher needs to connect to this server.
/// </summary>
public static readonly CVarDef<string> BuildEngineType =
CVarDef.Create("build.engine_type", "Supermatter");

/// <summary>
/// Engine version that launcher needs to connect to this server.
/// </summary>
Expand Down Expand Up @@ -942,12 +948,12 @@ protected CVars()
public static readonly CVarDef<bool> AuthAllowLocal =
CVarDef.Create("auth.allowlocal", true, CVar.SERVERONLY);

// Only respected on server, client goes through IAuthManager for security.
/// <summary>
/// Authentication server address.
/// List of comma separated URLs to use as whitelisted authentication servers
/// </summary>
public static readonly CVarDef<string> AuthServer =
CVarDef.Create("auth.server", AuthManager.DefaultAuthServer, CVar.SERVERONLY);
/// <example>"Space-Wizards@https://auth.spacestation14.com/,SimpleStation@https://auth.simplestation.org/"</example>
public static readonly CVarDef<string> AuthServers =
CVarDef.Create("auth.servers", AuthServer.ToStringList(AuthManager.DefaultAuthServers), CVar.REPLICATED);

/*
* RENDERING
Expand Down
Loading
Loading