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 }