diff --git a/Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs b/Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs index 5637288732..f6d259c115 100644 --- a/Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs @@ -10,6 +10,10 @@ public sealed class FrenchAccentSystem : EntitySystem { [Dependency] private readonly ReplacementAccentSystem _replacement = default!; + private static readonly Regex RegexTh = new(@"th", RegexOptions.IgnoreCase); + private static readonly Regex RegexStartH = new(@"(? DirectReplacements = new() - { - { "let me", "lemme" }, - { "should", "oughta" }, - { "the", "da" }, - { "them", "dem" }, - { "attack", "whack" }, - { "kill", "whack" }, - { "murder", "whack" }, - { "dead", "sleepin' with da fishies"}, - { "hey", "ey'o" }, - { "hi", "ey'o"}, - { "hello", "ey'o"}, - { "rules", "roolz" }, - { "you", "yous" }, - { "have to", "gotta" }, - { "going to", "boutta" }, - { "about to", "boutta" }, - { "here", "'ere" } - }; - public override void Initialize() { base.Initialize(); @@ -51,20 +37,20 @@ public sealed class MobsterAccentSystem : EntitySystem // thinking -> thinkin' // king -> king //Uses captures groups to make sure the captialization of IN is kept - msg = Regex.Replace(msg, @"(?<=\w\w)(in)g(?!\w)", "$1'", RegexOptions.IgnoreCase); + msg = RegexIng.Replace(msg, "$1'"); // or -> uh and ar -> ah in the middle of words (fuhget, tahget) - msg = Regex.Replace(msg, @"(?<=\w)o[Rr](?=\w)", "uh"); - msg = Regex.Replace(msg, @"(?<=\w)O[Rr](?=\w)", "UH"); - msg = Regex.Replace(msg, @"(?<=\w)a[Rr](?=\w)", "ah"); - msg = Regex.Replace(msg, @"(?<=\w)A[Rr](?=\w)", "AH"); + msg = RegexLowerOr.Replace(msg, "uh"); + msg = RegexUpperOr.Replace(msg, "UH"); + msg = RegexLowerAr.Replace(msg, "ah"); + msg = RegexUpperAr.Replace(msg, "AH"); // Prefix if (_random.Prob(0.15f)) { //Checks if the first word of the sentence is all caps //So the prefix can be allcapped and to not resanitize the captial - var firstWordAllCaps = !Regex.Match(msg, @"^(\S+)").Value.Any(char.IsLower); + var firstWordAllCaps = !RegexFirstWord.Match(msg).Value.Any(char.IsLower); var pick = _random.Next(1, 2); // Reverse sanitize capital @@ -84,7 +70,7 @@ public sealed class MobsterAccentSystem : EntitySystem { //Checks if the last word of the sentence is all caps //So the suffix can be allcapped - var lastWordAllCaps = !Regex.Match(msg, @"(\S+)$").Value.Any(char.IsLower); + var lastWordAllCaps = !RegexLastWord.Match(msg).Value.Any(char.IsLower); var suffix = ""; if (component.IsBoss) { @@ -94,7 +80,7 @@ public sealed class MobsterAccentSystem : EntitySystem else { var pick = _random.Next(1, 3); - suffix = Loc.GetString($"accent-mobster-suffix-minion-{pick}"); + suffix = Loc.GetString($"accent-mobster-suffix-minion-{pick}"); } if (lastWordAllCaps) suffix = suffix.ToUpper(); diff --git a/Content.Server/Speech/EntitySystems/MothAccentSystem.cs b/Content.Server/Speech/EntitySystems/MothAccentSystem.cs index 3de4651b4a..84b79d4ce9 100644 --- a/Content.Server/Speech/EntitySystems/MothAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/MothAccentSystem.cs @@ -5,6 +5,9 @@ namespace Content.Server.Speech.EntitySystems; public sealed class MothAccentSystem : EntitySystem { + private static readonly Regex RegexLowerBuzz = new Regex("z{1,3}"); + private static readonly Regex RegexUpperBuzz = new Regex("Z{1,3}"); + public override void Initialize() { base.Initialize(); @@ -16,10 +19,10 @@ public sealed class MothAccentSystem : EntitySystem var message = args.Message; // buzzz - message = Regex.Replace(message, "z{1,3}", "zzz"); + message = RegexLowerBuzz.Replace(message, "zzz"); // buZZZ - message = Regex.Replace(message, "Z{1,3}", "ZZZ"); - + message = RegexUpperBuzz.Replace(message, "ZZZ"); + args.Message = message; } } diff --git a/Content.Server/Speech/EntitySystems/ParrotAccentSystem.cs b/Content.Server/Speech/EntitySystems/ParrotAccentSystem.cs index 10437c235d..ae8fe522b9 100644 --- a/Content.Server/Speech/EntitySystems/ParrotAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/ParrotAccentSystem.cs @@ -7,6 +7,8 @@ namespace Content.Server.Speech.EntitySystems; public sealed partial class ParrotAccentSystem : EntitySystem { + private static readonly Regex WordCleanupRegex = new Regex("[^A-Za-z0-9 -]"); + [Dependency] private readonly IRobustRandom _random = default!; public override void Initialize() @@ -27,7 +29,7 @@ public sealed partial class ParrotAccentSystem : EntitySystem if (_random.Prob(entity.Comp.LongestWordRepeatChance)) { // Don't count non-alphanumeric characters as parts of words - var cleaned = Regex.Replace(message, "[^A-Za-z0-9 -]", string.Empty); + var cleaned = WordCleanupRegex.Replace(message, string.Empty); // Split on whitespace and favor words towards the end of the message var words = cleaned.Split(null).Reverse(); // Find longest word diff --git a/Content.Server/Speech/EntitySystems/PirateAccentSystem.cs b/Content.Server/Speech/EntitySystems/PirateAccentSystem.cs index 9f5f8080b9..84298cbf01 100644 --- a/Content.Server/Speech/EntitySystems/PirateAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/PirateAccentSystem.cs @@ -7,6 +7,8 @@ namespace Content.Server.Speech.EntitySystems; public sealed class PirateAccentSystem : EntitySystem { + private static readonly Regex FirstWordAllCapsRegex = new(@"^(\S+)"); + [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ReplacementAccentSystem _replacement = default!; @@ -26,7 +28,7 @@ public sealed class PirateAccentSystem : EntitySystem return msg; //Checks if the first word of the sentence is all caps //So the prefix can be allcapped and to not resanitize the captial - var firstWordAllCaps = !Regex.Match(msg, @"^(\S+)").Value.Any(char.IsLower); + var firstWordAllCaps = !FirstWordAllCapsRegex.Match(msg).Value.Any(char.IsLower); var pick = _random.Pick(component.PirateWords); var pirateWord = Loc.GetString(pick); diff --git a/Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs b/Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs index 37b267bec2..8a61c0ea50 100644 --- a/Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs @@ -7,6 +7,8 @@ namespace Content.Server.Speech.EntitySystems { public sealed class ScrambledAccentSystem : EntitySystem { + private static readonly Regex RegexLoneI = new(@"(?<=\ )i(?=[\ \.\?]|$)"); + [Dependency] private readonly IRobustRandom _random = default!; public override void Initialize() @@ -34,7 +36,7 @@ namespace Content.Server.Speech.EntitySystems msg = msg[0].ToString().ToUpper() + msg.Remove(0, 1); // Capitalize lone i's - msg = Regex.Replace(msg, @"(?<=\ )i(?=[\ \.\?]|$)", "I"); + msg = RegexLoneI.Replace(msg, "I"); return msg; } diff --git a/Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs b/Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs index 4d401367cc..b9260eb844 100644 --- a/Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs @@ -5,8 +5,12 @@ namespace Content.Server.Speech.EntitySystems; public sealed class SouthernAccentSystem : EntitySystem { + private static readonly Regex RegexIng = new(@"ing\b"); + private static readonly Regex RegexAnd = new(@"\band\b"); + private static readonly Regex RegexDve = new("d've"); + [Dependency] private readonly ReplacementAccentSystem _replacement = default!; - + public override void Initialize() { base.Initialize(); @@ -20,9 +24,9 @@ public sealed class SouthernAccentSystem : EntitySystem message = _replacement.ApplyReplacements(message, "southern"); //They shoulda started runnin' an' hidin' from me! - message = Regex.Replace(message, @"ing\b", "in'"); - message = Regex.Replace(message, @"\band\b", "an'"); - message = Regex.Replace(message, "d've", "da"); + message = RegexIng.Replace(message, "in'"); + message = RegexAnd.Replace(message, "an'"); + message = RegexDve.Replace(message, "da"); args.Message = message; } }; diff --git a/Content.Shared/Preferences/HumanoidCharacterProfile.cs b/Content.Shared/Preferences/HumanoidCharacterProfile.cs index 3f3444195c..f9b037c8ab 100644 --- a/Content.Shared/Preferences/HumanoidCharacterProfile.cs +++ b/Content.Shared/Preferences/HumanoidCharacterProfile.cs @@ -26,6 +26,9 @@ namespace Content.Shared.Preferences [Serializable, NetSerializable] public sealed partial class HumanoidCharacterProfile : ICharacterProfile { + private static readonly Regex RestrictedNameRegex = new("[^A-Z,a-z,0-9, -]"); + private static readonly Regex ICNameCaseRegex = new(@"^(?\w)|\b(?\w)(?=\w*$)"); + public const int MaxNameLength = 32; public const int MaxDescLength = 512; @@ -418,15 +421,13 @@ namespace Content.Shared.Preferences if (configManager.GetCVar(CCVars.RestrictedNames)) { - name = Regex.Replace(name, @"[^A-Z,a-z,0-9, -]", string.Empty); + name = RestrictedNameRegex.Replace(name, string.Empty); } if (configManager.GetCVar(CCVars.ICNameCase)) { // This regex replaces the first character of the first and last words of the name with their uppercase version - name = Regex.Replace(name, - @"^(?\w)|\b(?\w)(?=\w*$)", - m => m.Groups["word"].Value.ToUpper()); + name = ICNameCaseRegex.Replace(name, m => m.Groups["word"].Value.ToUpper()); } if (string.IsNullOrEmpty(name))