From 899d6cf6987b7ff3a143f7707aba28bde38700bc Mon Sep 17 00:00:00 2001 From: Remuchi Date: Sun, 28 Jan 2024 16:31:58 +0700 Subject: [PATCH] =?UTF-8?q?fix:=20=D1=84=D0=B8=D0=BA=D1=81=20=D1=87=D0=B0?= =?UTF-8?q?=D1=82=D0=B1=D0=B0=D0=B1=D0=BB=D0=B0=20=D0=BA=D1=83=D0=BB=D1=8C?= =?UTF-8?q?=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Content.Server/Chat/Commands/CultCommand.cs | 9 +- Content.Server/Chat/Systems/ChatSystem.cs | 262 ++++++++++++++------ Resources/Locale/ru-RU/White/cult.ftl | 2 +- 3 files changed, 192 insertions(+), 81 deletions(-) diff --git a/Content.Server/Chat/Commands/CultCommand.cs b/Content.Server/Chat/Commands/CultCommand.cs index 6d037e6f19..bb080ff3bf 100644 --- a/Content.Server/Chat/Commands/CultCommand.cs +++ b/Content.Server/Chat/Commands/CultCommand.cs @@ -1,11 +1,8 @@ using Content.Server.Chat.Systems; using Content.Shared.Administration; -using Content.Shared.Chat; using Content.Shared.White.Cult; -using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Enums; -using Robust.Shared.Player; namespace Content.Server.Chat.Commands { @@ -13,7 +10,9 @@ namespace Content.Server.Chat.Commands internal sealed class CultCommand : IConsoleCommand { public string Command => "csay"; + public string Description => "Send cult message"; + public string Help => "csay "; public void Execute(IConsoleShell shell, string argStr, string[] args) @@ -43,7 +42,9 @@ namespace Content.Server.Chat.Commands var message = string.Join(" ", args).Trim(); if (string.IsNullOrEmpty(message)) return; - EntitySystem.Get().TrySendInGameOOCMessage(entity, message, InGameOOCChatType.Cult, false, shell, player); + + entityManager.System() + .TrySendInGameOOCMessage(entity, message, InGameOOCChatType.Cult, false, shell, player); } } } diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 99114af14a..287b510377 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -6,10 +6,6 @@ using Content.Server.Chat.Managers; using Content.Server.GameTicking; using Content.Server.Speech.Components; using Content.Server.Speech.EntitySystems; -using Content.Server.Ghost.Components; -using Content.Server.Players; -using Content.Server.Popups; -using Content.Server.Speech.Components; using Content.Server.Station.Components; using Content.Server.Station.Systems; using Content.Server.White.AspectsSystem.Aspects.Components; @@ -22,7 +18,6 @@ using Content.Shared.Chat; using Content.Shared.Database; using Content.Shared.Decals; using Content.Shared.Ghost; -using Content.Shared.Humanoid; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Mobs.Systems; @@ -69,14 +64,14 @@ public sealed partial class ChatSystem : SharedChatSystem [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly ReplacementAccentSystem _wordreplacement = default!; [Dependency] private readonly INetConfigurationManager _netConfigurationManager = default!; // WD - [Dependency] private readonly GameTicker _gameTicker = default!; // WD + [Dependency] private readonly GameTicker _gameTicker = default!; // WD //WD-EDIT [Dependency] private readonly PandaWebManager _pandaWeb = default!; //WD-EDIT - public const int VoiceRange = 10; // how far voice goes in world units - public const int WhisperClearRange = 2; // how far whisper goes while still being understandable, in world units + public const int VoiceRange = 10; // how far voice goes in world units + public const int WhisperClearRange = 2; // how far whisper goes while still being understandable, in world units public const int WhisperMuffledRange = 5; // how far whisper goes at all, in world units public const string DefaultAnnouncementSound = "/Audio/Announcements/announce.ogg"; @@ -84,9 +79,9 @@ public sealed partial class ChatSystem : SharedChatSystem private bool _deadLoocEnabled; private bool _critLoocEnabled; private const bool AdminLoocEnabled = true; + private const string ChatNamePalette = "Material"; [ValidatePrototypeId] - private const string _chatNamePalette = "Material"; private string[] _chatNameColors = default!; public override void Initialize() @@ -99,7 +94,7 @@ public sealed partial class ChatSystem : SharedChatSystem SubscribeLocalEvent(OnGameChange); - var nameColors = _prototypeManager.Index(_chatNamePalette).Colors.Values.ToArray(); + var nameColors = _prototypeManager.Index(ChatNamePalette).Colors.Values.ToArray(); _chatNameColors = new string[nameColors.Length]; for (var i = 0; i < nameColors.Length; i++) { @@ -117,7 +112,8 @@ public sealed partial class ChatSystem : SharedChatSystem private void OnLoocEnabledChanged(bool val) { - if (_loocEnabled == val) return; + if (_loocEnabled == val) + return; _loocEnabled = val; _chatManager.DispatchServerAnnouncement( @@ -126,11 +122,14 @@ public sealed partial class ChatSystem : SharedChatSystem private void OnDeadLoocEnabledChanged(bool val) { - if (_deadLoocEnabled == val) return; + if (_deadLoocEnabled == val) + return; _deadLoocEnabled = val; _chatManager.DispatchServerAnnouncement( - Loc.GetString(val ? "chat-manager-dead-looc-chat-enabled-message" : "chat-manager-dead-looc-chat-disabled-message")); + Loc.GetString(val + ? "chat-manager-dead-looc-chat-enabled-message" + : "chat-manager-dead-looc-chat-disabled-message")); } private void OnCritLoocEnabledChanged(bool val) @@ -140,7 +139,9 @@ public sealed partial class ChatSystem : SharedChatSystem _critLoocEnabled = val; _chatManager.DispatchServerAnnouncement( - Loc.GetString(val ? "chat-manager-crit-looc-chat-enabled-message" : "chat-manager-crit-looc-chat-disabled-message")); + Loc.GetString(val + ? "chat-manager-crit-looc-chat-enabled-message" + : "chat-manager-crit-looc-chat-disabled-message")); } private void OnGameChange(GameRunLevelChangedEvent ev) @@ -150,10 +151,12 @@ public sealed partial class ChatSystem : SharedChatSystem 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; } } @@ -173,13 +176,17 @@ public sealed partial class ChatSystem : SharedChatSystem EntityUid source, string message, InGameICChatType desiredType, - bool hideChat, bool hideLog = false, + bool hideChat, + bool hideLog = false, IConsoleShell? shell = null, - ICommonSession? player = null, string? nameOverride = null, + ICommonSession? player = null, + string? nameOverride = null, bool checkRadioPrefix = true, bool ignoreActionBlocker = false) { - TrySendInGameICMessage(source, message, desiredType, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, hideLog, shell, player, nameOverride, checkRadioPrefix, ignoreActionBlocker); + TrySendInGameICMessage(source, message, desiredType, + hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, hideLog, shell, player, nameOverride, + checkRadioPrefix, ignoreActionBlocker); } /// @@ -204,15 +211,17 @@ public sealed partial class ChatSystem : SharedChatSystem string? nameOverride = null, bool checkRadioPrefix = true, bool ignoreActionBlocker = false - ) + ) { if (HasComp(source)) { - if(desiredType == InGameICChatType.Emote) + if (desiredType == InGameICChatType.Emote) return; // Ghosts can only send dead chat messages, so we'll forward it to InGame OOC. - TrySendInGameOOCMessage(source, message, InGameOOCChatType.Dead, range == ChatTransmitRange.HideChat, shell, player); + TrySendInGameOOCMessage(source, message, InGameOOCChatType.Dead, range == ChatTransmitRange.HideChat, shell, + player); + return; } @@ -254,7 +263,8 @@ public sealed partial class ChatSystem : SharedChatSystem var shouldPunctuate = _configurationManager.GetCVar(CCVars.ChatPunctuation); var sanitizeSlang = _configurationManager.GetCVar(WhiteCVars.ChatSlangFilter); - message = SanitizeInGameICMessage(source, message, out var emoteStr, shouldCapitalize, shouldPunctuate, sanitizeSlang); + message = SanitizeInGameICMessage(source, message, out var emoteStr, shouldCapitalize, shouldPunctuate, + sanitizeSlang); // Was there an emote in the message? If so, send it. if (emoteStr != message && emoteStr != null) @@ -296,7 +306,9 @@ public sealed partial class ChatSystem : SharedChatSystem SendEntityWhisper(source, message, range, null, nameOverride, hideLog, ignoreActionBlocker); break; case InGameICChatType.Emote: - SendEntityEmote(source, message, range, nameOverride, hideLog: hideLog, ignoreActionBlocker: ignoreActionBlocker); + SendEntityEmote(source, message, range, nameOverride, hideLog: hideLog, + ignoreActionBlocker: ignoreActionBlocker); + break; } } @@ -308,7 +320,7 @@ public sealed partial class ChatSystem : SharedChatSystem bool hideChat, IConsoleShell? shell = null, ICommonSession? player = null - ) + ) { if (!CanSendInGame(message, shell, player)) return; @@ -350,7 +362,6 @@ public sealed partial class ChatSystem : SharedChatSystem } } - public string AfterSpeechTransformed(EntityUid sender, string message) { var ev = new SpeechTransformedEvent(sender, message); @@ -358,7 +369,7 @@ public sealed partial class ChatSystem : SharedChatSystem return ev.Message; } - #region Announcements +#region Announcements /// /// Dispatches an announcement to all. @@ -373,14 +384,21 @@ 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))); + var wrappedMessage = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender), + ("message", FormattedMessage.EscapeText(message))); + _chatManager.ChatMessageToAll(ChatChannel.Radio, message, wrappedMessage, default, false, true, colorOverride); if (playSound) { - _audio.PlayGlobal(announcementSound?.GetSound() ?? DefaultAnnouncementSound, Filter.Broadcast(), true, AudioParams.Default.WithVolume(-2f)); + _audio.PlayGlobal( + announcementSound is not null ? _audio.GetSound(announcementSound) : DefaultAnnouncementSound, + Filter.Broadcast(), + true, + AudioParams.Default.WithVolume(-2f)); } + _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Global station announcement from {sender}: {message}"); } @@ -400,7 +418,9 @@ public sealed partial class ChatSystem : SharedChatSystem SoundSpecifier? announcementSound = null, Color? colorOverride = null) { - var wrappedMessage = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender), ("message", FormattedMessage.EscapeText(message))); + var wrappedMessage = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender), + ("message", FormattedMessage.EscapeText(message))); + var station = _stationSystem.GetOwningStation(source); if (station == null) @@ -409,23 +429,29 @@ public sealed partial class ChatSystem : SharedChatSystem return; } - if (!EntityManager.TryGetComponent(station, out var stationDataComp)) return; + if (!EntityManager.TryGetComponent(station, out var stationDataComp)) + return; var filter = _stationSystem.GetInStation(stationDataComp); - _chatManager.ChatMessageToManyFiltered(filter, ChatChannel.Radio, message, wrappedMessage, source, false, true, colorOverride); + _chatManager.ChatMessageToManyFiltered(filter, ChatChannel.Radio, message, wrappedMessage, source, false, true, + colorOverride); if (playDefaultSound) { - _audio.PlayGlobal(announcementSound?.GetSound() ?? DefaultAnnouncementSound, filter, true, AudioParams.Default.WithVolume(-2f)); + _audio.PlayGlobal( + announcementSound is not null ? _audio.GetSound(announcementSound) : DefaultAnnouncementSound, + filter, + true, + AudioParams.Default.WithVolume(-2f)); } _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Station Announcement on {station} from {sender}: {message}"); } - #endregion +#endregion - #region Private API +#region Private API private void SendEntitySpeak( EntityUid source, @@ -434,7 +460,7 @@ public sealed partial class ChatSystem : SharedChatSystem string? nameOverride, bool hideLog = false, bool ignoreActionBlocker = false - ) + ) { if (!_actionBlocker.CanSpeak(source) && !ignoreActionBlocker) return; @@ -459,18 +485,20 @@ public sealed partial class ChatSystem : SharedChatSystem RaiseLocalEvent(source, nameEv); name = nameEv.Name; // Check for a speech verb override - if (nameEv.SpeechVerb != null && _prototypeManager.TryIndex(nameEv.SpeechVerb, out var proto)) + if (nameEv.SpeechVerb != null && + _prototypeManager.TryIndex(nameEv.SpeechVerb, out var proto)) speech = proto; } name = FormattedMessage.EscapeText(name); // color the name unless it's something like "the old man" - string coloredName = name; + var coloredName = name; if (!TryComp(source, out var grammar) || grammar.ProperNoun == true) coloredName = $"[color={GetNameColor(name)}]{name}[/color]"; - var wrappedMessage = Loc.GetString(speech.Bold ? "chat-manager-entity-say-bold-wrap-message" : "chat-manager-entity-say-wrap-message", + var wrappedMessage = Loc.GetString( + speech.Bold ? "chat-manager-entity-say-bold-wrap-message" : "chat-manager-entity-say-wrap-message", ("entityName", coloredName), ("verb", Loc.GetString(_random.Pick(speech.SpeechVerbStrings))), ("fontType", speech.FontId), @@ -501,9 +529,15 @@ public sealed partial class ChatSystem : SharedChatSystem if (originalMessage == message) { if (name != Name(source)) - _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Say from {ToPrettyString(source):user} as {name}: {originalMessage}."); + { + _adminLogger.Add(LogType.Chat, LogImpact.Low, + $"Say from {ToPrettyString(source):user} as {name}: {originalMessage}."); + } else - _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Say from {ToPrettyString(source):user}: {originalMessage}."); + { + _adminLogger.Add(LogType.Chat, LogImpact.Low, + $"Say from {ToPrettyString(source):user}: {originalMessage}."); + } } else { @@ -528,7 +562,7 @@ public sealed partial class ChatSystem : SharedChatSystem string? nameOverride, bool hideLog = false, bool ignoreActionBlocker = false - ) + ) { if (!_actionBlocker.CanSpeak(source) && !ignoreActionBlocker) return; @@ -555,6 +589,7 @@ public sealed partial class ChatSystem : SharedChatSystem RaiseLocalEvent(source, nameEv); name = nameEv.Name; } + name = FormattedMessage.EscapeText(name); // color the name unless it's something like "the old man" @@ -570,28 +605,39 @@ public sealed partial class ChatSystem : SharedChatSystem var wrappedUnknownMessage = Loc.GetString("chat-manager-entity-whisper-unknown-wrap-message", ("message", obfuscatedMessage)); - foreach (var (session, data) in GetRecipients(source, WhisperMuffledRange)) { if (session.AttachedEntity is not { Valid: true }) continue; + var listener = session.AttachedEntity.Value; if (MessageRangeCheck(session, data, range) != MessageRangeCheckResult.Full) 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 <= WhisperClearRange) - _chatManager.ChatMessageToOne(ChatChannel.Whisper, message, wrappedMessage, source, false, session.Channel); + { + _chatManager.ChatMessageToOne(ChatChannel.Whisper, message, wrappedMessage, source, false, + session.Channel); + } //If listener is too far, they only hear fragments of the message //Collisiongroup.Opaque is not ideal for this use. Preferably, there should be a check specifically with "Can Ent1 see Ent2" in mind - else if (_interactionSystem.InRangeUnobstructed(source, listener, WhisperMuffledRange, Shared.Physics.CollisionGroup.Opaque)) //Shared.Physics.CollisionGroup.Opaque - _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedobfuscatedMessage, source, false, session.Channel); + else if (_interactionSystem.InRangeUnobstructed(source, listener, WhisperMuffledRange, + Shared.Physics.CollisionGroup.Opaque)) //Shared.Physics.CollisionGroup.Opaque + { + _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedobfuscatedMessage, source, + false, session.Channel); + } //If listener is too far and has no line of sight, they can't identify the whisperer's identity else - _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedUnknownMessage, source, false, session.Channel); + { + _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedUnknownMessage, source, + false, session.Channel); + } } - _replay.RecordServerMessage(new ChatMessage(ChatChannel.Whisper, message, wrappedMessage, GetNetEntity(source), null, MessageRangeHideChatForReplay(range))); + _replay.RecordServerMessage(new ChatMessage(ChatChannel.Whisper, message, wrappedMessage, GetNetEntity(source), + null, MessageRangeHideChatForReplay(range))); var ev = new EntitySpokeEvent(source, message, originalMessage, channel, obfuscatedMessage); RaiseLocalEvent(source, ev, true); @@ -601,9 +647,15 @@ public sealed partial class ChatSystem : SharedChatSystem if (originalMessage == message) { if (name != Name(source)) - _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Whisper from {ToPrettyString(source):user} as {name}: {originalMessage}."); + { + _adminLogger.Add(LogType.Chat, LogImpact.Low, + $"Whisper from {ToPrettyString(source):user} as {name}: {originalMessage}."); + } else - _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Whisper from {ToPrettyString(source):user}: {originalMessage}."); + { + _adminLogger.Add(LogType.Chat, LogImpact.Low, + $"Whisper from {ToPrettyString(source):user}: {originalMessage}."); + } } else { @@ -629,7 +681,7 @@ public sealed partial class ChatSystem : SharedChatSystem bool checkEmote = true, bool ignoreActionBlocker = false, NetUserId? author = null - ) + ) { if (!_actionBlocker.CanEmote(source) && !ignoreActionBlocker) return; @@ -646,27 +698,34 @@ public sealed partial class ChatSystem : SharedChatSystem if (checkEmote) TryEmoteChatInput(source, action); + SendInVoiceRange(ChatChannel.Emotes, action, wrappedMessage, source, range, author); if (hideLog) return; if (name != Name(source)) - _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Emote from {ToPrettyString(source):user} as {name}: {action}"); + { + _adminLogger.Add(LogType.Chat, LogImpact.Low, + $"Emote from {ToPrettyString(source):user} as {name}: {action}"); + } else + { _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Emote from {ToPrettyString(source):user}: {action}"); + } //WD-EDIT - string ckey = string.Empty; + var ckey = string.Empty; if (TryComp(source, out var actorComponent)) { ckey = actorComponent.PlayerSession.Name; } - if(string.IsNullOrEmpty(ckey)) return; + if (string.IsNullOrEmpty(ckey)) + return; - var utkaEmoteEvent = new UtkaChatMeEvent() + var utkaEmoteEvent = new UtkaChatMeEvent { Ckey = ckey, Message = action, @@ -701,7 +760,9 @@ public sealed partial class ChatSystem : SharedChatSystem ("entityName", name), ("message", FormattedMessage.EscapeText(message))); - SendInVoiceRange(ChatChannel.LOOC, message, wrappedMessage, source, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, player.UserId); + SendInVoiceRange(ChatChannel.LOOC, message, wrappedMessage, source, + hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, player.UserId); + _adminLogger.Add(LogType.Chat, LogImpact.Low, $"LOOC from {player:Player}: {message}"); } @@ -710,15 +771,15 @@ public sealed partial class ChatSystem : SharedChatSystem { var clients = GetCultChatClients(); var playerName = Name(source); - string wrappedMessage; - wrappedMessage = Loc.GetString("chat-manager-send-cult-chat-wrap-message", + var wrappedMessage = Loc.GetString("chat-manager-send-cult-chat-wrap-message", ("channelName", Loc.GetString("chat-manager-cult-channel-name")), ("player", playerName), ("message", FormattedMessage.EscapeText(message))); _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Cult chat from {player:Player}: {message}"); - _chatManager.ChatMessageToMany(ChatChannel.Cult, message, wrappedMessage, source, hideChat, false, clients.ToList()); + _chatManager.ChatMessageToMany(ChatChannel.Cult, message, wrappedMessage, source, hideChat, false, + clients.ToList()); } private IEnumerable GetCultChatClients() @@ -728,7 +789,7 @@ public sealed partial class ChatSystem : SharedChatSystem .AddWhereAttachedEntity(HasComp) .Recipients .Union(_adminManager.ActiveAdmins) - .Select(p => p.ConnectedClient); + .Select(p => p.Channel); } private void SendDeadChat(EntityUid source, ICommonSession player, string message, bool hideChat) @@ -737,12 +798,13 @@ public sealed partial class ChatSystem : SharedChatSystem var playerName = Name(source); string wrappedMessage; if (_adminManager.IsAdmin(player) && - _netConfigurationManager.GetClientCVar(player.ConnectedClient, WhiteCVars.DeadChatAdmin)) // WD + _netConfigurationManager.GetClientCVar(player.Channel, WhiteCVars.DeadChatAdmin)) // WD { wrappedMessage = Loc.GetString("chat-manager-send-admin-dead-chat-wrap-message", ("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")), ("userName", player.Channel.UserName), ("message", FormattedMessage.EscapeText(message))); + _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Admin dead chat from {player:Player}: {message}"); } else @@ -751,14 +813,17 @@ public sealed partial class ChatSystem : SharedChatSystem ("deadChannelName", Loc.GetString("chat-manager-dead-channel-name")), ("playerName", (playerName)), ("message", FormattedMessage.EscapeText(message))); + _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Dead chat from {player:Player}: {message}"); } - _chatManager.ChatMessageToMany(ChatChannel.Dead, message, wrappedMessage, source, hideChat, true, clients.ToList(), author: player.UserId); + _chatManager.ChatMessageToMany(ChatChannel.Dead, message, wrappedMessage, source, hideChat, true, + clients.ToList(), author: player.UserId); } - #endregion - #region Utility +#endregion + +#region Utility /// /// Returns the chat name color for a mob @@ -790,7 +855,10 @@ public sealed partial class ChatSystem : SharedChatSystem /// Checks if a target as returned from GetRecipients should receive the message. /// Keep in mind data.Range is -1 for out of range observers. /// - private MessageRangeCheckResult MessageRangeCheck(ICommonSession session, ICChatRecipientData data, ChatTransmitRange range) + private MessageRangeCheckResult MessageRangeCheck( + ICommonSession session, + ICChatRecipientData data, + ChatTransmitRange range) { var initialResult = MessageRangeCheckResult.Full; switch (range) @@ -799,39 +867,57 @@ public sealed partial class ChatSystem : SharedChatSystem initialResult = MessageRangeCheckResult.Full; break; case ChatTransmitRange.GhostRangeLimit: - initialResult = (data.Observer && data.Range < 0 && !_adminManager.IsAdmin(session)) ? MessageRangeCheckResult.HideChat : MessageRangeCheckResult.Full; + initialResult = (data.Observer && data.Range < 0 && !_adminManager.IsAdmin(session)) + ? MessageRangeCheckResult.HideChat + : MessageRangeCheckResult.Full; + break; case ChatTransmitRange.HideChat: initialResult = MessageRangeCheckResult.HideChat; break; case ChatTransmitRange.NoGhosts: - initialResult = (data.Observer && !_adminManager.IsAdmin(session)) ? MessageRangeCheckResult.Disallowed : MessageRangeCheckResult.Full; + initialResult = (data.Observer && !_adminManager.IsAdmin(session)) + ? MessageRangeCheckResult.Disallowed + : MessageRangeCheckResult.Full; + break; } + var insistHideChat = data.HideChatOverride ?? false; var insistNoHideChat = !(data.HideChatOverride ?? true); if (insistHideChat && initialResult == MessageRangeCheckResult.Full) return MessageRangeCheckResult.HideChat; + if (insistNoHideChat && initialResult == MessageRangeCheckResult.HideChat) return MessageRangeCheckResult.Full; + return initialResult; } /// /// Sends a chat message to the given players in range of the source entity. /// - public void SendInVoiceRange(ChatChannel channel, string message, string wrappedMessage, EntityUid source, ChatTransmitRange range, NetUserId? author = null) + public void SendInVoiceRange( + ChatChannel channel, + string message, + string wrappedMessage, + EntityUid source, + ChatTransmitRange range, + NetUserId? author = null) { foreach (var (session, data) in GetRecipients(source, VoiceRange)) { var entRange = MessageRangeCheck(session, data, range); if (entRange == MessageRangeCheckResult.Disallowed) continue; + var entHideChat = entRange == MessageRangeCheckResult.HideChat; - _chatManager.ChatMessageToOne(channel, message, wrappedMessage, source, entHideChat, session.Channel, author: author); + _chatManager.ChatMessageToOne(channel, message, wrappedMessage, source, entHideChat, session.Channel, + author: author); } - _replay.RecordServerMessage(new ChatMessage(channel, message, wrappedMessage, GetNetEntity(source), null, MessageRangeHideChatForReplay(range))); + _replay.RecordServerMessage(new ChatMessage(channel, message, wrappedMessage, GetNetEntity(source), null, + MessageRangeHideChatForReplay(range))); } /// @@ -861,16 +947,24 @@ public sealed partial class ChatSystem : SharedChatSystem } // ReSharper disable once InconsistentNaming - private string SanitizeInGameICMessage(EntityUid source, string message, out string? emoteStr, bool capitalize = true, bool punctuate = false, bool sanitizeSlang = true) + private string SanitizeInGameICMessage( + EntityUid source, + string message, + out string? emoteStr, + bool capitalize = true, + bool punctuate = false, + bool sanitizeSlang = true) { var newMessage = message.Trim(); newMessage = _sanitizer.SanitizeTags(newMessage); - if(sanitizeSlang) + if (sanitizeSlang) newMessage = _sanitizer.SanitizeOutSlang(newMessage); + if (capitalize) newMessage = SanitizeMessageCapital(newMessage); + if (punctuate) newMessage = SanitizeMessagePeriod(newMessage); @@ -919,9 +1013,11 @@ public sealed partial class ChatSystem : SharedChatSystem { if (string.IsNullOrEmpty(message)) return message; + // Adds a period if the last character is a letter. if (char.IsLetter(message[^1])) message += "."; + return message; } @@ -968,7 +1064,8 @@ public sealed partial class ChatSystem : SharedChatSystem var observer = ghostHearing.HasComponent(playerEntity); // even if they are a ghost hearer, in some situations we still need the range - if (sourceCoords.TryDistance(EntityManager, transformEntity.Coordinates, out var distance) && distance < voiceGetRange) + if (sourceCoords.TryDistance(EntityManager, transformEntity.Coordinates, out var distance) && + distance < voiceGetRange) { recipients.Add(player, new ICChatRecipientData(distance, observer)); continue; @@ -1011,17 +1108,21 @@ public sealed partial class ChatSystem : SharedChatSystem { sb.Append(_random.Pick(charOptions)); } + return sb.ToString(); } - #endregion +#endregion } /// /// This event is raised before chat messages are sent out to clients. This enables some systems to send the chat /// messages to otherwise out-of view entities (e.g. for multiple viewports from cameras). /// -public record ExpandICChatRecipientstEvent(EntityUid Source, float VoiceRange, Dictionary Recipients); +public record ExpandICChatRecipientstEvent( + EntityUid Source, + float VoiceRange, + Dictionary Recipients); public sealed class TransformSpeakerNameEvent : EntityEventArgs { @@ -1080,7 +1181,12 @@ public sealed class EntitySpokeEvent : EntityEventArgs /// public RadioChannelPrototype? Channel; - public EntitySpokeEvent(EntityUid source, string message, string originalMessage, RadioChannelPrototype? channel, string? obfuscatedMessage) + public EntitySpokeEvent( + EntityUid source, + string message, + string originalMessage, + RadioChannelPrototype? channel, + string? obfuscatedMessage) { Source = source; Message = message; @@ -1091,9 +1197,10 @@ public sealed class EntitySpokeEvent : EntityEventArgs } //WD-EDIT -public class SetSpeakerColorEvent +public sealed class SetSpeakerColorEvent { public EntityUid Sender { get; set; } + public string Name { get; set; } public SetSpeakerColorEvent(EntityUid sender, string name) @@ -1145,10 +1252,13 @@ public enum ChatTransmitRange : byte { /// Acts normal, ghosts can hear across the map, etc. Normal, + /// Normal but ghosts are still range-limited. GhostRangeLimit, + /// Hidden from the chat window. HideChat, + /// Ghosts can't hear or see it at all. Regular players can if in-range. NoGhosts } diff --git a/Resources/Locale/ru-RU/White/cult.ftl b/Resources/Locale/ru-RU/White/cult.ftl index ef296c999b..c27fa06cef 100644 --- a/Resources/Locale/ru-RU/White/cult.ftl +++ b/Resources/Locale/ru-RU/White/cult.ftl @@ -54,5 +54,5 @@ ent-CultSharpener = древний точильный камень .desc = Используется для заточки кромок стальных инструментов. chat-manager-cult-channel-name = Культ -chat-manager-send-cult-chat-wrap-message = \[{ $channelName }\] { $player }: { $message } +chat-manager-send-cult-chat-wrap-message = [bold]\[{ $channelName }\] [BubbleHeader]{ $player }[/BubbleHeader]:[/bold] [BubbleContent]{ $message }[/BubbleContent] hud-chatbox-select-channel-Cult = Культ