diff --git a/Content.Server/Administration/Commands/BanCommand.cs b/Content.Server/Administration/Commands/BanCommand.cs index b6102f7f1d..eeeb34e54c 100644 --- a/Content.Server/Administration/Commands/BanCommand.cs +++ b/Content.Server/Administration/Commands/BanCommand.cs @@ -5,19 +5,20 @@ using System.Text; using Content.Server.Database; using Content.Shared.Administration; using Robust.Server.Player; +using Robust.Shared.Configuration; using Robust.Shared.Console; namespace Content.Server.Administration.Commands { [AdminCommand(AdminFlags.Ban)] - public sealed class BanCommand : IConsoleCommand + public sealed class BanCommand : LocalizedCommands { - public string Command => "ban"; - public string Description => Loc.GetString("cmd-ban-desc"); - public string Help => Loc.GetString("cmd-ban-help", ("Command", Command)); + [Dependency] private readonly IConfigurationManager _cfg = default!; - public async void Execute(IConsoleShell shell, string argStr, string[] args) + public override string Command => "ban"; + + public override async void Execute(IConsoleShell shell, string argStr, string[] args) { var player = shell.Player as IPlayerSession; var plyMgr = IoCManager.Resolve(); @@ -54,7 +55,7 @@ namespace Content.Server.Administration.Commands var located = await locator.LookupIdByNameOrIdAsync(target); if (located == null) { - shell.WriteError(Loc.GetString("cmd-ban-player")); + shell.WriteError(LocalizationManager.GetString("cmd-ban-player")); return; } @@ -64,7 +65,7 @@ namespace Content.Server.Administration.Commands if (player != null && player.UserId == targetUid) { - shell.WriteLine(Loc.GetString("cmd-ban-self")); + shell.WriteLine(LocalizationManager.GetString("cmd-ban-self")); return; } @@ -100,43 +101,42 @@ namespace Content.Server.Administration.Commands var response = new StringBuilder($"Banned {target} with reason \"{reason}\""); - response.Append(expires == null ? - " permanently." - : $" until {expires}"); + response.Append(expires == null ? " permanently." : $" until {expires}"); shell.WriteLine(response.ToString()); if (plyMgr.TryGetSessionById(targetUid, out var targetPlayer)) { - targetPlayer.ConnectedClient.Disconnect(banDef.DisconnectMessage); + var message = banDef.FormatBanMessage(_cfg, LocalizationManager); + targetPlayer.ConnectedClient.Disconnect(message); } } - public CompletionResult GetCompletion(IConsoleShell shell, string[] args) + public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) { if (args.Length == 1) { var playerMgr = IoCManager.Resolve(); var options = playerMgr.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray(); - return CompletionResult.FromHintOptions(options, Loc.GetString("cmd-ban-hint")); + return CompletionResult.FromHintOptions(options, LocalizationManager.GetString("cmd-ban-hint")); } if (args.Length == 2) - return CompletionResult.FromHint(Loc.GetString("cmd-ban-hint-reason")); + return CompletionResult.FromHint(LocalizationManager.GetString("cmd-ban-hint-reason")); if (args.Length == 3) { var durations = new CompletionOption[] { - new("0", Loc.GetString("cmd-ban-hint-duration-1")), - new("1440", Loc.GetString("cmd-ban-hint-duration-2")), - new("4320", Loc.GetString("cmd-ban-hint-duration-3")), - new("10080", Loc.GetString("cmd-ban-hint-duration-4")), - new("20160", Loc.GetString("cmd-ban-hint-duration-5")), - new("43800", Loc.GetString("cmd-ban-hint-duration-6")), + new("0", LocalizationManager.GetString("cmd-ban-hint-duration-1")), + new("1440", LocalizationManager.GetString("cmd-ban-hint-duration-2")), + new("4320", LocalizationManager.GetString("cmd-ban-hint-duration-3")), + new("10080", LocalizationManager.GetString("cmd-ban-hint-duration-4")), + new("20160", LocalizationManager.GetString("cmd-ban-hint-duration-5")), + new("43800", LocalizationManager.GetString("cmd-ban-hint-duration-6")), }; - return CompletionResult.FromHintOptions(durations, Loc.GetString("cmd-ban-hint-duration")); + return CompletionResult.FromHintOptions(durations, LocalizationManager.GetString("cmd-ban-hint-duration")); } return CompletionResult.Empty; diff --git a/Content.Server/Connection/ConnectionManager.cs b/Content.Server/Connection/ConnectionManager.cs index febdb56e32..43ba601f77 100644 --- a/Content.Server/Connection/ConnectionManager.cs +++ b/Content.Server/Connection/ConnectionManager.cs @@ -28,6 +28,7 @@ namespace Content.Server.Connection [Dependency] private readonly IServerNetManager _netMgr = default!; [Dependency] private readonly IServerDbManager _db = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private readonly ILocalizationManager _loc = default!; public void Initialize() { @@ -147,7 +148,8 @@ namespace Content.Server.Connection if (bans.Count > 0) { var firstBan = bans[0]; - return (ConnectionDenyReason.Ban, firstBan.DisconnectMessage, bans); + var message = firstBan.FormatBanMessage(_cfg, _loc); + return (ConnectionDenyReason.Ban, message, bans); } if (_cfg.GetCVar(CCVars.WhitelistEnabled)) diff --git a/Content.Server/Database/ServerBanDef.cs b/Content.Server/Database/ServerBanDef.cs index 755365ca45..d5bc677184 100644 --- a/Content.Server/Database/ServerBanDef.cs +++ b/Content.Server/Database/ServerBanDef.cs @@ -1,5 +1,7 @@ using System.Collections.Immutable; using System.Net; +using Content.Shared.CCVar; +using Robust.Shared.Configuration; using Robust.Shared.Network; @@ -52,19 +54,30 @@ namespace Content.Server.Database Unban = unban; } - public string DisconnectMessage + public string FormatBanMessage(IConfigurationManager cfg, ILocalizationManager loc) { - get { - var expires = Loc.GetString("ban-banned-permanent"); - if (this.ExpirationTime is { } expireTime) - { - var duration = expireTime - this.BanTime; - var utc = expireTime.ToUniversalTime(); - expires = Loc.GetString("ban-expires", ("duration", duration.TotalMinutes.ToString("N0")), ("time", utc.ToString("f"))); - } - var details = Loc.GetString("ban-banned-1") + "\n" + Loc.GetString("ban-banned-2", ("reason", this.Reason)) + "\n" + expires; - return details; + string expires; + if (ExpirationTime is { } expireTime) + { + var duration = expireTime - BanTime; + var utc = expireTime.ToUniversalTime(); + expires = loc.GetString("ban-expires", ("duration", duration.TotalMinutes.ToString("N0")), ("time", utc.ToString("f"))); } + else + { + var appeal = cfg.GetCVar(CCVars.InfoLinksAppeal); + if (!string.IsNullOrWhiteSpace(appeal)) + expires = loc.GetString("ban-banned-permanent-appeal", ("link", appeal)); + else + expires = loc.GetString("ban-banned-permanent"); + } + + return $""" + {loc.GetString("ban-banned-1")} + {loc.GetString("ban-banned-2", ("reason", Reason))} + {expires} + {loc.GetString("ban-banned-3")} + """; } } } diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 708796067d..38018ed84b 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -1475,6 +1475,12 @@ namespace Content.Shared.CCVar public static readonly CVarDef InfoLinksBugReport = CVarDef.Create("infolinks.bug_report", "", CVar.SERVER | CVar.REPLICATED); + /// + /// Link to site handling ban appeals. Shown in ban disconnect messages. + /// + public static readonly CVarDef InfoLinksAppeal = + CVarDef.Create("infolinks.appeal", "", CVar.SERVER | CVar.REPLICATED); + /* * CONFIG */ diff --git a/Resources/ConfigPresets/WizardsDen/wizardsDen.toml b/Resources/ConfigPresets/WizardsDen/wizardsDen.toml index d8709f0e9d..3e3d7ef8e4 100644 --- a/Resources/ConfigPresets/WizardsDen/wizardsDen.toml +++ b/Resources/ConfigPresets/WizardsDen/wizardsDen.toml @@ -14,6 +14,7 @@ github = "https://github.com/space-wizards/space-station-14" patreon = "https://www.patreon.com/spacestation14" website = "https://spacestation14.io" wiki = "https://wiki.spacestation14.io" +appeal = "https://appeal.ss14.io" [net] max_connections = 1024 diff --git a/Resources/Locale/en-US/connection-messages.ftl b/Resources/Locale/en-US/connection-messages.ftl index 5d2768fdc1..2755cf789a 100644 --- a/Resources/Locale/en-US/connection-messages.ftl +++ b/Resources/Locale/en-US/connection-messages.ftl @@ -25,10 +25,12 @@ command-whitelistremove-not-found = Unable to find '{$username}' command-kicknonwhitelisted-description = Kicks all non-whitelisted players from the server. command-kicknonwhitelisted-help = kicknonwhitelisted -ban-banned-permanent = This ban is appeal only. +ban-banned-permanent = This ban will only be removed via appeal. +ban-banned-permanent-appeal = This ban will only be removed via appeal. You can appeal at {$link} ban-expires = This ban is for {$duration} minutes and will expire at {$time} UTC. ban-banned-1 = You, or another user of this computer or connection, are banned from playing here. ban-banned-2 = The ban reason is: "{$reason}" +ban-banned-3 = Attempts to circumvent this ban such as creating a new account will be logged. soft-player-cap-full = The server is full! panic-bunker-account-denied = This server is in panic bunker mode. New connections are not being accepted at this time. Try again later