diff --git a/Content.Client/UserInterface/AdminMenu/AdminMenuWindow.cs b/Content.Client/UserInterface/AdminMenu/AdminMenuWindow.cs index 266cf46f01..bff971a090 100644 --- a/Content.Client/UserInterface/AdminMenu/AdminMenuWindow.cs +++ b/Content.Client/UserInterface/AdminMenu/AdminMenuWindow.cs @@ -36,6 +36,7 @@ namespace Content.Client.UserInterface.AdminMenu private readonly List _adminButtons = new() { new KickCommandButton(), + new BanCommandButton(), new DirectCommandButton("Admin Ghost", "aghost"), new TeleportCommandButton(), new DirectCommandButton("Permissions Panel", "permissions"), @@ -552,6 +553,42 @@ namespace Content.Client.UserInterface.AdminMenu } } + private class BanCommandButton : UICommandButton + { + public override string Name => "Ban"; + public override string RequiredCommand => "ban"; + + private readonly CommandUIDropDown _playerDropDown = new() + { + Name = "Player", + GetData = () => IoCManager.Resolve().Sessions.ToList(), + GetDisplayName = (obj) => $"{((IPlayerSession) obj).Name} ({((IPlayerSession) obj).AttachedEntity?.Name})", + GetValueFromData = (obj) => ((IPlayerSession) obj).Name, + }; + + private readonly CommandUILineEdit _reason = new() + { + Name = "Reason" + }; + + private readonly CommandUILineEdit _minutes = new() + { + Name = "Minutes" + }; + + public override List UI => new() + { + _playerDropDown, + _reason, + _minutes + }; + + public override void Submit() + { + IoCManager.Resolve().ExecuteCommand($"ban \"{_playerDropDown.GetValue()}\" \"{CommandParsing.Escape(_reason.GetValue())}\" \"{_minutes.GetValue()}"); + } + } + private class TeleportCommandButton : UICommandButton { public override string Name => "Teleport"; diff --git a/Content.Server/Administration/Commands/BanCommand.cs b/Content.Server/Administration/Commands/BanCommand.cs index c5b45f060b..f23b4ada45 100644 --- a/Content.Server/Administration/Commands/BanCommand.cs +++ b/Content.Server/Administration/Commands/BanCommand.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using Content.Server.Database; using Content.Shared.Administration; using Robust.Server.Player; @@ -15,7 +16,7 @@ namespace Content.Server.Administration.Commands { public string Command => "ban"; public string Description => "Bans somebody"; - public string Help => "Usage: "; + public string Help => $"Usage: {Command} "; public async void Execute(IConsoleShell shell, string argStr, string[] args) { @@ -23,9 +24,33 @@ namespace Content.Server.Administration.Commands var plyMgr = IoCManager.Resolve(); var dbMan = IoCManager.Resolve(); - var target = args[0]; - var reason = args[1]; - var duration = int.Parse(args[2]); + string target; + string reason; + uint minutes; + + switch (args.Length) + { + case 2: + target = args[0]; + reason = args[1]; + minutes = 0; + break; + case 3: + target = args[0]; + reason = args[1]; + + if (!uint.TryParse(args[2], out minutes)) + { + shell.WriteLine($"{args[2]} is not a valid amount of minutes.\n{Help}"); + return; + } + + break; + default: + shell.WriteLine($"Invalid amount of arguments.{Help}"); + return; + } + NetUserId targetUid; if (plyMgr.TryGetSessionByUsername(target, out var targetSession)) @@ -42,14 +67,28 @@ namespace Content.Server.Administration.Commands return; } - DateTimeOffset? expires = null; - if (duration > 0) + if (player != null && player.UserId == targetUid) { - expires = DateTimeOffset.Now + TimeSpan.FromMinutes(duration); + shell.WriteLine("You can't ban yourself!"); + return; + } + + DateTimeOffset? expires = null; + if (minutes > 0) + { + expires = DateTimeOffset.Now + TimeSpan.FromMinutes(minutes); } await dbMan.AddServerBanAsync(new ServerBanDef(null, targetUid, null, DateTimeOffset.Now, expires, reason, player?.UserId, null)); + var response = new StringBuilder($"Banned {targetUid} with reason \"{reason}\""); + + response.Append(expires == null ? + " permanently." + : $" until {expires.ToString()}"); + + shell.WriteLine(response.ToString()); + if (plyMgr.TryGetSessionById(targetUid, out var targetPlayer)) { targetPlayer.ConnectedClient.Disconnect("You've been banned. Tough shit.");