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;
///
/// 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.
///
public sealed class MOTDSystem : EntitySystem
{
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
///
/// The cached value of the Message of the Day. Used for fast access.
///
private string _messageOfTheDay = "";
public override void Initialize()
{
base.Initialize();
_configurationManager.OnValueChanged(CCVars.MOTD, OnMOTDChanged, invokeImmediately: true);
SubscribeLocalEvent(OnPlayerJoinedLobby);
}
public override void Shutdown()
{
_configurationManager.UnsubValueChanged(CCVars.MOTD, OnMOTDChanged);
base.Shutdown();
}
///
/// Sends the Message Of The Day, if any, to all connected players.
///
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);
}
///
/// Sends the Message Of The Day, if any, to a specific player.
///
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);
}
///
/// Sends the Message Of The Day, if any, to a specific player's console and chat.
///
///
/// 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.
///
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
///
/// Posts the Message Of The Day to any players who join the lobby.
///
private void OnPlayerJoinedLobby(PlayerJoinedLobbyEvent ev)
{
TrySendMOTD(ev.PlayerSession);
}
///
/// Broadcasts changes to the Message Of The Day to all players.
///
private void OnMOTDChanged(string val)
{
if (val == _messageOfTheDay)
return;
_messageOfTheDay = val;
TrySendMOTD();
}
#endregion Event Handlers
}