From 6af331c9ff8be54c3e53c67a4ecf1ec387a94234 Mon Sep 17 00:00:00 2001
From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Date: Wed, 23 Nov 2022 00:52:19 +1300
Subject: [PATCH] Remove StoredChatMessage (#12623)
---
Content.Client/Chat/StoredChatMessage.cs | 51 ----------
.../Systems/Chat/ChatUIController.cs | 20 ++--
.../Systems/Chat/Widgets/ChatBox.xaml.cs | 6 +-
Content.Server/Chat/Managers/ChatManager.cs | 78 +++++++--------
Content.Server/Chat/Managers/IChatManager.cs | 11 ++-
Content.Server/Chat/Systems/ChatSystem.cs | 56 ++++++-----
Content.Server/GameTicking/GameTicker.cs | 5 +-
.../GameTicking/Rules/ZombieRuleSystem.cs | 1 +
.../Radio/EntitySystems/RadioDeviceSystem.cs | 2 +-
.../Radio/EntitySystems/RadioSystem.cs | 19 ++--
Content.Shared/Chat/MsgChatMessage.cs | 94 +++++++------------
11 files changed, 131 insertions(+), 212 deletions(-)
delete mode 100644 Content.Client/Chat/StoredChatMessage.cs
diff --git a/Content.Client/Chat/StoredChatMessage.cs b/Content.Client/Chat/StoredChatMessage.cs
deleted file mode 100644
index 1d8d9c61f4..0000000000
--- a/Content.Client/Chat/StoredChatMessage.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Content.Shared.Chat;
-using Robust.Shared.Log;
-using Robust.Shared.Maths;
-
-namespace Content.Client.Chat
-{
- public sealed class StoredChatMessage
- {
- // TODO Make me reflected with respect to MsgChatMessage
-
- ///
- /// Client's own copies of chat messages used in filtering locally
- ///
-
- ///
- /// Actual Message contents, i.e. words
- ///
- public string Message { get; set; }
-
- ///
- /// Message channel, used for filtering
- ///
- public ChatChannel Channel { get; set; }
-
- ///
- /// Modified message with some wrapping text. E.g. 'Joe says: "HELP!"'
- ///
- public string WrappedMessage { get; set; }
-
- ///
- /// The override color of the message
- ///
- public Color MessageColorOverride { get; set; }
-
- ///
- /// Whether the user has read this message at least once.
- ///
- public bool Read { get; set; }
-
- ///
- /// Constructor to copy a net message into stored client variety
- ///
- public StoredChatMessage(MsgChatMessage netMsg)
- {
- Message = netMsg.Message;
- Channel = netMsg.Channel;
- WrappedMessage = netMsg.WrappedMessage;
- MessageColorOverride = netMsg.MessageColorOverride;
- }
- }
-}
diff --git a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
index fbc674bcf7..585a55e063 100644
--- a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
+++ b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
@@ -109,6 +109,7 @@ public sealed class ChatUIController : UIController
= new();
private readonly HashSet _chats = new();
+ public IReadOnlySet Chats => _chats;
///
/// The max amount of characters an entity can send in one message
@@ -121,7 +122,7 @@ public sealed class ChatUIController : UIController
///
private readonly Dictionary _unreadMessages = new();
- public readonly List History = new();
+ public readonly List History = new();
// Maintains which channels a client should be able to filter (for showing in the chatbox)
// and select (for attempting to send on).
@@ -142,7 +143,7 @@ public sealed class ChatUIController : UIController
public event Action? FilterableChannelsChanged;
public event Action? SelectableChannelsChanged;
public event Action? UnreadMessageCountsUpdated;
- public event Action? MessageAdded;
+ public event Action? MessageAdded;
public override void Initialize()
{
@@ -285,7 +286,7 @@ public sealed class ChatUIController : UIController
UpdateChannelPermissions();
}
- private void AddSpeechBubble(MsgChatMessage msg, SpeechBubble.SpeechType speechType)
+ private void AddSpeechBubble(ChatMessage msg, SpeechBubble.SpeechType speechType)
{
if (!_entities.EntityExists(msg.SenderEntity))
{
@@ -635,18 +636,19 @@ public sealed class ChatUIController : UIController
box.ChatInput.Input.ReleaseKeyboardFocus();
}
- private void OnChatMessage(MsgChatMessage msg)
+ private void OnChatMessage(MsgChatMessage message) => ProcessChatMessage(message.Message);
+
+ public void ProcessChatMessage(ChatMessage msg)
{
// Log all incoming chat to repopulate when filter is un-toggled
if (!msg.HideChat)
{
- var storedMessage = new StoredChatMessage(msg);
- History.Add(storedMessage);
- MessageAdded?.Invoke(storedMessage);
+ History.Add(msg);
+ MessageAdded?.Invoke(msg);
- if (!storedMessage.Read)
+ if (!msg.Read)
{
- _sawmill.Debug($"Message filtered: {storedMessage.Channel}: {storedMessage.Message}");
+ _sawmill.Debug($"Message filtered: {msg.Channel}: {msg.Message}");
if (!_unreadMessages.TryGetValue(msg.Channel, out var count))
count = 0;
diff --git a/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs b/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs
index a67740503e..663cb3dd0a 100644
--- a/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs
+++ b/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs
@@ -44,7 +44,7 @@ public partial class ChatBox : UIWidget
_controller.SendMessage(this, SelectedChannel);
}
- private void OnMessageAdded(StoredChatMessage msg)
+ private void OnMessageAdded(ChatMessage msg)
{
Logger.DebugS("chat", $"{msg.Channel}: {msg.Message}");
if (!ChatInput.FilterButton.ChatFilterPopup.IsActive(msg.Channel))
@@ -54,8 +54,8 @@ public partial class ChatBox : UIWidget
msg.Read = true;
- var color = msg.MessageColorOverride != Color.Transparent
- ? msg.MessageColorOverride
+ var color = msg.MessageColorOverride != null
+ ? msg.MessageColorOverride.Value
: msg.Channel.TextColor();
AddLine(msg.WrappedMessage, color);
diff --git a/Content.Server/Chat/Managers/ChatManager.cs b/Content.Server/Chat/Managers/ChatManager.cs
index e32542a5d6..e9f16334fa 100644
--- a/Content.Server/Chat/Managers/ChatManager.cs
+++ b/Content.Server/Chat/Managers/ChatManager.cs
@@ -13,6 +13,7 @@ using Robust.Shared.Configuration;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Player;
+using Robust.Shared.Replays;
using Robust.Shared.Utility;
namespace Content.Server.Chat.Managers
@@ -30,15 +31,13 @@ namespace Content.Server.Chat.Managers
{ "revolutionary", "#aa00ff" }
};
+ [Dependency] private readonly IReplayRecordingManager _replay = default!;
[Dependency] private readonly IServerNetManager _netManager = default!;
[Dependency] private readonly IMoMMILink _mommiLink = default!;
[Dependency] private readonly IAdminManager _adminManager = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IServerPreferencesManager _preferencesManager = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
- [Dependency] private readonly IEntityManager _entityManager = default!;
-
- private StationSystem _stationSystem = default!;
///
/// The maximum length a player-sent message can be sent
@@ -50,7 +49,6 @@ namespace Content.Server.Chat.Managers
public void Initialize()
{
- _stationSystem = _entityManager.EntitySysManager.GetEntitySystem();
_netManager.RegisterNetMessage();
_configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true);
@@ -78,7 +76,7 @@ namespace Content.Server.Chat.Managers
public void DispatchServerAnnouncement(string message, Color? colorOverride = null)
{
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", FormattedMessage.EscapeText(message)));
- ChatMessageToAll(ChatChannel.Server, message, wrappedMessage, colorOverride);
+ ChatMessageToAll(ChatChannel.Server, message, wrappedMessage, EntityUid.Invalid, hideChat: false, recordReplay: true, colorOverride: colorOverride);
Logger.InfoS("SERVER", message);
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Server announcement: {message}");
@@ -99,7 +97,7 @@ namespace Content.Server.Chat.Managers
var wrappedMessage = Loc.GetString("chat-manager-send-admin-announcement-wrap-message",
("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")), ("message", FormattedMessage.EscapeText(message)));
- ChatMessageToMany(ChatChannel.Admin, message, wrappedMessage, default, false, clients);
+ ChatMessageToMany(ChatChannel.Admin, message, wrappedMessage, default, false, true, clients);
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Admin announcement from {message}: {message}");
}
@@ -110,7 +108,7 @@ namespace Content.Server.Chat.Managers
return;
}
var wrappedMessage = Loc.GetString("chat-manager-send-hook-ooc-wrap-message", ("senderName", sender), ("message", FormattedMessage.EscapeText(message)));
- ChatMessageToAll(ChatChannel.OOC, message, wrappedMessage);
+ ChatMessageToAll(ChatChannel.OOC, message, wrappedMessage, source: EntityUid.Invalid, hideChat: false, recordReplay: true);
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Hook OOC from {sender}: {message}");
}
@@ -176,7 +174,7 @@ namespace Content.Server.Chat.Managers
}
//TODO: player.Name color, this will need to change the structure of the MsgChatMessage
- ChatMessageToAll(ChatChannel.OOC, message, wrappedMessage, colorOverride);
+ ChatMessageToAll(ChatChannel.OOC, message, wrappedMessage, EntityUid.Invalid, hideChat: false, recordReplay: true, colorOverride);
_mommiLink.SendOOCMessage(player.Name, message);
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"OOC from {player:Player}: {message}");
}
@@ -193,7 +191,7 @@ namespace Content.Server.Chat.Managers
var wrappedMessage = Loc.GetString("chat-manager-send-admin-chat-wrap-message",
("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")),
("playerName", player.Name), ("message", FormattedMessage.EscapeText(message)));
- ChatMessageToMany(ChatChannel.Admin, message, wrappedMessage, default, false, clients.ToList());
+ ChatMessageToMany(ChatChannel.Admin, message, wrappedMessage, default, false, true, clients.ToList());
_adminLogger.Add(LogType.Chat, $"Admin chat from {player:Player}: {message}");
}
@@ -202,40 +200,32 @@ namespace Content.Server.Chat.Managers
#region Utility
- public void ChatMessageToOne(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, INetChannel client, Color? colorOverride = null)
+ public void ChatMessageToOne(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, INetChannel client, Color? colorOverride = null, bool recordReplay = false)
{
- var msg = new MsgChatMessage();
- msg.Channel = channel;
- msg.Message = message;
- msg.WrappedMessage = wrappedMessage;
- msg.SenderEntity = source;
- msg.HideChat = hideChat;
- if (colorOverride != null)
- {
- msg.MessageColorOverride = colorOverride.Value;
- }
- _netManager.ServerSendMessage(msg, client);
+ var msg = new ChatMessage(channel, message, wrappedMessage, source, hideChat, colorOverride);
+ _netManager.ServerSendMessage(new MsgChatMessage() { Message = msg }, client);
+
+ if (recordReplay)
+ _replay.QueueReplayMessage(msg);
}
- public void ChatMessageToMany(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, IEnumerable clients, Color? colorOverride = null)
+ public void ChatMessageToMany(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, IEnumerable clients, Color? colorOverride = null)
+ => ChatMessageToMany(channel, message, wrappedMessage, source, hideChat, recordReplay, clients.ToList(), colorOverride);
+
+ public void ChatMessageToMany(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, List clients, Color? colorOverride = null)
{
- var msg = new MsgChatMessage();
- msg.Channel = channel;
- msg.Message = message;
- msg.WrappedMessage = wrappedMessage;
- msg.SenderEntity = source;
- msg.HideChat = hideChat;
- if (colorOverride != null)
- {
- msg.MessageColorOverride = colorOverride.Value;
- }
- _netManager.ServerSendToMany(msg, clients.ToList());
+ var msg = new ChatMessage(channel, message, wrappedMessage, source, hideChat, colorOverride);
+ _netManager.ServerSendToMany(new MsgChatMessage() { Message = msg }, clients);
+
+ if (recordReplay)
+ _replay.QueueReplayMessage(msg);
}
public void ChatMessageToManyFiltered(Filter filter, ChatChannel channel, string message, string wrappedMessage, EntityUid source,
- bool hideChat, Color? colorOverride = null)
+ bool hideChat, bool recordReplay, Color? colorOverride = null)
{
- if (!filter.Recipients.Any()) return;
+ if (!recordReplay && !filter.Recipients.Any())
+ return;
var clients = new List();
foreach (var recipient in filter.Recipients)
@@ -243,20 +233,16 @@ namespace Content.Server.Chat.Managers
clients.Add(recipient.ConnectedClient);
}
- ChatMessageToMany(channel, message, wrappedMessage, source, hideChat, clients, colorOverride);
+ ChatMessageToMany(channel, message, wrappedMessage, source, hideChat, recordReplay, clients, colorOverride);
}
- public void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, Color? colorOverride = null)
+ public void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride = null)
{
- var msg = new MsgChatMessage();
- msg.Channel = channel;
- msg.Message = message;
- msg.WrappedMessage = wrappedMessage;
- if (colorOverride != null)
- {
- msg.MessageColorOverride = colorOverride.Value;
- }
- _netManager.ServerSendToAll(msg);
+ var msg = new ChatMessage(channel, message, wrappedMessage, source, hideChat, colorOverride);
+ _netManager.ServerSendToAll(new MsgChatMessage() { Message = msg });
+
+ if (recordReplay)
+ _replay.QueueReplayMessage(msg);
}
public bool MessageCharacterLimit(IPlayerSession? player, string message)
diff --git a/Content.Server/Chat/Managers/IChatManager.cs b/Content.Server/Chat/Managers/IChatManager.cs
index a38005cebd..cbf5814c36 100644
--- a/Content.Server/Chat/Managers/IChatManager.cs
+++ b/Content.Server/Chat/Managers/IChatManager.cs
@@ -24,11 +24,14 @@ namespace Content.Server.Chat.Managers
void SendAdminAnnouncement(string message);
void ChatMessageToOne(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat,
- INetChannel client, Color? colorOverride = null);
- void ChatMessageToMany(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat,
+ INetChannel client, Color? colorOverride = null, bool recordReplay = false);
+
+ void ChatMessageToMany(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay,
IEnumerable clients, Color? colorOverride = null);
- void ChatMessageToManyFiltered(Filter filter, ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, Color? colorOverride);
- void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, Color? colorOverride = null);
+
+ void ChatMessageToManyFiltered(Filter filter, ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride);
+
+ void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride = null);
bool MessageCharacterLimit(IPlayerSession player, string message);
}
diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs
index 843b0fc011..499784fe3b 100644
--- a/Content.Server/Chat/Systems/ChatSystem.cs
+++ b/Content.Server/Chat/Systems/ChatSystem.cs
@@ -1,24 +1,22 @@
using System.Linq;
using System.Text;
-using System.Text.RegularExpressions;
using Content.Server.Administration.Logs;
using Content.Server.Administration.Managers;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Server.Ghost.Components;
-using Content.Server.Mind.Components;
+using Content.Server.MobState;
using Content.Server.Players;
using Content.Server.Popups;
-using Content.Server.Radio.EntitySystems;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
-using Content.Server.MobState;
using Content.Shared.ActionBlocker;
using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Database;
using Content.Shared.IdentityManagement;
using Content.Shared.Inventory;
+using Content.Shared.Radio;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Audio;
@@ -29,9 +27,8 @@ using Robust.Shared.Player;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
+using Robust.Shared.Replays;
using Robust.Shared.Utility;
-using Content.Server.Speech.EntitySystems;
-using Content.Shared.Radio;
namespace Content.Server.Chat.Systems;
@@ -41,6 +38,7 @@ namespace Content.Server.Chat.Systems;
///
public sealed partial class ChatSystem : SharedChatSystem
{
+ [Dependency] private readonly IReplayRecordingManager _replay = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IChatSanitizationManager _sanitizer = default!;
@@ -119,7 +117,7 @@ public sealed partial class ChatSystem : SharedChatSystem
/// The player doing the speaking
/// The name to use for the speaking entity. Usually this should just be modified via . If this is set, the event will not get raised.
public void TrySendInGameICMessage(EntityUid source, string message, InGameICChatType desiredType, bool hideChat, bool hideGlobalGhostChat = false,
- IConsoleShell? shell = null, IPlayerSession? player = null, string? nameOverride = null)
+ IConsoleShell? shell = null, IPlayerSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true)
{
if (HasComp(source))
{
@@ -157,7 +155,7 @@ public sealed partial class ChatSystem : SharedChatSystem
switch (desiredType)
{
case InGameICChatType.Speak:
- SendEntitySpeak(source, message, hideChat, hideGlobalGhostChat, nameOverride);
+ SendEntitySpeak(source, message, hideChat, hideGlobalGhostChat, nameOverride, checkRadioPrefix);
break;
case InGameICChatType.Whisper:
SendEntityWhisper(source, message, hideChat, hideGlobalGhostChat, null, nameOverride);
@@ -211,7 +209,7 @@ public sealed partial class ChatSystem : SharedChatSystem
bool playSound = true, SoundSpecifier? announcementSound = null, Color? colorOverride = null)
{
var wrappedMessage = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender), ("message", FormattedMessage.EscapeText(message)));
- _chatManager.ChatMessageToAll(ChatChannel.Radio, message, wrappedMessage, colorOverride);
+ _chatManager.ChatMessageToAll(ChatChannel.Radio, message, wrappedMessage, default, false, true, colorOverride);
if (playSound)
{
SoundSystem.Play(announcementSound?.GetSound() ?? DefaultAnnouncementSound, Filter.Broadcast(), AudioParams.Default.WithVolume(-2f));
@@ -243,7 +241,7 @@ public sealed partial class ChatSystem : SharedChatSystem
var filter = _stationSystem.GetInStation(stationDataComp);
- _chatManager.ChatMessageToManyFiltered(filter, ChatChannel.Radio, message, wrappedMessage, source, false, colorOverride);
+ _chatManager.ChatMessageToManyFiltered(filter, ChatChannel.Radio, message, wrappedMessage, source, false, true, colorOverride);
if (playDefaultSound)
{
@@ -257,12 +255,18 @@ public sealed partial class ChatSystem : SharedChatSystem
#region Private API
- private void SendEntitySpeak(EntityUid source, string originalMessage, bool hideChat, bool hideGlobalGhostChat, string? nameOverride)
+ private void SendEntitySpeak(EntityUid source, string originalMessage, bool hideChat, bool hideGlobalGhostChat, string? nameOverride, bool checkRadioPrefix)
{
if (!_actionBlocker.CanSpeak(source))
return;
- var (message, channel) = GetRadioPrefix(source, originalMessage);
+ RadioChannelPrototype? channel = null;
+ string message;
+
+ if (checkRadioPrefix)
+ (message, channel) = GetRadioPrefix(source, originalMessage);
+ else
+ message = originalMessage;
if (channel != null)
{
@@ -331,6 +335,15 @@ public sealed partial class ChatSystem : SharedChatSystem
}
name = FormattedMessage.EscapeText(name);
+
+ var wrappedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message",
+ ("entityName", name), ("message", FormattedMessage.EscapeText(message)));
+
+
+ var wrappedobfuscatedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message",
+ ("entityName", name), ("message", FormattedMessage.EscapeText(obfuscatedMessage)));
+
+
foreach (var (session, data) in GetRecipients(source, VoiceRange))
{
if (session.AttachedEntity is not { Valid: true } playerEntity)
@@ -340,22 +353,13 @@ public sealed partial class ChatSystem : SharedChatSystem
continue; // Won't get logged to chat, and ghosts are too far away to see the pop-up, so we just won't send it to them.
if (data.Range <= WhisperRange)
- {
- var wrappedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message",
- ("entityName", name), ("message", FormattedMessage.EscapeText(message)));
-
_chatManager.ChatMessageToOne(ChatChannel.Whisper, message, wrappedMessage, source, data.HideChatOverride ?? hideChat, session.ConnectedClient);
- }
else
- {
- var wrappedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message",
- ("entityName", name), ("message", FormattedMessage.EscapeText(obfuscatedMessage)));
-
- _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedMessage, source, data.HideChatOverride ?? hideChat,
- session.ConnectedClient);
- }
+ _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedobfuscatedMessage, source, data.HideChatOverride ?? hideChat, session.ConnectedClient);
}
+ _replay.QueueReplayMessage(new ChatMessage(ChatChannel.Whisper, message, wrappedMessage, source, hideChat));
+
var ev = new EntitySpokeEvent(source, message, channel, obfuscatedMessage);
RaiseLocalEvent(source, ev, true);
@@ -421,7 +425,7 @@ public sealed partial class ChatSystem : SharedChatSystem
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Dead chat from {player:Player}: {message}");
}
- _chatManager.ChatMessageToMany(ChatChannel.Dead, message, wrappedMessage, source, hideChat, clients.ToList());
+ _chatManager.ChatMessageToMany(ChatChannel.Dead, message, wrappedMessage, source, hideChat, false, clients.ToList());
}
#endregion
@@ -438,6 +442,8 @@ public sealed partial class ChatSystem : SharedChatSystem
var entHideChat = data.HideChatOverride ?? (hideChat || hideGlobalGhostChat && data.Observer && data.Range < 0);
_chatManager.ChatMessageToOne(channel, message, wrappedMessage, source, entHideChat, session.ConnectedClient);
}
+
+ _replay.QueueReplayMessage(new ChatMessage(channel, message, wrappedMessage, source, hideChat));
}
///
diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs
index ec21e456ef..89e2d3c504 100644
--- a/Content.Server/GameTicking/GameTicker.cs
+++ b/Content.Server/GameTicking/GameTicker.cs
@@ -85,10 +85,7 @@ namespace Content.Server.GameTicking
private void SendServerMessage(string message)
{
- var msg = new MsgChatMessage();
- msg.Channel = ChatChannel.Server;
- msg.Message = message;
- IoCManager.Resolve().ServerSendToAll(msg);
+ _chatManager.ChatMessageToAll(ChatChannel.Server, message, "", default, false, true);
}
public override void Update(float frameTime)
diff --git a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs
index e587810a12..fc45058211 100644
--- a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs
+++ b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs
@@ -306,6 +306,7 @@ public sealed class ZombieRuleSystem : GameRuleSystem
_initialInfectedNames.Add(inCharacterName, mind.Session.Name);
// I went all the way to ChatManager.cs and all i got was this lousy T-shirt
+ // You got a free T-shirt!?!?
_chatManager.ChatMessageToOne(Shared.Chat.ChatChannel.Server, message,
wrappedMessage, default, false, mind.Session.ConnectedClient, Color.Plum);
}
diff --git a/Content.Server/Radio/EntitySystems/RadioDeviceSystem.cs b/Content.Server/Radio/EntitySystems/RadioDeviceSystem.cs
index 0afb003fdb..8d192c4de0 100644
--- a/Content.Server/Radio/EntitySystems/RadioDeviceSystem.cs
+++ b/Content.Server/Radio/EntitySystems/RadioDeviceSystem.cs
@@ -143,6 +143,6 @@ public sealed class RadioDeviceSystem : EntitySystem
("originalName", nameEv.Name));
var hideGlobalGhostChat = true; // log to chat so people can identity the speaker/source, but avoid clogging ghost chat if there are many radios
- _chat.TrySendInGameICMessage(uid, args.Message, InGameICChatType.Speak, false, nameOverride: name, hideGlobalGhostChat:hideGlobalGhostChat);
+ _chat.TrySendInGameICMessage(uid, args.Message, InGameICChatType.Speak, false, nameOverride: name, hideGlobalGhostChat:hideGlobalGhostChat, checkRadioPrefix: false);
}
}
diff --git a/Content.Server/Radio/EntitySystems/RadioSystem.cs b/Content.Server/Radio/EntitySystems/RadioSystem.cs
index a5dd5a2f2b..27c39c168d 100644
--- a/Content.Server/Radio/EntitySystems/RadioSystem.cs
+++ b/Content.Server/Radio/EntitySystems/RadioSystem.cs
@@ -1,22 +1,23 @@
using Content.Server.Chat.Systems;
using Content.Server.Radio.Components;
-using Content.Server.Speech;
using Content.Server.VoiceMask;
using Content.Shared.Chat;
using Content.Shared.IdentityManagement;
using Content.Shared.Radio;
using Robust.Server.GameObjects;
using Robust.Shared.Network;
+using Robust.Shared.Replays;
using Robust.Shared.Utility;
namespace Content.Server.Radio.EntitySystems;
///
-/// This system handles radio speakers and microphones (which together form a hand-held radio).
+/// This system handles intrinsic radios and the general process of converting radio messages into chat messages.
///
public sealed class RadioSystem : EntitySystem
{
[Dependency] private readonly INetManager _netMan = default!;
+ [Dependency] private readonly IReplayRecordingManager _replay = default!;
// set used to prevent radio feedback loops.
private readonly HashSet _messages = new();
@@ -56,13 +57,12 @@ public sealed class RadioSystem : EntitySystem
name = FormattedMessage.EscapeText(name);
// most radios are relayed to chat, so lets parse the chat message beforehand
- var chatMsg = new MsgChatMessage
- {
- Channel = ChatChannel.Radio,
- Message = message,
- //Square brackets are added here to avoid issues with escaping
- WrappedMessage = Loc.GetString("chat-radio-message-wrap", ("color", channel.Color), ("channel", $"\\[{channel.LocalizedName}\\]"), ("name", name), ("message", FormattedMessage.EscapeText(message)))
- };
+ var chat = new ChatMessage(
+ ChatChannel.Radio,
+ message,
+ Loc.GetString("chat-radio-message-wrap", ("color", channel.Color), ("channel", $"\\[{channel.LocalizedName}\\]"), ("name", name), ("message", FormattedMessage.EscapeText(message))),
+ EntityUid.Invalid);
+ var chatMsg = new MsgChatMessage { Message = chat };
var ev = new RadioReceiveEvent(message, source, channel, chatMsg);
var attemptEv = new RadioReceiveAttemptEvent(message, source, channel);
@@ -84,6 +84,7 @@ public sealed class RadioSystem : EntitySystem
RaiseLocalEvent(radio.Owner, ev);
}
+ _replay.QueueReplayMessage(chat);
_messages.Remove(message);
}
}
diff --git a/Content.Shared/Chat/MsgChatMessage.cs b/Content.Shared/Chat/MsgChatMessage.cs
index 980d5578dd..4497ef8f7f 100644
--- a/Content.Shared/Chat/MsgChatMessage.cs
+++ b/Content.Shared/Chat/MsgChatMessage.cs
@@ -2,9 +2,35 @@ using JetBrains.Annotations;
using Lidgren.Network;
using Robust.Shared.Network;
using Robust.Shared.Serialization;
+using Robust.Shared.Utility;
+using System.IO;
namespace Content.Shared.Chat
{
+ [Serializable, NetSerializable]
+ public sealed class ChatMessage
+ {
+ public ChatChannel Channel;
+ public string Message;
+ public string WrappedMessage;
+ public EntityUid SenderEntity;
+ public bool HideChat;
+ public Color? MessageColorOverride;
+
+ [NonSerialized]
+ public bool Read;
+
+ public ChatMessage(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat = false, Color? colorOverride = null)
+ {
+ Channel = channel;
+ Message = message;
+ WrappedMessage = wrappedMessage;
+ SenderEntity = source;
+ HideChat = hideChat;
+ MessageColorOverride = colorOverride;
+ }
+ }
+
///
/// Sent from server to client to notify the client about a new chat message.
///
@@ -13,73 +39,21 @@ namespace Content.Shared.Chat
{
public override MsgGroups MsgGroup => MsgGroups.Command;
- ///
- /// The channel the message is on. This can also change whether certain params are used.
- ///
- public ChatChannel Channel { get; set; }
-
- ///
- /// The actual message contents.
- ///
- public string Message { get; set; } = string.Empty;
-
- ///
- /// Modified message with some wrapping text. E.g. 'Joe says: "HELP!"'
- ///
- public string WrappedMessage { get; set; } = string.Empty;
-
- ///
- /// The sending entity.
- /// Only applies to , and .
- ///
- public EntityUid SenderEntity { get; set; }
-
- ///
- /// The override color of the message
- ///
- public Color MessageColorOverride { get; set; } = Color.Transparent;
-
- public bool HideChat { get; set; }
-
+ public ChatMessage Message = default!;
public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
{
- Channel = (ChatChannel) buffer.ReadInt16();
- Message = buffer.ReadString();
- WrappedMessage = buffer.ReadString();
-
- switch (Channel)
- {
- case ChatChannel.Local:
- case ChatChannel.Whisper:
- case ChatChannel.Dead:
- case ChatChannel.Admin:
- case ChatChannel.Emotes:
- SenderEntity = buffer.ReadEntityUid();
- break;
- }
- MessageColorOverride = buffer.ReadColor();
- HideChat = buffer.ReadBoolean();
+ var length = buffer.ReadVariableInt32();
+ using var stream = buffer.ReadAlignedMemory(length);
+ serializer.DeserializeDirect(stream, out Message);
}
public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer)
{
- buffer.Write((short)Channel);
- buffer.Write(Message);
- buffer.Write(WrappedMessage);
-
- switch (Channel)
- {
- case ChatChannel.Local:
- case ChatChannel.Whisper:
- case ChatChannel.Dead:
- case ChatChannel.Admin:
- case ChatChannel.Emotes:
- buffer.Write(SenderEntity);
- break;
- }
- buffer.Write(MessageColorOverride);
- buffer.Write(HideChat);
+ var stream = new MemoryStream();
+ serializer.SerializeDirect(stream, Message);
+ buffer.WriteVariableInt32((int) stream.Length);
+ buffer.Write(stream.AsSpan());
}
}
}