Add option for admins to disable bwoink (#25008)

* Add option for admins to disable bwoink

In a vain attempt to get people to ahelp more, provide the possibility
for admins to not play the bwoink sound if they don't want to scare the
player.

* Add silent indicator to discord relay

* Use string interpolation
This commit is contained in:
dffdff2423
2024-02-21 00:52:03 -06:00
committed by GitHub
parent 77e8930a72
commit a3c93b0bd7
6 changed files with 35 additions and 21 deletions

View File

@@ -19,11 +19,11 @@ namespace Content.Client.Administration.Systems
OnBwoinkTextMessageRecieved?.Invoke(this, message); OnBwoinkTextMessageRecieved?.Invoke(this, message);
} }
public void Send(NetUserId channelId, string text) public void Send(NetUserId channelId, string text, bool playSound)
{ {
// Reuse the channel ID as the 'true sender'. // Reuse the channel ID as the 'true sender'.
// Server will ignore this and if someone makes it not ignore this (which is bad, allows impersonation!!!), that will help. // Server will ignore this and if someone makes it not ignore this (which is bad, allows impersonation!!!), that will help.
RaiseNetworkEvent(new BwoinkTextMessage(channelId, channelId, text)); RaiseNetworkEvent(new BwoinkTextMessage(channelId, channelId, text, playSound: playSound));
SendInputTextUpdated(channelId, false); SendInputTextUpdated(channelId, false);
} }

View File

@@ -7,6 +7,8 @@
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="2"> <BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="2">
<BoxContainer Access="Public" Name="BwoinkArea" VerticalExpand="True" /> <BoxContainer Access="Public" Name="BwoinkArea" VerticalExpand="True" />
<BoxContainer Orientation="Horizontal" HorizontalExpand="True"> <BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<CheckBox Visible="True" Name="PlaySound" Access="Public" Text="{Loc 'admin-bwoink-play-sound'}" Pressed="True" />
<Control HorizontalExpand="True" MinWidth="5" />
<Button Visible="True" Name="PopOut" Access="Public" Text="{Loc 'admin-logs-pop-out'}" StyleClasses="OpenBoth" HorizontalAlignment="Left" /> <Button Visible="True" Name="PopOut" Access="Public" Text="{Loc 'admin-logs-pop-out'}" StyleClasses="OpenBoth" HorizontalAlignment="Left" />
<Control HorizontalExpand="True" /> <Control HorizontalExpand="True" />
<Button Visible="False" Name="Bans" Text="{Loc 'admin-player-actions-bans'}" StyleClasses="OpenRight" /> <Button Visible="False" Name="Bans" Text="{Loc 'admin-player-actions-bans'}" StyleClasses="OpenRight" />

View File

@@ -133,7 +133,7 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged<BwoinkSyst
{ {
return; return;
} }
if (localPlayer.UserId != message.TrueSender) if (message.PlaySound && localPlayer.UserId != message.TrueSender)
{ {
if (_aHelpSound != null) if (_aHelpSound != null)
_audio.PlayGlobal(_aHelpSound, Filter.Local(), false); _audio.PlayGlobal(_aHelpSound, Filter.Local(), false);
@@ -173,7 +173,7 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged<BwoinkSyst
UIHelper = isAdmin ? new AdminAHelpUIHandler(ownerUserId) : new UserAHelpUIHandler(ownerUserId); UIHelper = isAdmin ? new AdminAHelpUIHandler(ownerUserId) : new UserAHelpUIHandler(ownerUserId);
UIHelper.DiscordRelayChanged(_discordRelayActive); UIHelper.DiscordRelayChanged(_discordRelayActive);
UIHelper.SendMessageAction = (userId, textMessage) => _bwoinkSystem?.Send(userId, textMessage); UIHelper.SendMessageAction = (userId, textMessage, playSound) => _bwoinkSystem?.Send(userId, textMessage, playSound);
UIHelper.InputTextChanged += (channel, text) => _bwoinkSystem?.SendInputTextUpdated(channel, text.Length > 0); UIHelper.InputTextChanged += (channel, text) => _bwoinkSystem?.SendInputTextUpdated(channel, text.Length > 0);
UIHelper.OnClose += () => { SetAHelpPressed(false); }; UIHelper.OnClose += () => { SetAHelpPressed(false); };
UIHelper.OnOpen += () => { SetAHelpPressed(true); }; UIHelper.OnOpen += () => { SetAHelpPressed(true); };
@@ -322,7 +322,7 @@ public interface IAHelpUIHandler : IDisposable
public void PeopleTypingUpdated(BwoinkPlayerTypingUpdated args); public void PeopleTypingUpdated(BwoinkPlayerTypingUpdated args);
public event Action OnClose; public event Action OnClose;
public event Action OnOpen; public event Action OnOpen;
public Action<NetUserId, string>? SendMessageAction { get; set; } public Action<NetUserId, string, bool>? SendMessageAction { get; set; }
public event Action<NetUserId, string>? InputTextChanged; public event Action<NetUserId, string>? InputTextChanged;
} }
public sealed class AdminAHelpUIHandler : IAHelpUIHandler public sealed class AdminAHelpUIHandler : IAHelpUIHandler
@@ -406,7 +406,7 @@ public sealed class AdminAHelpUIHandler : IAHelpUIHandler
public event Action? OnClose; public event Action? OnClose;
public event Action? OnOpen; public event Action? OnOpen;
public Action<NetUserId, string>? SendMessageAction { get; set; } public Action<NetUserId, string, bool>? SendMessageAction { get; set; }
public event Action<NetUserId, string>? InputTextChanged; public event Action<NetUserId, string>? InputTextChanged;
public void Open(NetUserId channelId, bool relayActive) public void Open(NetUserId channelId, bool relayActive)
@@ -460,7 +460,7 @@ public sealed class AdminAHelpUIHandler : IAHelpUIHandler
if (_activePanelMap.TryGetValue(channelId, out var existingPanel)) if (_activePanelMap.TryGetValue(channelId, out var existingPanel))
return existingPanel; return existingPanel;
_activePanelMap[channelId] = existingPanel = new BwoinkPanel(text => SendMessageAction?.Invoke(channelId, text)); _activePanelMap[channelId] = existingPanel = new BwoinkPanel(text => SendMessageAction?.Invoke(channelId, text, Window?.Bwoink.PlaySound.Pressed ?? true));
existingPanel.InputTextChanged += text => InputTextChanged?.Invoke(channelId, text); existingPanel.InputTextChanged += text => InputTextChanged?.Invoke(channelId, text);
existingPanel.Visible = false; existingPanel.Visible = false;
if (!Control!.BwoinkArea.Children.Contains(existingPanel)) if (!Control!.BwoinkArea.Children.Contains(existingPanel))
@@ -546,7 +546,7 @@ public sealed class UserAHelpUIHandler : IAHelpUIHandler
public event Action? OnClose; public event Action? OnClose;
public event Action? OnOpen; public event Action? OnOpen;
public Action<NetUserId, string>? SendMessageAction { get; set; } public Action<NetUserId, string, bool>? SendMessageAction { get; set; }
public event Action<NetUserId, string>? InputTextChanged; public event Action<NetUserId, string>? InputTextChanged;
public void Open(NetUserId channelId, bool relayActive) public void Open(NetUserId channelId, bool relayActive)
@@ -559,7 +559,7 @@ public sealed class UserAHelpUIHandler : IAHelpUIHandler
{ {
if (_window is { Disposed: false }) if (_window is { Disposed: false })
return; return;
_chatPanel = new BwoinkPanel(text => SendMessageAction?.Invoke(_ownerId, text)); _chatPanel = new BwoinkPanel(text => SendMessageAction?.Invoke(_ownerId, text, true));
_chatPanel.InputTextChanged += text => InputTextChanged?.Invoke(_ownerId, text); _chatPanel.InputTextChanged += text => InputTextChanged?.Invoke(_ownerId, text);
_chatPanel.RelayedToDiscordLabel.Visible = relayActive; _chatPanel.RelayedToDiscordLabel.Visible = relayActive;
_window = new DefaultWindow() _window = new DefaultWindow()

View File

@@ -72,7 +72,7 @@ namespace Content.Server.Administration.Systems
Subs.CVar(_config, CVars.GameHostName, OnServerNameChanged, true); Subs.CVar(_config, CVars.GameHostName, OnServerNameChanged, true);
Subs.CVar(_config, CCVars.AdminAhelpOverrideClientName, OnOverrideChanged, true); Subs.CVar(_config, CCVars.AdminAhelpOverrideClientName, OnOverrideChanged, true);
_sawmill = IoCManager.Resolve<ILogManager>().GetSawmill("AHELP"); _sawmill = IoCManager.Resolve<ILogManager>().GetSawmill("AHELP");
_maxAdditionalChars = GenerateAHelpMessage("", "", true, _gameTicker.RoundDuration().ToString("hh\\:mm\\:ss"), _gameTicker.RunLevel).Length; _maxAdditionalChars = GenerateAHelpMessage("", "", true, _gameTicker.RoundDuration().ToString("hh\\:mm\\:ss"), _gameTicker.RunLevel, false).Length;
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged; _playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
SubscribeLocalEvent<GameRunLevelChangedEvent>(OnGameRunLevelChanged); SubscribeLocalEvent<GameRunLevelChangedEvent>(OnGameRunLevelChanged);
@@ -398,18 +398,21 @@ namespace Content.Server.Administration.Systems
if (senderAdmin is not null && senderAdmin.Flags == AdminFlags.Adminhelp) // Mentor. Not full admin. That's why it's colored differently. if (senderAdmin is not null && senderAdmin.Flags == AdminFlags.Adminhelp) // Mentor. Not full admin. That's why it's colored differently.
{ {
bwoinkText = $"[color=purple]{senderSession.Name}[/color]: {escapedText}"; bwoinkText = $"[color=purple]{senderSession.Name}[/color]";
} }
else if (senderAdmin is not null && senderAdmin.HasFlag(AdminFlags.Adminhelp)) else if (senderAdmin is not null && senderAdmin.HasFlag(AdminFlags.Adminhelp))
{ {
bwoinkText = $"[color=red]{senderSession.Name}[/color]: {escapedText}"; bwoinkText = $"[color=red]{senderSession.Name}[/color]";
} }
else else
{ {
bwoinkText = $"{senderSession.Name}: {escapedText}"; bwoinkText = $"{senderSession.Name}";
} }
var msg = new BwoinkTextMessage(message.UserId, senderSession.UserId, bwoinkText); bwoinkText = $"{(message.PlaySound ? "" : "(S) ")}{bwoinkText}: {escapedText}";
var playSound = senderAHelpAdmin && message.PlaySound;
var msg = new BwoinkTextMessage(message.UserId, senderSession.UserId, bwoinkText, playSound: playSound);
LogBwoink(msg); LogBwoink(msg);
@@ -433,18 +436,20 @@ namespace Content.Server.Administration.Systems
// Doing the same thing as above, but with the override name. Theres probably a better way to do this. // Doing the same thing as above, but with the override name. Theres probably a better way to do this.
if (senderAdmin is not null && senderAdmin.Flags == AdminFlags.Adminhelp) // Mentor. Not full admin. That's why it's colored differently. if (senderAdmin is not null && senderAdmin.Flags == AdminFlags.Adminhelp) // Mentor. Not full admin. That's why it's colored differently.
{ {
overrideMsgText = $"[color=purple]{_overrideClientName}[/color]: {escapedText}"; overrideMsgText = $"[color=purple]{_overrideClientName}[/color]";
} }
else if (senderAdmin is not null && senderAdmin.HasFlag(AdminFlags.Adminhelp)) else if (senderAdmin is not null && senderAdmin.HasFlag(AdminFlags.Adminhelp))
{ {
overrideMsgText = $"[color=red]{_overrideClientName}[/color]: {escapedText}"; overrideMsgText = $"[color=red]{_overrideClientName}[/color]";
} }
else else
{ {
overrideMsgText = $"{senderSession.Name}: {escapedText}"; // Not an admin, name is not overridden. overrideMsgText = $"{senderSession.Name}"; // Not an admin, name is not overridden.
} }
RaiseNetworkEvent(new BwoinkTextMessage(message.UserId, senderSession.UserId, overrideMsgText), session.Channel); overrideMsgText = $"{(message.PlaySound ? "" : "(S) ")}{overrideMsgText}: {escapedText}";
RaiseNetworkEvent(new BwoinkTextMessage(message.UserId, senderSession.UserId, overrideMsgText, playSound: playSound), session.Channel);
} }
else else
RaiseNetworkEvent(msg, session.Channel); RaiseNetworkEvent(msg, session.Channel);
@@ -465,7 +470,7 @@ namespace Content.Server.Administration.Systems
str = str[..(DescriptionMax - _maxAdditionalChars - unameLength)]; str = str[..(DescriptionMax - _maxAdditionalChars - unameLength)];
} }
var nonAfkAdmins = GetNonAfkAdmins(); var nonAfkAdmins = GetNonAfkAdmins();
_messageQueues[msg.UserId].Enqueue(GenerateAHelpMessage(senderSession.Name, str, !personalChannel, _gameTicker.RoundDuration().ToString("hh\\:mm\\:ss"), _gameTicker.RunLevel, nonAfkAdmins.Count == 0)); _messageQueues[msg.UserId].Enqueue(GenerateAHelpMessage(senderSession.Name, str, !personalChannel, _gameTicker.RoundDuration().ToString("hh\\:mm\\:ss"), _gameTicker.RunLevel, playSound, nonAfkAdmins.Count == 0));
} }
if (admins.Count != 0 || sendsWebhook) if (admins.Count != 0 || sendsWebhook)
@@ -493,7 +498,7 @@ namespace Content.Server.Administration.Systems
.ToList(); .ToList();
} }
private static string GenerateAHelpMessage(string username, string message, bool admin, string roundTime, GameRunLevel roundState, bool noReceivers = false) private static string GenerateAHelpMessage(string username, string message, bool admin, string roundTime, GameRunLevel roundState, bool playedSound, bool noReceivers = false)
{ {
var stringbuilder = new StringBuilder(); var stringbuilder = new StringBuilder();
@@ -506,6 +511,8 @@ namespace Content.Server.Administration.Systems
if(roundTime != string.Empty && roundState == GameRunLevel.InRound) if(roundTime != string.Empty && roundState == GameRunLevel.InRound)
stringbuilder.Append($" **{roundTime}**"); stringbuilder.Append($" **{roundTime}**");
if (!playedSound)
stringbuilder.Append(" **(S)**");
stringbuilder.Append($" **{username}:** "); stringbuilder.Append($" **{username}:** ");
stringbuilder.Append(message); stringbuilder.Append(message);
return stringbuilder.ToString(); return stringbuilder.ToString();

View File

@@ -38,12 +38,15 @@ namespace Content.Shared.Administration
public NetUserId TrueSender { get; } public NetUserId TrueSender { get; }
public string Text { get; } public string Text { get; }
public BwoinkTextMessage(NetUserId userId, NetUserId trueSender, string text, DateTime? sentAt = default) public bool PlaySound { get; }
public BwoinkTextMessage(NetUserId userId, NetUserId trueSender, string text, DateTime? sentAt = default, bool playSound = true)
{ {
SentAt = sentAt ?? DateTime.Now; SentAt = sentAt ?? DateTime.Now;
UserId = userId; UserId = userId;
TrueSender = trueSender; TrueSender = trueSender;
Text = text; Text = text;
PlaySound = playSound;
} }
} }
} }

View File

@@ -10,3 +10,5 @@ bwoink-system-typing-indicator = {$players} {$count ->
[one] is [one] is
*[other] are *[other] are
} typing... } typing...
admin-bwoink-play-sound = Bwoink?