From 38ef65aae017f0c7bd79d9f055fbcd8d7438124f Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 1 Feb 2025 14:07:32 -0600 Subject: [PATCH] misc: chore: Move all GeneratedRegex methods into one static class with static instance accessors. --- src/Ryujinx.Common/Helpers/Patterns.cs | 118 ++++++++++++++++++ src/Ryujinx.Graphics.Vulkan/Vendor.cs | 8 +- src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs | 5 +- .../HOS/Applets/Error/ErrorApplet.cs | 6 +- .../CJKCharacterValidation.cs | 14 +-- .../NumericCharacterValidation.cs | 14 +-- .../Sockets/Sfdnsres/Proxy/DnsBlacklist.cs | 30 +---- .../Loaders/Executables/NsoExecutable.cs | 14 +-- .../UI/ViewModels/SettingsViewModel.cs | 6 +- 9 files changed, 139 insertions(+), 76 deletions(-) create mode 100644 src/Ryujinx.Common/Helpers/Patterns.cs diff --git a/src/Ryujinx.Common/Helpers/Patterns.cs b/src/Ryujinx.Common/Helpers/Patterns.cs new file mode 100644 index 000000000..84cc1353a --- /dev/null +++ b/src/Ryujinx.Common/Helpers/Patterns.cs @@ -0,0 +1,118 @@ +using System.Text.RegularExpressions; + +namespace Ryujinx.Common.Helper +{ + public static partial class Patterns + { + #region Accessors + + public static readonly Regex Numeric = NumericRegex(); + + public static readonly Regex AmdGcn = AmdGcnRegex(); + public static readonly Regex NvidiaConsumerClass = NvidiaConsumerClassRegex(); + + public static readonly Regex DomainLp1Ns = DomainLp1NsRegex(); + public static readonly Regex DomainLp1Lp1Npln = DomainLp1Lp1NplnRegex(); + public static readonly Regex DomainLp1Znc = DomainLp1ZncRegex(); + public static readonly Regex DomainSbApi = DomainSbApiRegex(); + public static readonly Regex DomainSbAccounts = DomainSbAccountsRegex(); + public static readonly Regex DomainAccounts = DomainAccountsRegex(); + + public static readonly Regex Module = ModuleRegex(); + public static readonly Regex FsSdk = FsSdkRegex(); + public static readonly Regex SdkMw = SdkMwRegex(); + + // ReSharper disable once InconsistentNaming + public static readonly Regex CJK = CJKRegex(); + + public static readonly Regex LdnPassphrase = LdnPassphraseRegex(); + + public static readonly Regex CleanText = CleanTextRegex(); + + #endregion + + #region Generated pattern stubs + + #region Numeric validation + + [GeneratedRegex("[0-9]|.")] + internal static partial Regex NumericRegex(); + + #endregion + + #region GPU names + + [GeneratedRegex( + "Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\\d{2}(\\D|$))|([7-8]\\d{3}(\\D|$))|Fury|Nano))|(Pro Duo)")] + internal static partial Regex AmdGcnRegex(); + + [GeneratedRegex("NVIDIA GeForce (R|G)?TX? (\\d{3}\\d?)M?")] + internal static partial Regex NvidiaConsumerClassRegex(); + + #endregion + + #region DNS blocking + + public static readonly Regex[] BlockedHosts = + [ + DomainLp1Ns, + DomainLp1Lp1Npln, + DomainLp1Znc, + DomainSbApi, + DomainSbAccounts, + DomainAccounts + ]; + + const RegexOptions DnsRegexOpts = + RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture; + + [GeneratedRegex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", DnsRegexOpts)] + internal static partial Regex DomainLp1NsRegex(); + + [GeneratedRegex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", DnsRegexOpts)] + internal static partial Regex DomainLp1Lp1NplnRegex(); + + [GeneratedRegex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", DnsRegexOpts)] + internal static partial Regex DomainLp1ZncRegex(); + + [GeneratedRegex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", DnsRegexOpts)] + internal static partial Regex DomainSbApiRegex(); + + [GeneratedRegex(@"^(.*)\-sb\.accounts\.nintendo\.com$", DnsRegexOpts)] + internal static partial Regex DomainSbAccountsRegex(); + + [GeneratedRegex(@"^accounts\.nintendo\.com$", DnsRegexOpts)] + internal static partial Regex DomainAccountsRegex(); + + #endregion + + #region Executable information + + [GeneratedRegex(@"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] + internal static partial Regex ModuleRegex(); + + [GeneratedRegex(@"sdk_version: ([0-9.]*)")] + internal static partial Regex FsSdkRegex(); + + [GeneratedRegex(@"SDK MW[ -~]*")] + internal static partial Regex SdkMwRegex(); + + #endregion + + #region CJK + + [GeneratedRegex( + "\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")] + private static partial Regex CJKRegex(); + + #endregion + + [GeneratedRegex("Ryujinx-[0-9a-f]{8}")] + private static partial Regex LdnPassphraseRegex(); + + [GeneratedRegex(@"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..")] + private static partial Regex CleanTextRegex(); + + #endregion + } +} diff --git a/src/Ryujinx.Graphics.Vulkan/Vendor.cs b/src/Ryujinx.Graphics.Vulkan/Vendor.cs index 6a2a76a88..87c6407cd 100644 --- a/src/Ryujinx.Graphics.Vulkan/Vendor.cs +++ b/src/Ryujinx.Graphics.Vulkan/Vendor.cs @@ -16,14 +16,8 @@ namespace Ryujinx.Graphics.Vulkan Unknown, } - static partial class VendorUtils + static class VendorUtils { - [GeneratedRegex("Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\\d{2}(\\D|$))|([7-8]\\d{3}(\\D|$))|Fury|Nano))|(Pro Duo)")] - public static partial Regex AmdGcnRegex(); - - [GeneratedRegex("NVIDIA GeForce (R|G)?TX? (\\d{3}\\d?)M?")] - public static partial Regex NvidiaConsumerClassRegex(); - public static Vendor FromId(uint id) { return id switch diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index 986baf91b..e90606dcf 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -1,5 +1,6 @@ using Gommon; using Ryujinx.Common.Configuration; +using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; @@ -375,11 +376,11 @@ namespace Ryujinx.Graphics.Vulkan GpuVersion = $"Vulkan v{ParseStandardVulkanVersion(properties.ApiVersion)}, Driver v{ParseDriverVersion(ref properties)}"; - IsAmdGcn = !IsMoltenVk && Vendor == Vendor.Amd && VendorUtils.AmdGcnRegex().IsMatch(GpuRenderer); + IsAmdGcn = !IsMoltenVk && Vendor == Vendor.Amd && Patterns.AmdGcn.IsMatch(GpuRenderer); if (Vendor == Vendor.Nvidia) { - Match match = VendorUtils.NvidiaConsumerClassRegex().Match(GpuRenderer); + Match match = Patterns.NvidiaConsumerClass.Match(GpuRenderer); if (match != null && int.TryParse(match.Groups[2].Value, out int gpuNumber)) { diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs index 54b5721c1..b41bc60b1 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs @@ -5,6 +5,7 @@ using LibHac.FsSystem; using LibHac.Ncm; using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem.NcaUtils; +using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Am.AppletAE; using Ryujinx.HLE.HOS.SystemState; @@ -30,9 +31,6 @@ namespace Ryujinx.HLE.HOS.Applets.Error public event EventHandler AppletStateChanged; - [GeneratedRegex(@"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..")] - private static partial Regex CleanTextRegex(); - public ErrorApplet(Horizon horizon) { _horizon = horizon; @@ -107,7 +105,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error private static string CleanText(string value) { - return CleanTextRegex().Replace(value, string.Empty).Replace("\0", string.Empty); + return Patterns.CleanText.Replace(value, string.Empty).Replace("\0", string.Empty); } private string GetMessageText(uint module, uint description, string key) diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs index 6134a3cdd..022fa9d5b 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs @@ -1,17 +1,9 @@ -using System.Text.RegularExpressions; +using Ryujinx.Common.Helper; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { - public static partial class CJKCharacterValidation + public static class CJKCharacterValidation { - public static bool IsCJK(char value) - { - Regex regex = CJKRegex(); - - return regex.IsMatch(value.ToString()); - } - - [GeneratedRegex("\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")] - private static partial Regex CJKRegex(); + public static bool IsCJK(char value) => Patterns.CJK.IsMatch(value.ToString()); } } diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/NumericCharacterValidation.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/NumericCharacterValidation.cs index d72b68eae..4f61773c0 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/NumericCharacterValidation.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/NumericCharacterValidation.cs @@ -1,17 +1,9 @@ -using System.Text.RegularExpressions; +using Ryujinx.Common.Helper; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard { - public static partial class NumericCharacterValidation + public static class NumericCharacterValidation { - public static bool IsNumeric(char value) - { - Regex regex = NumericRegex(); - - return regex.IsMatch(value.ToString()); - } - - [GeneratedRegex("[0-9]|.")] - private static partial Regex NumericRegex(); + public static bool IsNumeric(char value) => Patterns.Numeric.IsMatch(value.ToString()); } } diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs index 78c6be164..507e60573 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs @@ -1,37 +1,13 @@ +using Ryujinx.Common.Helper; using System.Text.RegularExpressions; namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Proxy { - static partial class DnsBlacklist + static class DnsBlacklist { - const RegexOptions RegexOpts = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture; - - [GeneratedRegex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", RegexOpts)] - private static partial Regex BlockedHost1(); - [GeneratedRegex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", RegexOpts)] - private static partial Regex BlockedHost2(); - [GeneratedRegex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", RegexOpts)] - private static partial Regex BlockedHost3(); - [GeneratedRegex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", RegexOpts)] - private static partial Regex BlockedHost4(); - [GeneratedRegex(@"^(.*)\-sb\.accounts\.nintendo\.com$", RegexOpts)] - private static partial Regex BlockedHost5(); - [GeneratedRegex(@"^accounts\.nintendo\.com$", RegexOpts)] - private static partial Regex BlockedHost6(); - - private static readonly Regex[] _blockedHosts = - [ - BlockedHost1(), - BlockedHost2(), - BlockedHost3(), - BlockedHost4(), - BlockedHost5(), - BlockedHost6() - ]; - public static bool IsHostBlocked(string host) { - foreach (Regex regex in _blockedHosts) + foreach (Regex regex in Patterns.BlockedHosts) { if (regex.IsMatch(host)) { diff --git a/src/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs b/src/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs index 5217612b9..84f229d8e 100644 --- a/src/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs +++ b/src/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs @@ -2,6 +2,7 @@ using LibHac.Common.FixedArrays; using LibHac.Fs; using LibHac.Loader; using LibHac.Tools.FsSystem; +using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using System; using System.Text; @@ -29,13 +30,6 @@ namespace Ryujinx.HLE.Loaders.Executables public string Name; public Array32 BuildId; - [GeneratedRegex(@"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] - private static partial Regex ModuleRegex(); - [GeneratedRegex(@"sdk_version: ([0-9.]*)")] - private static partial Regex FsSdkRegex(); - [GeneratedRegex(@"SDK MW[ -~]*")] - private static partial Regex SdkMwRegex(); - public NsoExecutable(IStorage inStorage, string name = null) { NsoReader reader = new(); @@ -90,7 +84,7 @@ namespace Ryujinx.HLE.Loaders.Executables if (string.IsNullOrEmpty(modulePath)) { - Match moduleMatch = ModuleRegex().Match(rawTextBuffer); + Match moduleMatch = Patterns.Module.Match(rawTextBuffer); if (moduleMatch.Success) { modulePath = moduleMatch.Value; @@ -99,13 +93,13 @@ namespace Ryujinx.HLE.Loaders.Executables stringBuilder.AppendLine($" Module: {modulePath}"); - Match fsSdkMatch = FsSdkRegex().Match(rawTextBuffer); + Match fsSdkMatch = Patterns.FsSdk.Match(rawTextBuffer); if (fsSdkMatch.Success) { stringBuilder.AppendLine($" FS SDK Version: {fsSdkMatch.Value.Replace("sdk_version: ", string.Empty)}"); } - MatchCollection sdkMwMatches = SdkMwRegex().Matches(rawTextBuffer); + MatchCollection sdkMwMatches = Patterns.SdkMw.Matches(rawTextBuffer); if (sdkMwMatches.Count != 0) { string libHeader = " SDK Libraries: "; diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 5a73dd574..488828482 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -16,6 +16,7 @@ using Ryujinx.Ava.Utilities.Configuration.System; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.GraphicsDriver; +using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Vulkan; @@ -330,9 +331,6 @@ namespace Ryujinx.Ava.UI.ViewModels } } - [GeneratedRegex("Ryujinx-[0-9a-f]{8}")] - private static partial Regex LdnPassphraseRegex(); - public bool IsInvalidLdnPassphraseVisible { get; set; } public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this() @@ -470,7 +468,7 @@ namespace Ryujinx.Ava.UI.ViewModels private bool ValidateLdnPassphrase(string passphrase) { - return string.IsNullOrEmpty(passphrase) || (passphrase.Length == 16 && LdnPassphraseRegex().IsMatch(passphrase)); + return string.IsNullOrEmpty(passphrase) || (passphrase.Length == 16 && Patterns.LdnPassphrase.IsMatch(passphrase)); } public void ValidateAndSetTimeZone(string location)