diff --git a/Content.Server/Administration/AdminManager.cs b/Content.Server/Administration/AdminManager.cs index cb8dc386a9..4ca81c52fc 100644 --- a/Content.Server/Administration/AdminManager.cs +++ b/Content.Server/Administration/AdminManager.cs @@ -21,6 +21,7 @@ using Robust.Shared.Interfaces.Network; using Robust.Shared.Interfaces.Resources; using Robust.Shared.IoC; using Robust.Shared.Localization; +using Robust.Shared.Network; using Robust.Shared.Utility; using YamlDotNet.RepresentationModel; @@ -40,6 +41,7 @@ namespace Content.Server.Administration [Dependency] private readonly IChatManager _chat = default!; private readonly Dictionary _admins = new(); + private readonly HashSet _promotedPlayers = new(); public event Action? OnPermsChanged; @@ -227,6 +229,13 @@ namespace Content.Server.Administration } } + public void PromoteHost(IPlayerSession player) + { + _promotedPlayers.Add(player.UserId); + + ReloadAdmin(player); + } + void IPostInjectInit.PostInject() { _playerManager.PlayerStatusChanged += PlayerStatusChanged; @@ -309,7 +318,7 @@ namespace Content.Server.Administration private async Task<(AdminData dat, int? rankId, bool specialLogin)?> LoadAdminData(IPlayerSession session) { - if (IsLocal(session) && _cfg.GetCVar(CCVars.ConsoleLoginLocal)) + if (IsLocal(session) && _cfg.GetCVar(CCVars.ConsoleLoginLocal) || _promotedPlayers.Contains(session.UserId)) { var data = new AdminData { @@ -463,7 +472,7 @@ namespace Content.Server.Administration public AdminData Data; public int? RankId; - // Such as console.loginlocal + // Such as console.loginlocal or promotehost public bool IsSpecialLogin; public AdminReg(IPlayerSession session, AdminData data) diff --git a/Content.Server/Administration/Commands/PromoteHostCommand.cs b/Content.Server/Administration/Commands/PromoteHostCommand.cs new file mode 100644 index 0000000000..058557fa14 --- /dev/null +++ b/Content.Server/Administration/Commands/PromoteHostCommand.cs @@ -0,0 +1,35 @@ +#nullable enable +using JetBrains.Annotations; +using Robust.Server.Interfaces.Console; +using Robust.Server.Interfaces.Player; +using Robust.Shared.IoC; + +namespace Content.Server.Administration.Commands +{ + [UsedImplicitly] + public sealed class PromoteHostCommand : IClientCommand + { + public string Command => "promotehost"; + public string Description => "Grants client temporary full host admin privileges. Use this to bootstrap admins."; + public string Help => "Usage promotehost "; + + public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args) + { + if (args.Length != 1) + { + shell.SendText(player, "Expected exactly one argument."); + return; + } + + var plyMgr = IoCManager.Resolve(); + if (!plyMgr.TryGetSessionByUsername(args[0], out var targetPlayer)) + { + shell.SendText(player, "Unable to find a player by that name."); + return; + } + + var adminMgr = IoCManager.Resolve(); + adminMgr.PromoteHost(targetPlayer); + } + } +} diff --git a/Content.Server/Administration/IAdminManager.cs b/Content.Server/Administration/IAdminManager.cs index ba2088f0b6..6137387669 100644 --- a/Content.Server/Administration/IAdminManager.cs +++ b/Content.Server/Administration/IAdminManager.cs @@ -72,5 +72,7 @@ namespace Content.Server.Administration void ReloadAdminsWithRank(int rankId); void Initialize(); + + void PromoteHost(IPlayerSession player); } }