Cleanup chat highlighting code (#38235)

* Cache regexes

* Convert static LocManager to resolved

* Use Any instead of Count > 0

* Use var instead of explicit types

* Make _highlights readonly
This commit is contained in:
Tayrtahn
2025-06-12 01:09:05 -04:00
committed by GitHub
parent aee55954d3
commit 70ce570fe9

View File

@@ -14,12 +14,17 @@ namespace Content.Client.UserInterface.Systems.Chat;
/// </summary> /// </summary>
public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSystem> public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSystem>
{ {
[Dependency] private readonly ILocalizationManager _loc = default!;
[UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!; [UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!;
private static readonly Regex StartDoubleQuote = new("\"$");
private static readonly Regex EndDoubleQuote = new("^\"|(?<=^@)\"");
private static readonly Regex StartAtSign = new("^@");
/// <summary> /// <summary>
/// The list of words to be highlighted in the chatbox. /// The list of words to be highlighted in the chatbox.
/// </summary> /// </summary>
private List<string> _highlights = new(); private readonly List<string> _highlights = new();
/// <summary> /// <summary>
/// The string holding the hex color used to highlight words. /// The string holding the hex color used to highlight words.
@@ -42,7 +47,7 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
_config.OnValueChanged(CCVars.ChatHighlightsColor, (value) => { _highlightsColor = value; }, true); _config.OnValueChanged(CCVars.ChatHighlightsColor, (value) => { _highlightsColor = value; }, true);
// Load highlights if any were saved. // Load highlights if any were saved.
string highlights = _config.GetCVar(CCVars.ChatHighlights); var highlights = _config.GetCVar(CCVars.ChatHighlights);
if (!string.IsNullOrEmpty(highlights)) if (!string.IsNullOrEmpty(highlights))
{ {
@@ -84,12 +89,12 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
// We first subdivide the highlights based on newlines to prevent replacing // We first subdivide the highlights based on newlines to prevent replacing
// a valid "\n" tag and adding it to the final regex. // a valid "\n" tag and adding it to the final regex.
string[] splittedHighlights = newHighlights.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); var splittedHighlights = newHighlights.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
for (int i = 0; i < splittedHighlights.Length; i++) for (var i = 0; i < splittedHighlights.Length; i++)
{ {
// Replace every "\" character with a "\\" to prevent "\n", "\0", etc... // Replace every "\" character with a "\\" to prevent "\n", "\0", etc...
string keyword = splittedHighlights[i].Replace(@"\", @"\\"); var keyword = splittedHighlights[i].Replace(@"\", @"\\");
// Escape the keyword to prevent special characters like "(" and ")" to be considered valid regex. // Escape the keyword to prevent special characters like "(" and ")" to be considered valid regex.
keyword = Regex.Escape(keyword); keyword = Regex.Escape(keyword);
@@ -102,17 +107,17 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
// that make sure the words to match are separated by spaces or punctuation. // that make sure the words to match are separated by spaces or punctuation.
// NOTE: The reason why we don't use \b tags is that \b doesn't match reverse slash characters "\" so // NOTE: The reason why we don't use \b tags is that \b doesn't match reverse slash characters "\" so
// a pre-sanitized (see 1.) string like "\[test]" wouldn't get picked up by the \b. // a pre-sanitized (see 1.) string like "\[test]" wouldn't get picked up by the \b.
if (keyword.Count(c => (c == '"')) > 0) if (keyword.Any(c => c == '"'))
{ {
// Matches the last double quote character. // Matches the last double quote character.
keyword = Regex.Replace(keyword, "\"$", "(?!\\w)"); keyword = StartDoubleQuote.Replace(keyword, "(?!\\w)");
// When matching for the first double quote character we also consider the possibility // When matching for the first double quote character we also consider the possibility
// of the double quote being preceded by a @ character. // of the double quote being preceded by a @ character.
keyword = Regex.Replace(keyword, "^\"|(?<=^@)\"", "(?<!\\w)"); keyword = EndDoubleQuote.Replace(keyword, "(?<!\\w)");
} }
// Make sure any name tagged as ours gets highlighted only when others say it. // Make sure any name tagged as ours gets highlighted only when others say it.
keyword = Regex.Replace(keyword, "^@", "(?<=(?<=/name.*)|(?<=,.*\"\".*))"); keyword = StartAtSign.Replace(keyword, "(?<=(?<=/name.*)|(?<=,.*\"\".*))");
_highlights.Add(keyword); _highlights.Add(keyword);
} }
@@ -132,7 +137,7 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
var (_, job, _, _, entityName) = data; var (_, job, _, _, entityName) = data;
// Mark this entity's name as our character name for the "UpdateHighlights" function. // Mark this entity's name as our character name for the "UpdateHighlights" function.
string newHighlights = "@" + entityName; var newHighlights = "@" + entityName;
// Subdivide the character's name based on spaces or hyphens so that every word gets highlighted. // Subdivide the character's name based on spaces or hyphens so that every word gets highlighted.
if (newHighlights.Count(c => (c == ' ' || c == '-')) == 1) if (newHighlights.Count(c => (c == ' ' || c == '-')) == 1)
@@ -144,9 +149,9 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
newHighlights = newHighlights.Split('-')[0] + "\n@" + newHighlights.Split('-')[^1]; newHighlights = newHighlights.Split('-')[0] + "\n@" + newHighlights.Split('-')[^1];
// Convert the job title to kebab-case and use it as a key for the loc file. // Convert the job title to kebab-case and use it as a key for the loc file.
string jobKey = job.Replace(' ', '-').ToLower(); var jobKey = job.Replace(' ', '-').ToLower();
if (Loc.TryGetString($"highlights-{jobKey}", out var jobMatches)) if (_loc.TryGetString($"highlights-{jobKey}", out var jobMatches))
newHighlights += '\n' + jobMatches.Replace(", ", "\n"); newHighlights += '\n' + jobMatches.Replace(", ", "\n");
UpdateHighlights(newHighlights); UpdateHighlights(newHighlights);