* MOTD

* Message of the Day

* Pretty sure the tests aren't me. Let's check.

* Update Content.Shared/CCVar/CCVars.cs

Co-authored-by: AJCM-git <60196617+AJCM-git@users.noreply.github.com>

* command dependencies and moving MOTD to its own system

* Some doc comments

* Let's try those tests again

* More doc comments, most of the github reviews, and aliases for get-motd and set-motd

* Clear test MOTD

* Localized motd commands and completion hints

* Makes set-motd only show up in the alias command if the player has access to it.

---------

Co-authored-by: AJCM-git <60196617+AJCM-git@users.noreply.github.com>
This commit is contained in:
TemporalOroboros
2023-02-28 08:15:48 -08:00
committed by GitHub
parent c8d9d05bcf
commit 93ec824d57
7 changed files with 244 additions and 7 deletions

View File

@@ -77,6 +77,7 @@ public sealed partial class ChatSystem : SharedChatSystem
base.Shutdown();
ShutdownEmotes();
_configurationManager.UnsubValueChanged(CCVars.LoocEnabled, OnLoocEnabledChanged);
_configurationManager.UnsubValueChanged(CCVars.DeadLoocEnabled, OnDeadLoocEnabledChanged);
}
private void OnLoocEnabledChanged(bool val)
@@ -99,13 +100,17 @@ public sealed partial class ChatSystem : SharedChatSystem
private void OnGameChange(GameRunLevelChangedEvent ev)
{
if (_configurationManager.GetCVar(CCVars.OocEnableDuringRound))
return;
if (ev.New == GameRunLevel.InRound)
_configurationManager.SetCVar(CCVars.OocEnabled, false);
else if (ev.New == GameRunLevel.PostRound)
_configurationManager.SetCVar(CCVars.OocEnabled, true);
switch(ev.New)
{
case GameRunLevel.InRound:
if(!_configurationManager.GetCVar(CCVars.OocEnableDuringRound))
_configurationManager.SetCVar(CCVars.OocEnabled, false);
break;
case GameRunLevel.PostRound:
if(!_configurationManager.GetCVar(CCVars.OocEnableDuringRound))
_configurationManager.SetCVar(CCVars.OocEnabled, true);
break;
}
}
/// <summary>

View File

@@ -0,0 +1,20 @@
using Content.Shared.Administration;
using Robust.Shared.Console;
namespace Content.Server.Motd;
/// <summary>
/// A command that can be used by any player to print the Message of the Day.
/// </summary>
[AnyCommand]
public sealed class GetMotdCommand : LocalizedCommands
{
[Dependency] private readonly IEntityManager _entityManager = default!;
public override string Command => "get-motd";
public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
_entityManager.EntitySysManager.GetEntitySystem<MOTDSystem>().TrySendMOTD(shell);
}
}

View File

@@ -0,0 +1,36 @@
using Content.Server.Administration.Managers;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Motd;
/// <summary>
/// A console command which acts as an alias for <see cref="GetMotdCommand"/> or <see cref="SetMotdCommand"/> depending on the number of arguments given.
/// </summary>
[AnyCommand]
internal sealed class MOTDCommand : LocalizedCommands
{
[Dependency] private readonly IAdminManager _adminManager = default!;
public override string Command => "motd";
public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = (IPlayerSession?)shell.Player;
if (args.Length < 1 || (player != null && _adminManager is AdminManager aMan && !aMan.CanCommand(player, "set-motd")))
shell.ConsoleHost.ExecuteCommand(shell.Player, "get-motd");
else
shell.ConsoleHost.ExecuteCommand(shell.Player, $"set-motd {string.Join(" ", args)}");
}
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
var player = (IPlayerSession?)shell.Player;
if (player != null && _adminManager is AdminManager aMan && !aMan.CanCommand(player, "set-motd"))
return CompletionResult.Empty;
if (args.Length == 1)
return CompletionResult.FromHint(Loc.GetString("cmd-set-motd-hint-head"));
return CompletionResult.FromHint(Loc.GetString("cmd-set-motd-hint-cont"));
}
}

View File

@@ -0,0 +1,101 @@
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Shared.CCVar;
using Content.Shared.Chat;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Configuration;
namespace Content.Server.Motd;
/// <summary>
/// The system that handles broadcasting the Message Of The Day to players when they join the lobby/the MOTD changes/they ask for it to be printed.
/// </summary>
public sealed class MOTDSystem : EntitySystem
{
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
/// <summary>
/// The cached value of the Message of the Day. Used for fast access.
/// </summary>
private string _messageOfTheDay = "";
public override void Initialize()
{
base.Initialize();
_configurationManager.OnValueChanged(CCVars.MOTD, OnMOTDChanged, invokeImmediately: true);
SubscribeLocalEvent<PlayerJoinedLobbyEvent>(OnPlayerJoinedLobby);
}
public override void Shutdown()
{
_configurationManager.UnsubValueChanged(CCVars.MOTD, OnMOTDChanged);
base.Shutdown();
}
/// <summary>
/// Sends the Message Of The Day, if any, to all connected players.
/// </summary>
public void TrySendMOTD()
{
if (string.IsNullOrEmpty(_messageOfTheDay))
return;
var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay));
_chatManager.ChatMessageToAll(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, recordReplay: true);
}
/// <summary>
/// Sends the Message Of The Day, if any, to a specific player.
/// </summary>
public void TrySendMOTD(IPlayerSession player)
{
if (string.IsNullOrEmpty(_messageOfTheDay))
return;
var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay));
_chatManager.ChatMessageToOne(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, client: player.ConnectedClient);
}
/// <summary>
/// Sends the Message Of The Day, if any, to a specific player's console and chat.
/// </summary>
/// <remarks>
/// This is used by the MOTD console command because we can't tell whether the player is using `console or /console so we send the message to both.
/// </remarks>
public void TrySendMOTD(IConsoleShell shell)
{
if (string.IsNullOrEmpty(_messageOfTheDay))
return;
var wrappedMessage = Loc.GetString("motd-wrap-message", ("motd", _messageOfTheDay));
shell.WriteLine(wrappedMessage);
if (shell.Player is IPlayerSession player)
_chatManager.ChatMessageToOne(ChatChannel.Server, _messageOfTheDay, wrappedMessage, source: EntityUid.Invalid, hideChat: false, client: player.ConnectedClient);
}
#region Event Handlers
/// <summary>
/// Posts the Message Of The Day to any players who join the lobby.
/// </summary>
private void OnPlayerJoinedLobby(PlayerJoinedLobbyEvent ev)
{
TrySendMOTD(ev.PlayerSession);
}
/// <summary>
/// Broadcasts changes to the Message Of The Day to all players.
/// </summary>
private void OnMOTDChanged(string val)
{
if (val == _messageOfTheDay)
return;
_messageOfTheDay = val;
TrySendMOTD();
}
#endregion Event Handlers
}

View File

@@ -0,0 +1,55 @@
using Content.Server.Administration;
using Content.Server.Administration.Logs;
using Content.Shared.Administration;
using Content.Shared.Database;
using Content.Shared.CCVar;
using Content.Server.Chat.Managers;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
namespace Content.Server.Motd;
/// <summary>
/// A console command usable by any user which prints or sets the Message of the Day.
/// </summary>
[AdminCommand(AdminFlags.Admin)]
public sealed class SetMotdCommand : LocalizedCommands
{
[Dependency] private readonly IAdminLogManager _adminLogManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
public override string Command => "set-motd";
public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
string motd = "";
var player = (IPlayerSession?)shell.Player;
if (args.Length > 0)
{
motd = string.Join(" ", args).Trim();
if (player != null && _chatManager.MessageCharacterLimit(player, motd))
return; // check function prints its own error response
}
_configurationManager.SetCVar(CCVars.MOTD, motd); // A hook in MOTDSystem broadcasts changes to the MOTD to everyone so we don't need to do it here.
if (string.IsNullOrEmpty(motd))
{
shell.WriteLine(Loc.GetString("cmd-set-motd-cleared-motd-message"));
_adminLogManager.Add(LogType.Chat, LogImpact.Low, $"{(player == null ? "LOCALHOST" : player.ConnectedClient.UserName):Player} cleared the MOTD for the server.");
}
else
{
shell.WriteLine(Loc.GetString("cmd-set-motd-set-motd-message", ("motd", motd)));
_adminLogManager.Add(LogType.Chat, LogImpact.Low, $"{(player == null ? "LOCALHOST" : player.ConnectedClient.UserName):Player} set the MOTD for the server to \"{motd:motd}\"");
}
}
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
if (args.Length == 1)
return CompletionResult.FromHint(Loc.GetString("cmd-set-motd-hint-head"));
return CompletionResult.FromHint(Loc.GetString("cmd-set-motd-hint-cont"));
}
}