Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stealthmins #26263

Merged
merged 5 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
13 changes: 13 additions & 0 deletions Content.Server/Administration/Commands/AdminWhoCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
var adminMgr = IoCManager.Resolve<IAdminManager>();
var afk = IoCManager.Resolve<IAfkManager>();

var seeStealth = true;

// If null it (hopefully) means it is being called from the console.
if (shell.Player != null)
{
var playerData = adminMgr.GetAdminData(shell.Player);

seeStealth = playerData != null && playerData.CanStealth();
}

var sb = new StringBuilder();
var first = true;
foreach (var admin in adminMgr.ActiveAdmins)
Expand All @@ -30,6 +40,9 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
var adminData = adminMgr.GetAdminData(admin)!;
DebugTools.AssertNotNull(adminData);

if (adminData.Stealth && !seeStealth)
continue;

sb.Append(admin.Name);
if (adminData.Title is { } title)
sb.Append($": [{title}]");
nikthechampiongr marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
41 changes: 41 additions & 0 deletions Content.Server/Administration/Commands/StealthminCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Content.Server.Administration.Managers;
using Content.Shared.Administration;
using JetBrains.Annotations;
using Robust.Shared.Console;
using Robust.Shared.Utility;

namespace Content.Server.Administration.Commands;

[UsedImplicitly]
[AdminCommand(AdminFlags.Stealth)]
public sealed class StealthminCommand : IConsoleCommand
{
public string Command => "stealthmin";
public string Description => "Toggle whether others can see you in adminwho";
public string Help => "Usage: stealthmin\nUse stealthmin to toggle whether you appear in the output of the adminwho command.";

public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player;
if (player == null)
{
shell.WriteLine("You cannot use this command from the server console.");
return;
}

var mgr = IoCManager.Resolve<IAdminManager>();

var adminData = mgr.GetAdminData(player);

DebugTools.AssertNotNull(adminData);

if (!adminData!.Stealth)
{
mgr.Stealth(player);
}
else
{
mgr.UnStealth(player);
}
}
}
82 changes: 78 additions & 4 deletions Content.Server/Administration/Managers/AdminManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,42 @@ public void DeAdmin(ICommonSession session)
UpdateAdminStatus(session);
}

public void Stealth(ICommonSession session)
{
if (!_admins.TryGetValue(session, out var reg))
{
throw new ArgumentException($"Player {session} is not an admin");
}

if (reg.Data.Stealth)
return;

var playerData = session.ContentData()!;
playerData.Stealthed = true;
reg.Data.Stealth = true;

_chat.DispatchServerMessage(session, Loc.GetString("admin-manager-stealthed-message"));
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-de-admin-message", ("exAdminName", session.Name)), AdminFlags.Stealth);
}

nikthechampiongr marked this conversation as resolved.
Show resolved Hide resolved
public void UnStealth(ICommonSession session)
{
if (!_admins.TryGetValue(session, out var reg))
{
throw new ArgumentException($"Player {session} is not an admin");
}

if (!reg.Data.Stealth)
return;

var playerData = session.ContentData()!;
playerData.Stealthed = false;
reg.Data.Stealth = false;

_chat.DispatchServerMessage(session, Loc.GetString("admin-manager-unstealthed-message"));
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-re-admin-message", ("newAdminName", session.Name)), flagBlacklist: AdminFlags.Stealth);
}

nikthechampiongr marked this conversation as resolved.
Show resolved Hide resolved
public void ReAdmin(ICommonSession session)
{
if (!_admins.TryGetValue(session, out var reg))
Expand All @@ -113,7 +149,16 @@ public void ReAdmin(ICommonSession session)
plyData.ExplicitlyDeadminned = false;
reg.Data.Active = true;

_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-re-admin-message", ("newAdminName", session.Name)));
if (reg.Data.Stealth)
{
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-re-admin-message", ("newAdminName", session.Name)));
}
else
{
_chat.DispatchServerMessage(session, Loc.GetString("admin-manager-stealthed-message"));
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-re-admin-message",
("newAdminName", session.Name)), flagWhitelist: AdminFlags.Stealth);
}

SendPermsChangedEvent(session);
UpdateAdminStatus(session);
Expand Down Expand Up @@ -165,6 +210,11 @@ public async void ReloadAdmin(ICommonSession player)

_chat.DispatchServerMessage(player, Loc.GetString("admin-manager-admin-permissions-updated-message"));
}

if (player.ContentData()!.Stealthed)
{
aData.Stealth = true;
}
}

SendPermsChangedEvent(player);
Expand Down Expand Up @@ -283,9 +333,19 @@ private void PlayerStatusChanged(object? sender, SessionStatusEventArgs e)
}
else if (e.NewStatus == SessionStatus.Disconnected)
{
if (_admins.Remove(e.Session) && _cfg.GetCVar(CCVars.AdminAnnounceLogout))
if (_admins.Remove(e.Session, out var reg ) && _cfg.GetCVar(CCVars.AdminAnnounceLogout))
{
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-logout-message", ("name", e.Session.Name)));
if (reg.Data.Stealth)
{
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-logout-message",
("name", e.Session.Name)), flagWhitelist: AdminFlags.Stealth);

}
else
{
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-logout-message",
("name", e.Session.Name)));
}
}
}
}
Expand All @@ -308,13 +368,27 @@ private async void LoginAdminMaybe(ICommonSession session)

_admins.Add(session, reg);

if (session.ContentData()!.Stealthed)
reg.Data.Stealth = true;

if (!session.ContentData()!.ExplicitlyDeadminned)
{
reg.Data.Active = true;

if (_cfg.GetCVar(CCVars.AdminAnnounceLogin))
{
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-login-message", ("name", session.Name)));
if (reg.Data.Stealth)
{

_chat.DispatchServerMessage(session, Loc.GetString("admin-manager-stealthed-message"));
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-login-message",
("name", session.Name)), flagWhitelist: AdminFlags.Stealth);
}
else
{
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-login-message",
("name", session.Name)));
}
}

SendPermsChangedEvent(session);
Expand Down
10 changes: 10 additions & 0 deletions Content.Server/Administration/Managers/IAdminManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ public interface IAdminManager : ISharedAdminManager
/// </summary>
void ReAdmin(ICommonSession session);

/// <summary>
/// Make admin hidden from adminwho.
/// </summary>
void Stealth(ICommonSession session);

/// <summary>
/// Unhide admin from adminwho.
/// </summary>
void UnStealth(ICommonSession session);

/// <summary>
/// Re-loads the permissions of an player in case their admin data changed DB-side.
/// </summary>
Expand Down
18 changes: 16 additions & 2 deletions Content.Server/Chat/Managers/ChatManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,23 @@ public void DispatchServerMessage(ICommonSession player, string message, bool su
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Server message to {player:Player}: {message}");
}

public void SendAdminAnnouncement(string message)
public void SendAdminAnnouncement(string message, AdminFlags? flagBlacklist, AdminFlags? flagWhitelist)
{
var clients = _adminManager.ActiveAdmins.Select(p => p.Channel);
var clients = _adminManager.ActiveAdmins.Where(p =>
{
var adminData = _adminManager.GetAdminData(p);

DebugTools.AssertNotNull(adminData);

if (adminData == null)
return false;

if (flagBlacklist != null && adminData.HasFlag(flagBlacklist.Value))
return false;

return flagWhitelist == null || adminData.HasFlag(flagWhitelist.Value);

}).Select(p => p.Channel);

var wrappedMessage = Loc.GetString("chat-manager-send-admin-announcement-wrap-message",
("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")), ("message", FormattedMessage.EscapeText(message)));
Expand Down
3 changes: 2 additions & 1 deletion Content.Server/Chat/Managers/IChatManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using Content.Shared.Administration;
using Content.Shared.Chat;
using Robust.Shared.Network;
using Robust.Shared.Player;
Expand All @@ -21,7 +22,7 @@ public interface IChatManager
void TrySendOOCMessage(ICommonSession player, string message, OOCChatType type);

void SendHookOOC(string sender, string message);
void SendAdminAnnouncement(string message);
void SendAdminAnnouncement(string message, AdminFlags? flagBlacklist = null, AdminFlags? flagWhitelist = null);
void SendAdminAlert(string message);
void SendAdminAlert(EntityUid player, string message);

Expand Down
13 changes: 13 additions & 0 deletions Content.Shared/Administration/AdminData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public sealed class AdminData
/// </summary>
public bool Active;

/// <summary>
/// Whether the admin is in stealth mode and won't appear in adminwho to admins without the Stealth flag.
/// </summary>
public bool Stealth;

/// <summary>
/// The admin's title.
/// </summary>
Expand Down Expand Up @@ -56,6 +61,14 @@ public bool CanAdminMenu()
return HasFlag(AdminFlags.Admin);
}

/// <summary>
/// Check if this admin can be hidden and see other hidden admins.
/// </summary>
public bool CanStealth()
{
return HasFlag(AdminFlags.Stealth);
}

public bool CanAdminReloadPrototypes()
{
return HasFlag(AdminFlags.Host);
Expand Down
5 changes: 5 additions & 0 deletions Content.Shared/Administration/AdminFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ public enum AdminFlags : uint
/// </summary>
MassBan = 1 << 15,

/// <summary>
/// Allows you to remain hidden from adminwho except to other admins with this flag.
/// </summary>
Stealth = 1 << 16,

/// <summary>
/// Dangerous host permissions like scsi.
/// </summary>
Expand Down
10 changes: 8 additions & 2 deletions Content.Shared/Players/ContentPlayerData.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Shared.GameTicking;
using Content.Shared.Administration;
using Content.Shared.GameTicking;
using Content.Shared.Mind;
using Robust.Shared.Network;

Expand Down Expand Up @@ -37,9 +38,14 @@ public sealed class ContentPlayerData
/// </summary>
public bool ExplicitlyDeadminned { get; set; }

/// <summary>
/// If true, the admin will not show up in adminwho except to admins with the <see cref="AdminFlags.Stealth"/> flag.
/// </summary>
public bool Stealthed { get; set; }

public ContentPlayerData(NetUserId userId, string name)
{
UserId = userId;
Name = name;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ admin-manager-no-longer-admin-message = You are no longer an admin.
admin-manager-admin-permissions-updated-message = Your admin permission have been updated.
admin-manager-admin-logout-message = Admin logout: {$name}
admin-manager-admin-login-message = Admin login: {$name}
admin-manager-admin-data-host-title = Host
admin-manager-admin-data-host-title = Host
admin-manager-stealthed-message = You are now a hidden admin.
admin-manager-unstealthed-message = You are no longer hidden.
Loading