From 122feda215f253767addae329d7fd6de9f6b7856 Mon Sep 17 00:00:00 2001
From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Date: Mon, 5 Jan 2026 22:00:15 +0100
Subject: [PATCH] Msg Toolshed Command (#41936)
* init
* subfolder
* note
---
Content.Server/Prayer/PrayerSystem.cs | 4 +-
.../Toolshed/Commands/Misc/MsgCommand.cs | 83 +++++++++++++++++++
.../en-US/commands/toolshed/msg-command.ftl | 5 ++
.../{ => toolshed}/toolshed-commands.ftl | 2 +
4 files changed, 92 insertions(+), 2 deletions(-)
create mode 100644 Content.Server/Toolshed/Commands/Misc/MsgCommand.cs
create mode 100644 Resources/Locale/en-US/commands/toolshed/msg-command.ftl
rename Resources/Locale/en-US/commands/{ => toolshed}/toolshed-commands.ftl (99%)
diff --git a/Content.Server/Prayer/PrayerSystem.cs b/Content.Server/Prayer/PrayerSystem.cs
index 4235fa2a1c..cc627af1a1 100644
--- a/Content.Server/Prayer/PrayerSystem.cs
+++ b/Content.Server/Prayer/PrayerSystem.cs
@@ -75,7 +75,7 @@ public sealed class PrayerSystem : EntitySystem
/// The IPlayerSession that sent the message
/// The main message sent to the player via the chatbox
/// The popup to notify the player, also prepended to the messageString
- public void SendSubtleMessage(ICommonSession target, ICommonSession source, string messageString, string popupMessage)
+ public void SendSubtleMessage(ICommonSession target, ICommonSession? source, string messageString, string popupMessage)
{
if (target.AttachedEntity == null)
return;
@@ -84,7 +84,7 @@ public sealed class PrayerSystem : EntitySystem
_popupSystem.PopupEntity(popupMessage, target.AttachedEntity.Value, target, PopupType.Large);
_chatManager.ChatMessageToOne(ChatChannel.Local, messageString, message, EntityUid.Invalid, false, target.Channel);
- _adminLogger.Add(LogType.AdminMessage, LogImpact.Low, $"{ToPrettyString(target.AttachedEntity.Value):player} received subtle message from {source.Name}: {message}");
+ _adminLogger.Add(LogType.AdminMessage, LogImpact.Low, $"{ToPrettyString(target.AttachedEntity.Value):player} received subtle message from {source?.Name ?? "unknown source"}: {message}");
}
///
diff --git a/Content.Server/Toolshed/Commands/Misc/MsgCommand.cs b/Content.Server/Toolshed/Commands/Misc/MsgCommand.cs
new file mode 100644
index 0000000000..119a637c96
--- /dev/null
+++ b/Content.Server/Toolshed/Commands/Misc/MsgCommand.cs
@@ -0,0 +1,83 @@
+using Content.Server.Administration;
+using Content.Server.Chat.Managers;
+using Content.Server.Popups;
+using Content.Server.Prayer;
+using Content.Server.Tips;
+using Content.Shared.Administration;
+using Content.Shared.Chat;
+using Content.Shared.Popups;
+using Robust.Shared.Player;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Toolshed;
+
+namespace Content.Server.Toolshed.Commands.Misc;
+
+[ToolshedCommand, AdminCommand(AdminFlags.Fun)]
+public sealed class MsgCommand : ToolshedCommand
+{
+ [Dependency] private IChatManager _chatManager = default!;
+
+ private PrayerSystem? _prayer;
+ private PopupSystem? _popup;
+ private TipsSystem? _tips;
+
+ [CommandImplementation("subtle")]
+ public IEnumerable Subtle(IInvocationContext ctx, [PipedArgument] IEnumerable targets, string popup, string message)
+ {
+ _prayer ??= GetSys();
+
+ foreach (var ent in targets)
+ {
+ if (!TryComp(ent, out var actor))
+ continue;
+
+ _prayer.SendSubtleMessage(actor.PlayerSession, ctx.Session, message, popup);
+
+ yield return ent;
+ }
+ }
+
+ [CommandImplementation("chat")]
+ public IEnumerable Chat([PipedArgument] IEnumerable targets, string message)
+ {
+ foreach (var ent in targets)
+ {
+ if (!TryComp(ent, out var actor))
+ continue;
+
+ _chatManager.ChatMessageToOne(ChatChannel.Local, message, message, EntityUid.Invalid, false, actor.PlayerSession.Channel);
+ yield return ent;
+ }
+ }
+
+ [CommandImplementation("popup")]
+ public IEnumerable Popup([PipedArgument] IEnumerable targets, string popup, PopupType type, bool recipientOnly)
+ {
+ _popup ??= GetSys();
+
+ foreach (var ent in targets)
+ {
+ if (recipientOnly)
+ _popup.PopupEntity(popup, ent, ent, type); // If recipientOnly, show the popup only to the recipient.
+ else
+ _popup.PopupEntity(popup, ent, type); // Otherwise, show it to everyone within PVS of the target entity.
+ yield return ent;
+ }
+ }
+
+ [CommandImplementation("tippy")]
+ public IEnumerable Tippy([PipedArgument] IEnumerable targets, string message, EntProtoId prototype, float speakTime, float slideTime, float waddleInterval)
+ {
+ _tips ??= GetSys();
+
+ foreach (var ent in targets)
+ {
+ if (!TryComp(ent, out var actor))
+ continue;
+
+ _tips.SendTippy(actor.PlayerSession, message, prototype, speakTime, slideTime, waddleInterval);
+
+ yield return ent;
+ }
+ }
+}
diff --git a/Resources/Locale/en-US/commands/toolshed/msg-command.ftl b/Resources/Locale/en-US/commands/toolshed/msg-command.ftl
new file mode 100644
index 0000000000..3891decb75
--- /dev/null
+++ b/Resources/Locale/en-US/commands/toolshed/msg-command.ftl
@@ -0,0 +1,5 @@
+# Msg
+command-description-msg-subtle = Sends a combination of a popup and a message to the input entities. Behaves same as the Subtle Message admin verb. Outputs entities that successfuly received a message.
+command-description-msg-chat = Sends a chat message to the sessions of the input entities. Outputs entities that successfuly received a message.
+command-description-msg-popup = Displays a popup above the input entiites. Can specify to only be visible to the target.
+command-description-msg-tippy = Sends a Tippy to the sessions of the input entities. All parameters must be specified. Outputs entities that successfuly received a tippy.
diff --git a/Resources/Locale/en-US/commands/toolshed-commands.ftl b/Resources/Locale/en-US/commands/toolshed/toolshed-commands.ftl
similarity index 99%
rename from Resources/Locale/en-US/commands/toolshed-commands.ftl
rename to Resources/Locale/en-US/commands/toolshed/toolshed-commands.ftl
index bfd2f780b1..662a5a920d 100644
--- a/Resources/Locale/en-US/commands/toolshed-commands.ftl
+++ b/Resources/Locale/en-US/commands/toolshed/toolshed-commands.ftl
@@ -1,3 +1,5 @@
+# Please add future toolshed locale to their own files. This needs to be cleaned up.
+
command-description-visualize =
Takes the input list of entities and puts them into a UI window for easy browsing.
command-description-runverbas =
--
2.52.0