diff --git a/Clients/CirrusCiClient/CirrusCiClient.csproj b/Clients/CirrusCiClient/CirrusCiClient.csproj
index fe42b3e0..a134d39e 100644
--- a/Clients/CirrusCiClient/CirrusCiClient.csproj
+++ b/Clients/CirrusCiClient/CirrusCiClient.csproj
@@ -11,6 +11,6 @@
-
+
\ No newline at end of file
diff --git a/Clients/CompatApiClient/ApiConfig.cs b/Clients/CompatApiClient/ApiConfig.cs
index ae1465e6..c26f10c5 100644
--- a/Clients/CompatApiClient/ApiConfig.cs
+++ b/Clients/CompatApiClient/ApiConfig.cs
@@ -30,12 +30,12 @@ public static class ApiConfig
{-3, (false, false, false, "Illegal characters found, please try again with a different search term.") },
};
- public static readonly List ResultAmount = new(){25, 50, 100, 200};
+ public static readonly List ResultAmount = [25, 50, 100, 200];
public static readonly Dictionary Directions = new()
{
- {'a', new []{"a", "asc", "ascending"}},
- {'d', new []{"d", "desc", "descending"} },
+ {'a', ["a", "asc", "ascending"] },
+ {'d', ["d", "desc", "descending"] },
};
public static readonly Dictionary Statuses = new()
@@ -58,8 +58,8 @@ public static class ApiConfig
public static readonly Dictionary ReleaseTypes = new()
{
- {'b', new[] {"b", "d", "disc", "disk", "bluray", "blu-ray"}},
- {'n', new[] {"n", "p", "PSN"}},
+ {'b', ["b", "d", "disc", "disk", "bluray", "blu-ray"] },
+ {'n', ["n", "p", "PSN"] },
};
public static readonly Dictionary ReverseDirections;
diff --git a/Clients/CompatApiClient/CompatApiClient.csproj b/Clients/CompatApiClient/CompatApiClient.csproj
index d7eab5a6..d91730b4 100644
--- a/Clients/CompatApiClient/CompatApiClient.csproj
+++ b/Clients/CompatApiClient/CompatApiClient.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/Clients/CompatApiClient/Compression/CompressionMessageHandler.cs b/Clients/CompatApiClient/Compression/CompressionMessageHandler.cs
index 674474ea..ea8196b1 100644
--- a/Clients/CompatApiClient/Compression/CompressionMessageHandler.cs
+++ b/Clients/CompatApiClient/Compression/CompressionMessageHandler.cs
@@ -11,7 +11,7 @@ public class CompressionMessageHandler : DelegatingHandler
{
public ICollection Compressors { get; }
public static readonly string PostCompressionFlag = "X-Set-Content-Encoding";
- public static readonly string[] DefaultContentEncodings = { "gzip", "deflate" };
+ public static readonly string[] DefaultContentEncodings = ["gzip", "deflate"];
public static readonly string DefaultAcceptEncodings = "gzip, deflate";
private readonly bool isServer;
diff --git a/Clients/GithubClient/GithubClient.csproj b/Clients/GithubClient/GithubClient.csproj
index 14e0dae2..e762f69d 100644
--- a/Clients/GithubClient/GithubClient.csproj
+++ b/Clients/GithubClient/GithubClient.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/Clients/IrdLibraryClient/IrdClient.cs b/Clients/IrdLibraryClient/IrdClient.cs
index 01377f9f..9c2e8788 100644
--- a/Clients/IrdLibraryClient/IrdClient.cs
+++ b/Clients/IrdLibraryClient/IrdClient.cs
@@ -24,7 +24,6 @@ public class IrdClient
private readonly HttpClient client;
private readonly JsonSerializerOptions jsonOptions;
- private static readonly Regex IrdFilename = new(@"ird/(?\w{4}\d{5}-[A-F0-9]+\.ird)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase);
public IrdClient()
{
diff --git a/Clients/IrdLibraryClient/IrdLibraryClient.csproj b/Clients/IrdLibraryClient/IrdLibraryClient.csproj
index fb910fc5..9604ca98 100644
--- a/Clients/IrdLibraryClient/IrdLibraryClient.csproj
+++ b/Clients/IrdLibraryClient/IrdLibraryClient.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/Clients/MediafireClient/Client.cs b/Clients/MediafireClient/Client.cs
index 4d1d5b6e..eb72a97d 100644
--- a/Clients/MediafireClient/Client.cs
+++ b/Clients/MediafireClient/Client.cs
@@ -17,7 +17,7 @@
namespace MediafireClient;
-public sealed class Client
+public sealed partial class Client
{
private readonly HttpClient client;
private readonly JsonSerializerOptions jsonOptions;
@@ -25,7 +25,8 @@ public sealed class Client
//var optSecurityToken = "1605819132.376f3d84695f46daa7b69ee67fbc5edb0a00843a8b2d5ac7d3d1b1ad8a4212b0";
//private static readonly Regex SecurityTokenRegex = new(@"(var\s+optSecurityToken|name=""security"" value)\s*=\s*""(?.+)""", RegexOptions.ExplicitCapture);
//var optDirectURL = "https://download1499.mediafire.com/12zqzob7gbfg/tmybrjpmtrpcejl/DemonsSouls_CrashLog_Nov.19th.zip";
- private static readonly Regex DirectUrlRegex = new(@"(var\s+optDirectURL|href)\s*=\s*""(?https?://download\d+\.mediafire\.com/.+)""");
+ [GeneratedRegex(@"(var\s+optDirectURL|href)\s*=\s*""(?https?://download\d+\.mediafire\.com/.+)""")]
+ private static partial Regex DirectUrlRegex();
public Client()
{
@@ -81,7 +82,7 @@ public Client()
{
await response.Content.LoadIntoBufferAsync().ConfigureAwait(false);
var html = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
- var m = DirectUrlRegex.Match(html);
+ var m = DirectUrlRegex().Match(html);
if (m.Success)
return new(m.Groups["direct_link"].Value);
}
diff --git a/Clients/PsnClient/PsnClient.cs b/Clients/PsnClient/PsnClient.cs
index 1b77c717..e3b2fd99 100644
--- a/Clients/PsnClient/PsnClient.cs
+++ b/Clients/PsnClient/PsnClient.cs
@@ -20,7 +20,7 @@
namespace PsnClient;
-public class Client
+public partial class Client
{
private readonly HttpClient client;
private readonly JsonSerializerOptions dashedJson;
@@ -28,23 +28,27 @@ public class Client
private readonly MediaTypeFormatterCollection xmlFormatters;
private static readonly MemoryCache ResponseCache = new(new MemoryCacheOptions { ExpirationScanFrequency = TimeSpan.FromHours(1) });
private static readonly TimeSpan ResponseCacheDuration = TimeSpan.FromHours(1);
- private static readonly Regex ContainerIdLink = new(@"(?STORE-(\w|\d)+-(\w|\d)+)");
private static readonly string[] KnownStoreLocales =
- {
+ [
"en-US", "en-GB", "en-AE", "en-AU", "en-BG", "en-BH", "en-CA", "en-CY", "en-CZ", "en-DK", "en-FI", "en-GR", "en-HK", "en-HR", "en-HU", "en-ID", "en-IE", "en-IL", "en-IN", "en-IS",
"en-KW", "en-LB", "en-MT", "en-MY", "en-NO", "en-NZ", "en-OM", "en-PL", "en-QA", "en-RO", "en-SA", "en-SE", "en-SG", "en-SI", "en-SK", "en-TH", "en-TR", "en-TW", "en-ZA", "ja-JP",
"ar-AE", "ar-BH", "ar-KW", "ar-LB", "ar-OM", "ar-QA", "ar-SA", "da-DK", "de-AT", "de-CH", "de-DE", "de-LU", "es-AR", "es-BO", "es-CL", "es-CO", "es-CR", "es-EC", "es-ES", "es-GT",
"es-HN", "es-MX", "es-NI", "es-PA", "es-PE", "es-PY", "es-SV", "es-UY", "fi-FI", "fr-BE", "fr-CA", "fr-CH", "fr-FR", "fr-LU", "it-CH", "it-IT", "ko-KR", "nl-BE", "nl-NL", "no-NO",
"pl-PL", "pt-BR", "pt-PT", "ru-RU", "ru-UA", "sv-SE", "tr-TR", "zh-Hans-CN", "zh-Hans-HK", "zh-Hant-HK", "zh-Hant-TW",
- };
+ ];
+
+ [GeneratedRegex(@"(?STORE-(\w|\d)+-(\w|\d)+)")]
+ private static partial Regex ContainerIdLink();
+
// Dest=87;ImageVersion=0001091d;SystemSoftwareVersion=4.8500;CDN=http://duk01.ps3.update.playstation.net/update/ps3/image/uk/2019_0828_c975768e5d70e105a72656f498cc9be9/PS3UPDAT.PUP;CDN_Timeout=30;
- private static readonly Regex FwVersionInfo = new(
+ [GeneratedRegex(
@"Dest=(?\d+);ImageVersion=(?[0-9a-f]+);SystemSoftwareVersion=(?\d+\.\d+);CDN=(?http[^;]+);CDN_Timeout=(?\d+)",
- RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.Singleline | RegexOptions.IgnoreCase
- );
+ RegexOptions.ExplicitCapture | RegexOptions.Singleline | RegexOptions.IgnoreCase
+ )]
+ private static partial Regex FwVersionInfo();
// directly from vsh.self
- private static readonly string[] KnownFwLocales = { "jp", "us", "eu", "kr", "uk", "mx", "au", "sa", "tw", "ru", "cn", "br", };
+ private static readonly string[] KnownFwLocales = ["jp", "us", "eu", "kr", "uk", "mx", "au", "sa", "tw", "ru", "cn", "br",];
public Client()
{
@@ -117,7 +121,7 @@ public Client()
tries++;
}
if (response.StatusCode == HttpStatusCode.Redirect)
- return new(0);
+ return [];
}
using (response)
@@ -125,7 +129,7 @@ public Client()
{
await response.Content.LoadIntoBufferAsync().ConfigureAwait(false);
var html = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
- var matches = ContainerIdLink.Matches(html);
+ var matches = ContainerIdLink().Matches(html);
var result = new List();
foreach (Match m in matches)
if (m.Groups["id"].Value is {Length: >0} id)
@@ -345,7 +349,7 @@ public async Task> GetHighestFwVersionAsync(CancellationToken
allVersions = allVersions.OrderByDescending(fwi => fwi.Version).ToList();
if (allVersions.Count == 0)
- return new(0);
+ return [];
var maxFw = allVersions.First();
var result = allVersions.Where(fwi => fwi.Version == maxFw.Version).ToList();
@@ -419,7 +423,7 @@ private async Task GetSessionCookies(string locale, CancellationToken ca
if (string.IsNullOrEmpty(data))
return null;
- if (FwVersionInfo.Match(data) is not { Success: true } m)
+ if (FwVersionInfo().Match(data) is not { Success: true } m)
return null;
var ver = m.Groups["version"].Value;
diff --git a/Clients/PsnClient/Utils/TmdbHasher.cs b/Clients/PsnClient/Utils/TmdbHasher.cs
index 8fa4167f..a21d98f7 100644
--- a/Clients/PsnClient/Utils/TmdbHasher.cs
+++ b/Clients/PsnClient/Utils/TmdbHasher.cs
@@ -18,7 +18,7 @@ public static string GetTitleHash(string productId)
public static byte[] FromHexString(this string hexString)
{
if (hexString.Length == 0)
- return Array.Empty();
+ return [];
if (hexString.Length % 2 != 0)
throw new ArgumentException("Invalid hex string format: odd number of octets", nameof(hexString));
diff --git a/CompatBot/Commands/BotStats.cs b/CompatBot/Commands/BotStats.cs
index 12322d07..9cef4555 100644
--- a/CompatBot/Commands/BotStats.cs
+++ b/CompatBot/Commands/BotStats.cs
@@ -308,7 +308,7 @@ private static void AppendPawStats(DiscordEmbedBuilder embed)
}
}
- internal static readonly string[] GoodDog = {"๐ถ", "๐", "๐ฉ", "๐โ๐ฆบ",};
- internal static readonly string[] GoodKot = {"๐ธ", "๐บ", "๐ป", "๐ฝ",};
- private static readonly string[] MeanKot = {"๐", "๐ฟ", "๐พ",};
+ internal static readonly string[] GoodDog = ["๐ถ", "๐", "๐ฉ", "๐โ๐ฆบ",];
+ internal static readonly string[] GoodKot = ["๐ธ", "๐บ", "๐ป", "๐ฝ",];
+ private static readonly string[] MeanKot = ["๐", "๐ฟ", "๐พ",];
}
\ No newline at end of file
diff --git a/CompatBot/Commands/CompatList.cs b/CompatBot/Commands/CompatList.cs
index 746d8291..e1048892 100644
--- a/CompatBot/Commands/CompatList.cs
+++ b/CompatBot/Commands/CompatList.cs
@@ -32,7 +32,7 @@
namespace CompatBot.Commands;
-internal sealed class CompatList : BaseCommandModuleCustom
+internal sealed partial class CompatList : BaseCommandModuleCustom
{
private static readonly Client Client = new();
private static readonly GithubClient.Client GithubClient = new(Config.GithubToken);
@@ -41,10 +41,10 @@ internal sealed class CompatList : BaseCommandModuleCustom
private const string Rpcs3UpdateStateKey = "Rpcs3UpdateState";
private const string Rpcs3UpdateBuildKey = "Rpcs3UpdateBuild";
private static UpdateInfo? cachedUpdateInfo;
- private static readonly Regex UpdateVersionRegex = new(
- @"v(?\d+\.\d+\.\d+)-(?\d+)-(?[0-9a-f]+)\b",
- RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture
- );
+ [GeneratedRegex(@"v(?\d+\.\d+\.\d+)-(?\d+)-(?[0-9a-f]+)\b", RegexOptions.Singleline | RegexOptions.ExplicitCapture)]
+ private static partial Regex UpdateVersionRegex();
+ [GeneratedRegex(@"\b(demo|trial)\b", RegexOptions.IgnoreCase | RegexOptions.Singleline)]
+ internal static partial Regex TrialNamePattern();
static CompatList()
{
@@ -247,7 +247,7 @@ public static async Task CheckForRpcs3Updates(DiscordClient discordClient,
var latestUpdatePr = info?.LatestBuild?.Pr?.ToString();
var match = (
from field in embed.Fields
- let m = UpdateVersionRegex.Match(field.Value)
+ let m = UpdateVersionRegex().Match(field.Value)
where m.Success
select m
).FirstOrDefault();
@@ -430,7 +430,7 @@ private static async Task DoRequestAndRespond(CommandContext ctx, RequestBuilder
#endif
var channel = await ctx.GetChannelForSpamAsync().ConfigureAwait(false);
if (result?.Results?.Count == 1)
- await ProductCodeLookup.LookupAndPostProductCodeEmbedAsync(ctx.Client, ctx.Message, ctx.Channel, new(result.Results.Keys)).ConfigureAwait(false);
+ await ProductCodeLookup.LookupAndPostProductCodeEmbedAsync(ctx.Client, ctx.Message, ctx.Channel, [..result.Results.Keys]).ConfigureAwait(false);
else if (result != null)
foreach (var msg in FormatSearchResults(ctx, result))
await channel.SendAutosplitMessageAsync(msg, blockStart: "", blockEnd: "").ConfigureAwait(false);
@@ -597,7 +597,7 @@ public static async Task ImportMetacriticScoresAsync()
}
}
- var scoreList = JsonSerializer.Deserialize>(json) ?? new();
+ var scoreList = JsonSerializer.Deserialize>(json) ?? [];
Config.Log.Debug($"Importing {scoreList.Count} Metacritic items");
var duplicates = new List();
@@ -666,7 +666,7 @@ public static async Task ImportMetacriticScoresAsync()
.Where(i => i.coef > 0.85)
.OrderByDescending(i => i.coef)
.ToList()
- ?? new List<(string productCode, TitleInfo titleInfo, double coef)>();
+ ?? [];
if (compatListMatches.Any(i => i.coef > 0.99))
compatListMatches = compatListMatches.Where(i => i.coef > 0.99).ToList();
else if (compatListMatches.Any(i => i.coef > 0.95))
@@ -697,7 +697,7 @@ public static async Task ImportMetacriticScoresAsync()
Config.Log.Warn(e);
}
}
- matches = matches.Where(i => !Regex.IsMatch(i.thumb.Name ?? "", @"\b(demo|trial)\b", RegexOptions.IgnoreCase | RegexOptions.Singleline)).ToList();
+ matches = matches.Where(i => !TrialNamePattern().IsMatch(i.thumb.Name ?? "")).ToList();
//var bestMatch = matches.FirstOrDefault();
//Config.Log.Trace($"Best title match for [{item.Title}] is [{bestMatch.thumb.Name}] with score {bestMatch.coef:0.0000}");
if (matches.Count > 0)
diff --git a/CompatBot/Commands/ContentFilters.cs b/CompatBot/Commands/ContentFilters.cs
index abadf51a..0b85a30e 100644
--- a/CompatBot/Commands/ContentFilters.cs
+++ b/CompatBot/Commands/ContentFilters.cs
@@ -29,12 +29,16 @@ namespace CompatBot.Commands;
[Group("filters"), Aliases("piracy", "filter"), RequiresBotSudoerRole, RequiresDm]
[Description("Used to manage content filters. **Works only in DM**")]
-internal sealed class ContentFilters: BaseCommandModuleCustom
+internal sealed partial class ContentFilters: BaseCommandModuleCustom
{
private static readonly TimeSpan InteractTimeout = TimeSpan.FromMinutes(5);
- private static readonly char[] Separators = {' ', ',', ';', '|'};
+ private static readonly char[] Separators = [' ', ',', ';', '|'];
private static readonly SemaphoreSlim ImportLock = new(1, 1);
+ // match for "complex" names with several regions, or region-languages, or explicit revision
+ [GeneratedRegex(@" (\(.+\)\s*\(.+\)|\(\w+(,\s*\w+)+\))\.iso$")]
+ private static partial Regex ExtraIsoInfoPattern();
+
[Command("list")]
[Description("Lists all filters")]
public async Task List(CommandContext ctx)
@@ -202,8 +206,8 @@ public async Task Import(CommandContext ctx)
if (string.IsNullOrEmpty(name))
continue;
- // only match for "complex" names with several regions, or region-languages, or explicit revision
- if (!Regex.IsMatch(name, @" (\(.+\)\s*\(.+\)|\(\w+(,\s*\w+)+\))\.iso$"))
+
+ if (!ExtraIsoInfoPattern().IsMatch(name))
continue;
name = name[..^4]; //-.iso
@@ -710,7 +714,12 @@ Additional validation can help reduce false positives of a plaintext trigger mat
{
try
{
- _ = Regex.IsMatch("test", txt.Content, RegexOptions.Multiline | RegexOptions.IgnoreCase);
+ _ = Regex.IsMatch(
+ filter.String ?? "test",
+ txt.Content,
+ RegexOptions.Multiline | RegexOptions.IgnoreCase,
+ TimeSpan.FromMilliseconds(100)
+ );
}
catch (Exception e)
{
diff --git a/CompatBot/Commands/Converters/TextOnlyDiscordChannelConverter.cs b/CompatBot/Commands/Converters/TextOnlyDiscordChannelConverter.cs
index 78b3f082..2108c7e7 100644
--- a/CompatBot/Commands/Converters/TextOnlyDiscordChannelConverter.cs
+++ b/CompatBot/Commands/Converters/TextOnlyDiscordChannelConverter.cs
@@ -10,9 +10,10 @@
namespace CompatBot.Commands.Converters;
-internal sealed class TextOnlyDiscordChannelConverter : IArgumentConverter
+internal sealed partial class TextOnlyDiscordChannelConverter : IArgumentConverter
{
- private static Regex ChannelRegex { get; } = new(@"^<#(\d+)>$", RegexOptions.ECMAScript | RegexOptions.Compiled);
+ [GeneratedRegex(@"^<#(\d+)>$", RegexOptions.ECMAScript)]
+ private static partial Regex ChannelRegex();
Task> IArgumentConverter.ConvertAsync(string value, CommandContext ctx)
=> ConvertAsync(value, ctx);
@@ -20,7 +21,7 @@ Task> IArgumentConverter.ConvertAsync(s
public static async Task> ConvertAsync(string value, CommandContext ctx)
{
var guildList = new List(ctx.Client.Guilds.Count);
- if (ctx.Guild == null)
+ if (ctx.Guild is null)
foreach (var g in ctx.Client.Guilds.Keys)
guildList.Add(await ctx.Client.GetGuildAsync(g).ConfigureAwait(false));
else
@@ -37,7 +38,7 @@ select ch
return ret;
}
- var m = ChannelRegex.Match(value);
+ var m = ChannelRegex().Match(value);
if (m.Success && ulong.TryParse(m.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out cid))
{
var result = (
diff --git a/CompatBot/Commands/EventsBaseCommand.cs b/CompatBot/Commands/EventsBaseCommand.cs
index 0b71b50e..b7ded652 100644
--- a/CompatBot/Commands/EventsBaseCommand.cs
+++ b/CompatBot/Commands/EventsBaseCommand.cs
@@ -19,11 +19,12 @@
namespace CompatBot.Commands;
-internal class EventsBaseCommand: BaseCommandModuleCustom
+internal partial class EventsBaseCommand: BaseCommandModuleCustom
{
private static readonly TimeSpan InteractTimeout = TimeSpan.FromMinutes(5);
- private static readonly Regex Duration = new(@"((?\d+)(\.|d\s*))?((?\d+)(\:|h\s*))?((?\d+)m?)?",
- RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture);
+
+ [GeneratedRegex(@"((?\d+)(\.|d\s*))?((?\d+)(\:|h\s*))?((?\d+)m?)?", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture)]
+ private static partial Regex Duration();
protected static async Task NearestEvent(CommandContext ctx, string? eventName = null)
{
@@ -546,7 +547,7 @@ protected static async Task List(CommandContext ctx, string? eventName = null, i
private static async Task TryParseTimeSpanAsync(CommandContext ctx, string duration, bool react = true)
{
- var d = Duration.Match(duration);
+ var d = Duration().Match(duration);
if (!d.Success)
{
if (react)
diff --git a/CompatBot/Commands/Explain.cs b/CompatBot/Commands/Explain.cs
index f8529910..5f0c8c86 100644
--- a/CompatBot/Commands/Explain.cs
+++ b/CompatBot/Commands/Explain.cs
@@ -6,6 +6,7 @@
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Text;
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CompatApiClient.Compression;
using CompatApiClient.Utils;
@@ -330,7 +331,7 @@ public async Task Dump(CommandContext ctx, [RemainingText, Description("Term to
return;
termOrLink = termOrLink.ToLowerInvariant().StripQuotes();
- var isLink = CommandContextExtensions.MessageLinkRegex.IsMatch(termOrLink);
+ var isLink = CommandContextExtensions.MessageLinkPattern().IsMatch(termOrLink);
if (isLink)
{
await DumpLink(ctx, termOrLink).ConfigureAwait(false);
diff --git a/CompatBot/Commands/ForcedNicknames.cs b/CompatBot/Commands/ForcedNicknames.cs
index d73f06aa..430f26ff 100644
--- a/CompatBot/Commands/ForcedNicknames.cs
+++ b/CompatBot/Commands/ForcedNicknames.cs
@@ -49,12 +49,12 @@ public async Task Rename(CommandContext ctx,
List guilds;
if (ctx.Guild == null)
{
- guilds = ctx.Client.Guilds?.Values.ToList() ?? new List(0);
+ guilds = ctx.Client.Guilds?.Values.ToList() ?? [];
if (guilds.Count > 1)
await ctx.Channel.SendMessageAsync($"{discordUser.Mention} will be renamed in all {guilds.Count} servers").ConfigureAwait(false);
}
else
- guilds = new(){ctx.Guild};
+ guilds = [ctx.Guild];
int changed = 0, noPermissions = 0, failed = 0;
await using var db = new BotDb();
diff --git a/CompatBot/Commands/Minesweeper.cs b/CompatBot/Commands/Minesweeper.cs
index 642b51cf..d114e059 100644
--- a/CompatBot/Commands/Minesweeper.cs
+++ b/CompatBot/Commands/Minesweeper.cs
@@ -14,9 +14,9 @@ namespace CompatBot.Commands;
[Description("Generates a minesweeper field with specified parameters")]
internal sealed class Minesweeper : BaseCommandModuleCustom
{
- //private static readonly string[] Numbers = {"0๏ธโฃ", "1๏ธโฃ", "2๏ธโฃ", "3๏ธโฃ", "4๏ธโฃ", "5๏ธโฃ", "6๏ธโฃ", "7๏ธโฃ", "8๏ธโฃ", "9๏ธโฃ",};
- private static readonly string[] Numbers = {"๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ",};
- private static readonly string[] Bombs = {"๏ผ", "โ"};
+ //private static readonly string[] Numbers = ["0๏ธโฃ", "1๏ธโฃ", "2๏ธโฃ", "3๏ธโฃ", "4๏ธโฃ", "5๏ธโฃ", "6๏ธโฃ", "7๏ธโฃ", "8๏ธโฃ", "9๏ธโฃ"];
+ private static readonly string[] Numbers = ["๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ", "๏ผ"];
+ private static readonly string[] Bombs = ["๏ผ", "โ"];
private static readonly int MaxBombLength;
static Minesweeper()
diff --git a/CompatBot/Commands/Misc.cs b/CompatBot/Commands/Misc.cs
index 0999ca6c..31570b49 100644
--- a/CompatBot/Commands/Misc.cs
+++ b/CompatBot/Commands/Misc.cs
@@ -16,12 +16,12 @@
namespace CompatBot.Commands;
-internal sealed class Misc: BaseCommandModuleCustom
+internal sealed partial class Misc: BaseCommandModuleCustom
{
private static readonly Random rng = new();
- private static readonly List EightBallAnswers = new()
- {
+ private static readonly List EightBallAnswers =
+ [
// keep this at 2:1:1 ratio
// 70
"It is certain", "It is decidedly so", "Without a doubt", "Yes definitely", "You may rely on it",
@@ -40,7 +40,7 @@ internal sealed class Misc: BaseCommandModuleCustom
"Bones said yes", "Tea leaves settled in a 'yes' pattern", "Dice roll was solid, so yes", "No doubt about it", "Hmmm, I think so", // 70
// 30
- "Reply hazy, try again", "Ask again later", "Better not tell you now", "Cannot predict now", "Concentrate and ask again",
+ "Reply hazy, try again", "Ask again later", "Better not tell you now", "Cannot predict now", "Concentrate and ask again",
"Maybe", "I don't know", "I don't care", "Who cares", "Maybe yes, maybe not", // 10
"Maybe not, maybe yes", "Ugh", "Probably", "Error 404: answer not found", "Crystal ball is cloudy as milk, ask later",
"Don't ask me that again", "You should think twice before asking", "You what now?", "Ask Neko", "Ask Ani", // 20
@@ -55,11 +55,11 @@ internal sealed class Misc: BaseCommandModuleCustom
"Nein!", "I think not", "I'm afraid not", "Nay", "Yesn't",
"No way", "Certainly not", "I must say no", "Nah", "Negative", // 30
"Definitely not", "No way, Jose", "Not today", "No no no no no no no no no no. No.", "Not in a million years",
- "I'm afraid I can't let you do that Dave.", "This mission is too important for me to allow you to jeopardize it.", "Oh, I don't think so", "By *no* means", "๐", // 40
- };
+ "I'm afraid I can't let you do that Dave.", "This mission is too important for me to allow you to jeopardize it.", "Oh, I don't think so", "By *no* means", "๐" // 40
+ ];
- private static readonly List EightBallSnarkyComments = new()
- {
+ private static readonly List EightBallSnarkyComments =
+ [
"Can't answer the question that wasn't asked",
"Having issues with my mind reading attachment, you'll have to state your question explicitly",
"Bad reception on your brain waves today, can't read the question",
@@ -67,18 +67,17 @@ internal sealed class Misc: BaseCommandModuleCustom
"In Discord no one can read your question if you don't type it",
"In space no one can hear you scream; that's what you're doing right now",
"Unfortunately there's no technology to transmit your question telepathically just yet",
- "I'd say maybe, but I'd need to see your question first",
- };
+ "I'd say maybe, but I'd need to see your question first"
+ ];
- private static readonly List EightBallTimeUnits = new()
- {
+ private static readonly List EightBallTimeUnits =
+ [
"second", "minute", "hour", "day", "week", "month", "year", "decade", "century", "millennium",
- "night", "moon cycle", "solar eclipse", "blood moon", "complete emulator rewrite",
- };
+ "night", "moon cycle", "solar eclipse", "blood moon", "complete emulator rewrite"
+ ];
- private static readonly List RateAnswers = new()
- {
- // 60
+ private static readonly List RateAnswers =
+ [
"Not so bad", "I likesss!", "Pretty good", "Guchi gud", "Amazing!",
"Glorious!", "Very good", "Excellent...", "Magnificent", "Rate bot says he likes, so you like too",
"If you reorganize the words it says \"pretty cool\"", "I approve", "<:morgana_sparkle:315899996274688001>ใใใใใใญใผใ๏ผ", "Not half bad ๐", "Belissimo!",
@@ -109,11 +108,11 @@ internal sealed class Misc: BaseCommandModuleCustom
"Boring", "Easily forgettable", "An Abomination", "A Monstrosity", "Truly horrific",
"Filled with despair!", "Eroded by despair", "Hopelessโฆ", "It's pretty foolish to want to rate this", "Cursed with misfortune",
"Nothing but terror", "Not good, at all", "A waste of time",
- };
+ ];
- private static readonly char[] Separators = { ' ', 'ใ', '\r', '\n' };
- private static readonly char[] Suffixes = {',', '.', ':', ';', '!', '?', ')', '}', ']', '>', '+', '-', '/', '*', '=', '"', '\'', '`'};
- private static readonly char[] Prefixes = {'@', '(', '{', '[', '<', '!', '`', '"', '\'', '#'};
+ private static readonly char[] Separators = [' ', 'ใ', '\r', '\n'];
+ private static readonly char[] Suffixes = [',', '.', ':', ';', '!', '?', ')', '}', ']', '>', '+', '-', '/', '*', '=', '"', '\'', '`'];
+ private static readonly char[] Prefixes = ['@', '(', '{', '[', '<', '!', '`', '"', '\'', '#'];
private static readonly char[] EveryTimable = Separators.Concat(Suffixes).Concat(Prefixes).Distinct().ToArray();
private static readonly HashSet Me = new(StringComparer.InvariantCultureIgnoreCase)
@@ -126,9 +125,12 @@ internal sealed class Misc: BaseCommandModuleCustom
"your", "you're", "yor", "ur", "yours", "your's",
};
- private static readonly HashSet Vowels = new() {'a', 'e', 'i', 'o', 'u'};
+ private static readonly HashSet Vowels = ['a', 'e', 'i', 'o', 'u'];
- private static readonly Regex Instead = new("rate (?.+) instead", RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.Singleline);
+ [GeneratedRegex("rate (?.+) instead", RegexOptions.ExplicitCapture | RegexOptions.Singleline)]
+ private static partial Regex Instead();
+ [GeneratedRegex(@"(?\d+)?d(?\d+)(?:\+(?\d+))?")]
+ private static partial Regex DiceNotationPattern();
[Command("roll")]
[Description("Generates a random number between 1 and maxValue. Can also roll dices like `2d6`. Default is 1d6")]
@@ -155,7 +157,7 @@ internal static async Task RollImpl(DiscordMessage message, string dices)
{
var result = "";
var embed = new DiscordEmbedBuilder();
- if (dices is string dice && Regex.Matches(dice, @"(?\d+)?d(?\d+)(?:\+(?\d+))?") is {Count: > 0 and <= EmbedPager.MaxFields } matches)
+ if (dices is string dice && DiceNotationPattern().Matches(dice) is {Count: > 0 and <= EmbedPager.MaxFields } matches)
{
var grandTotal = 0;
foreach (Match m in matches)
@@ -241,7 +243,7 @@ public async Task RandomShit(CommandContext ctx, string stuff)
return;
}
- await ProductCodeLookup.LookupAndPostProductCodeEmbedAsync(ctx.Client, ctx.Message, ctx.Channel, new() {productCode.ProductCode}).ConfigureAwait(false);
+ await ProductCodeLookup.LookupAndPostProductCodeEmbedAsync(ctx.Client, ctx.Message, ctx.Channel, [productCode.ProductCode]).ConfigureAwait(false);
break;
}
default:
@@ -318,7 +320,7 @@ public async Task Rate(CommandContext ctx, [RemainingText, Description("Somethin
var choiceFlags = new HashSet();
whatever = whatever.ToLowerInvariant().StripInvisibleAndDiacritics();
var originalWhatever = whatever;
- var matches = Instead.Matches(whatever);
+ var matches = Instead().Matches(whatever);
if (matches.Any())
{
var insteadWhatever = matches.Last().Groups["instead"].Value.TrimEager();
diff --git a/CompatBot/Commands/Psn.Check.cs b/CompatBot/Commands/Psn.Check.cs
index d4e82555..48b10421 100644
--- a/CompatBot/Commands/Psn.Check.cs
+++ b/CompatBot/Commands/Psn.Check.cs
@@ -1,6 +1,7 @@
๏ปฟusing System;
using System.Collections.Generic;
using System.Linq;
+using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using CompatApiClient;
@@ -107,15 +108,15 @@ public async Task Updates(CommandContext ctx, [RemainingText, Description("Produ
catch (Exception e)
{
Config.Log.Warn(e, "Failed to get title update info");
- embeds = new()
- {
+ embeds =
+ [
new()
{
Color = Config.Colors.Maintenance,
Title = "Service is unavailable",
Description = "There was an error communicating with the service. Try again in a few minutes.",
}
- };
+ ];
}
if (ctx.IsOnionLike()
@@ -158,7 +159,7 @@ public async Task Content(CommandContext ctx, [RemainingText, Description("Conte
return;
}
- var matches = PsnScraper.ContentIdMatcher.Matches(contentIds.ToUpperInvariant());
+ var matches = PsnScraper.ContentIdMatcher().Matches(contentIds.ToUpperInvariant());
var itemsToCheck = matches.Select(m => m.Groups["content_id"].Value).ToList();
if (itemsToCheck.Count == 0)
{
diff --git a/CompatBot/Commands/Psn.cs b/CompatBot/Commands/Psn.cs
index 0cd056d8..92763af6 100644
--- a/CompatBot/Commands/Psn.cs
+++ b/CompatBot/Commands/Psn.cs
@@ -1,4 +1,5 @@
๏ปฟusing System.Linq;
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CompatBot.Commands.Attributes;
using CompatBot.Database;
@@ -39,8 +40,8 @@ public async Task Rename(CommandContext ctx, [Description("Product code such as
public async Task Add(CommandContext ctx, [Description("Product code such as BLUS12345")] string contentId, [RemainingText, Description("New game title to save in the database")] string title)
{
contentId = contentId.ToUpperInvariant();
- var productCodeMatch = ProductCodeLookup.ProductCode.Match(contentId);
- var contentIdMatch = PsnScraper.ContentIdMatcher.Match(contentId);
+ var productCodeMatch = ProductCodeLookup.Pattern().Match(contentId);
+ var contentIdMatch = PsnScraper.ContentIdMatcher().Match(contentId);
string productCode;
if (contentIdMatch.Success)
{
diff --git a/CompatBot/Commands/Sudo.Dotnet.cs b/CompatBot/Commands/Sudo.Dotnet.cs
index 91e4bb53..27511303 100644
--- a/CompatBot/Commands/Sudo.Dotnet.cs
+++ b/CompatBot/Commands/Sudo.Dotnet.cs
@@ -17,6 +17,9 @@ internal partial class Sudo
[Description("Commands to manage dotnet")]
public sealed partial class Dotnet : BaseCommandModuleCustom
{
+ [GeneratedRegex(@"\.NET( Core)? (?\d+)\.(?\d+)\.(?\d+)(-.+)?", RegexOptions.ExplicitCapture | RegexOptions.Singleline)]
+ private static partial Regex DotnetVersionPattern();
+
[Command("update"), Aliases("upgrade")]
[Description("Updates dotnet, and then restarts the bot")]
public async Task Update(CommandContext ctx, [Description("Dotnet SDK version (e.g. `5.1`)")] string version = "")
@@ -67,11 +70,7 @@ public async Task Update(CommandContext ctx, [Description("Dotnet SDK version (e
if (string.IsNullOrEmpty(version))
{
- var versionMatch = Regex.Match(
- System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription,
- @"\.NET( Core)? (?\d+)\.(?\d+)\.(?\d+)(-.+)?",
- RegexOptions.Singleline | RegexOptions.ExplicitCapture
- );
+ var versionMatch = DotnetVersionPattern().Match(System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription);
if (!versionMatch.Success)
throw new InvalidOperationException("Failed to resolve required dotnet sdk version");
@@ -102,6 +101,5 @@ public async Task Update(CommandContext ctx, [Description("Dotnet SDK version (e
return (true, stdout);
}
-
}
}
\ No newline at end of file
diff --git a/CompatBot/Commands/Sudo.Fix.cs b/CompatBot/Commands/Sudo.Fix.cs
index bd5daeb5..bc3db300 100644
--- a/CompatBot/Commands/Sudo.Fix.cs
+++ b/CompatBot/Commands/Sudo.Fix.cs
@@ -144,7 +144,7 @@ public async Task TitleMarks(CommandContext ctx)
{
if (demosOnly
&& thumb.Name != null
- && !Regex.IsMatch(thumb.Name, @"\b(demo|trial)\b", RegexOptions.IgnoreCase | RegexOptions.Singleline))
+ && !CompatList.TrialNamePattern().IsMatch(thumb.Name))
continue;
thumb.MetacriticId = null;
diff --git a/CompatBot/Commands/Sudo.cs b/CompatBot/Commands/Sudo.cs
index 2f0effa9..c6c94a94 100644
--- a/CompatBot/Commands/Sudo.cs
+++ b/CompatBot/Commands/Sudo.cs
@@ -135,18 +135,21 @@ public async Task Log(CommandContext ctx, [Description("Specific date")]string d
try
{
Config.Log.Factory.Flush();
- var logPath = Config.CurrentLogPath;
+ string[] logPaths = [Config.CurrentLogPath];
if (DateTime.TryParse(date, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var logDate))
- logPath = Path.Combine(Config.LogPath, $"bot.{logDate:yyyyMMdd}.*.log");
- if (!File.Exists(logPath))
{
- await ctx.ReactWithAsync(Config.Reactions.Failure, "Log file does not exist for specified day", true).ConfigureAwait(false);
+ var enumOptions = new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = false, };
+ logPaths = Directory.GetFiles(Config.LogPath, $"bot.{logDate:yyyyMMdd}.*.log", enumOptions);
+ }
+ if (logPaths.Length is 0)
+ {
+ await ctx.ReactWithAsync(Config.Reactions.Failure, "Log files do not exist for specified day", true).ConfigureAwait(false);
return;
}
await using var result = Config.MemoryStreamManager.GetStream();
using (var zip = new ZipWriter(result, new(CompressionType.LZMA){DeflateCompressionLevel = CompressionLevel.Default}))
- foreach (var fname in Directory.EnumerateFiles(Config.LogPath, Path.GetFileName(logPath), new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = false, }))
+ foreach (var fname in logPaths)
{
await using var log = File.Open(fname, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
zip.Write(Path.GetFileName(fname), log);
@@ -155,7 +158,7 @@ public async Task Log(CommandContext ctx, [Description("Specific date")]string d
if (result.Length <= ctx.GetAttachmentSizeLimit())
{
result.Seek(0, SeekOrigin.Begin);
- await ctx.Channel.SendMessageAsync(new DiscordMessageBuilder().AddFile(Path.GetFileName(logPath) + ".zip", result)).ConfigureAwait(false);
+ await ctx.Channel.SendMessageAsync(new DiscordMessageBuilder().AddFile(Path.GetFileName(logPaths[0]) + ".zip", result)).ConfigureAwait(false);
}
else
await ctx.ReactWithAsync(Config.Reactions.Failure, "Compressed log size is too large, ask 13xforever for help :(", true).ConfigureAwait(false);
diff --git a/CompatBot/Commands/Vision.cs b/CompatBot/Commands/Vision.cs
index 7f2a97b7..283e83e5 100644
--- a/CompatBot/Commands/Vision.cs
+++ b/CompatBot/Commands/Vision.cs
@@ -49,26 +49,26 @@ static Vision()
{
["cat"] = BotStats.GoodKot,
["dog"] = BotStats.GoodDog,
- ["hedgehog"] = new[] {"๐ฆ"},
- ["flower"] = new[] {"๐ท", "๐ธ", "๐น", "๐บ", "๐ผ", "๐ฅ", "๐", "๐ป", "๐ฎ",},
- ["lizard"] = new[] {"๐ฆ",},
- ["bird"] = new[] {"๐ฆ", "๐", "๐ฆ", "๐ฆ", "๐ฆ
", "๐", "๐ค", "๐ฆฉ",},
- ["duck"] = new[] {"๐ฆ",},
- ["eagle"] = new[] {"๐ฆ
",},
- ["turkey"] = new[] {"๐ฆ",},
- ["turtle"] = new[] {"๐ข",},
- ["bear"] = new[] {"๐ป", "๐ผ",},
- ["panda"] = new[] {"๐ผ",},
- ["fox"] = new[] {"๐ฆ",},
- ["pig"] = new[] {"๐ท", "๐", "๐ฝ", "๐",},
- ["primate"] = new[] {"๐ต", "๐", "๐", "๐", "๐",},
- ["fish"] = new[] {"๐", "๐ ", "๐ก", "๐ฆ",},
- ["car"] = new[] {"๐", "๐", "๐", "๐", "๐", "๐",},
- ["banana"] = new[] {"๐"},
- ["fruit"] = new[] {"๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐ฅ", "๐ฅ", "๐ฅญ", "๐
",},
- ["vegetable"] = new[] {"๐ ", "๐
", "๐", "๐ฅ", "๐ฅ", "๐ฅ",},
- ["watermelon"] = new[] {"๐",},
- ["strawberry"] = new[] {"๐",},
+ ["hedgehog"] = ["๐ฆ",],
+ ["flower"] = ["๐ท", "๐ธ", "๐น", "๐บ", "๐ผ", "๐ฅ", "๐", "๐ป", "๐ฎ",],
+ ["lizard"] = ["๐ฆ",],
+ ["bird"] = ["๐ฆ", "๐", "๐ฆ", "๐ฆ", "๐ฆ
", "๐", "๐ค", "๐ฆฉ",],
+ ["duck"] = ["๐ฆ",],
+ ["eagle"] = ["๐ฆ
",],
+ ["turkey"] = ["๐ฆ",],
+ ["turtle"] = ["๐ข",],
+ ["bear"] = ["๐ป", "๐ผ",],
+ ["panda"] = ["๐ผ",],
+ ["fox"] = ["๐ฆ",],
+ ["pig"] = ["๐ท", "๐", "๐ฝ", "๐",],
+ ["primate"] = ["๐ต", "๐", "๐", "๐", "๐",],
+ ["fish"] = ["๐", "๐ ", "๐ก", "๐ฆ",],
+ ["car"] = ["๐", "๐", "๐", "๐", "๐", "๐",],
+ ["banana"] = ["๐",],
+ ["fruit"] = ["๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐ฅ", "๐ฅ", "๐ฅญ", "๐
",],
+ ["vegetable"] = ["๐ ", "๐
", "๐", "๐ฅ", "๐ฅ", "๐ฅ",],
+ ["watermelon"] = ["๐",],
+ ["strawberry"] = ["๐",],
};
[Command("describe"), TriggersTyping]
diff --git a/CompatBot/CompatBot.csproj b/CompatBot/CompatBot.csproj
index 695463c2..12b4f951 100644
--- a/CompatBot/CompatBot.csproj
+++ b/CompatBot/CompatBot.csproj
@@ -43,32 +43,32 @@
-
+
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
diff --git a/CompatBot/Config.cs b/CompatBot/Config.cs
index 8a11c16e..6654ed71 100644
--- a/CompatBot/Config.cs
+++ b/CompatBot/Config.cs
@@ -96,8 +96,8 @@ internal static class Config
internal static class AllowedMentions
{
- internal static readonly IMention[] UsersOnly = { UserMention.All };
- internal static readonly IMention[] Nothing = Array.Empty();
+ internal static readonly IMention[] UsersOnly = [UserMention.All];
+ internal static readonly IMention[] Nothing = [];
}
internal static string CurrentLogPath => Path.GetFullPath(Path.Combine(LogPath, "bot.log"));
diff --git a/CompatBot/Database/Migrations/BotDb/20190205174241_ChangeE3ToGenericEvent.cs b/CompatBot/Database/Migrations/BotDb/20190205174241_ChangeE3ToGenericEvent.cs
index bf56b056..9552cd40 100644
--- a/CompatBot/Database/Migrations/BotDb/20190205174241_ChangeE3ToGenericEvent.cs
+++ b/CompatBot/Database/Migrations/BotDb/20190205174241_ChangeE3ToGenericEvent.cs
@@ -26,7 +26,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
migrationBuilder.CreateIndex(
name: "event_schedule_year_event_name",
table: "event_schedule",
- columns: new[] { "year", "event_name" });
+ columns: ["year", "event_name"]);
migrationBuilder.Sql("INSERT INTO event_schedule SELECT id, year, start, end, name, 'E3' AS event_name FROM e3_schedule");
diff --git a/CompatBot/Database/Migrations/BotDb/20190301155219_PersistentStats.cs b/CompatBot/Database/Migrations/BotDb/20190301155219_PersistentStats.cs
index fd0699c3..679a3d0e 100644
--- a/CompatBot/Database/Migrations/BotDb/20190301155219_PersistentStats.cs
+++ b/CompatBot/Database/Migrations/BotDb/20190301155219_PersistentStats.cs
@@ -25,7 +25,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
migrationBuilder.CreateIndex(
name: "stats_category_key",
table: "stats",
- columns: new[] { "category", "key" },
+ columns: ["category", "key"],
unique: true);
}
diff --git a/CompatBot/Database/Migrations/BotDb/20191129183704_AddForcedNickname.cs b/CompatBot/Database/Migrations/BotDb/20191129183704_AddForcedNickname.cs
index 73b9b518..87935383 100644
--- a/CompatBot/Database/Migrations/BotDb/20191129183704_AddForcedNickname.cs
+++ b/CompatBot/Database/Migrations/BotDb/20191129183704_AddForcedNickname.cs
@@ -24,7 +24,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
migrationBuilder.CreateIndex(
name: "forced_nickname_guild_id_user_id",
table: "forced_nicknames",
- columns: new[] { "guild_id", "user_id" },
+ columns: ["guild_id", "user_id"],
unique: true);
}
diff --git a/CompatBot/Database/Migrations/BotDb/20220704163631_AddStatsBucketColumn.cs b/CompatBot/Database/Migrations/BotDb/20220704163631_AddStatsBucketColumn.cs
index 65d4e330..4c6aeab2 100644
--- a/CompatBot/Database/Migrations/BotDb/20220704163631_AddStatsBucketColumn.cs
+++ b/CompatBot/Database/Migrations/BotDb/20220704163631_AddStatsBucketColumn.cs
@@ -21,7 +21,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
migrationBuilder.CreateIndex(
name: "stats_category_bucket_key",
table: "stats",
- columns: new[] { "category", "bucket", "key" },
+ columns: ["category", "bucket", "key"],
unique: true);
}
@@ -38,7 +38,7 @@ protected override void Down(MigrationBuilder migrationBuilder)
migrationBuilder.CreateIndex(
name: "stats_category_key",
table: "stats",
- columns: new[] { "category", "key" },
+ columns: ["category", "key"],
unique: true);
}
}
diff --git a/CompatBot/Database/Providers/HwInfoProvider.cs b/CompatBot/Database/Providers/HwInfoProvider.cs
index 21998f92..8bd37ff7 100644
--- a/CompatBot/Database/Providers/HwInfoProvider.cs
+++ b/CompatBot/Database/Providers/HwInfoProvider.cs
@@ -50,9 +50,9 @@ public static async Task AddOrUpdateSystemAsync(DiscordClient client, DiscordMes
if (gpuStringParts[0].ToLower() is not ("nvidia" or "amd" or "ati" or "intel" or "apple"))
if (LogParserResult.IsNvidia(gpuString))
- gpuStringParts = new[] { "NVIDIA", gpuString };
+ gpuStringParts = ["NVIDIA", gpuString];
else if (LogParserResult.IsAmd(gpuString))
- gpuStringParts = new[] { "AMD", gpuString };
+ gpuStringParts = ["AMD", gpuString];
else
{
Config.Log.Warn($"Unknown GPU maker {gpuStringParts[0]}, plz fix");
diff --git a/CompatBot/Database/Providers/StatsStorage.cs b/CompatBot/Database/Providers/StatsStorage.cs
index 9766b09f..c6d0210c 100644
--- a/CompatBot/Database/Providers/StatsStorage.cs
+++ b/CompatBot/Database/Providers/StatsStorage.cs
@@ -20,11 +20,11 @@ internal static class StatsStorage
private static readonly SemaphoreSlim Barrier = new(1, 1);
private static readonly SemaphoreSlim BucketLock = new(1, 1);
private static readonly (string name, MemoryCache cache)[] AllCaches =
- {
+ [
(nameof(CmdStatCache), CmdStatCache),
(nameof(ExplainStatCache), ExplainStatCache),
(nameof(GameStatCache), GameStatCache),
- };
+ ];
private static ((int y, int m, int d, int h) Key, string Value) bucketPrefix = ((0, 0, 0, 0), "");
diff --git a/CompatBot/EventHandlers/BotReactionsHandler.cs b/CompatBot/EventHandlers/BotReactionsHandler.cs
index 64245ee8..8ec894a6 100644
--- a/CompatBot/EventHandlers/BotReactionsHandler.cs
+++ b/CompatBot/EventHandlers/BotReactionsHandler.cs
@@ -15,7 +15,7 @@
namespace CompatBot.EventHandlers
{
- internal static class BotReactionsHandler
+ internal static partial class BotReactionsHandler
{
private static readonly AhoCorasickDoubleArrayTrie ChillCheck = new(new[]
{
@@ -47,10 +47,10 @@ internal static class BotReactionsHandler
}.Select(DiscordEmoji.FromUnicode).ToArray();
private static readonly string[] SadMessages =
- {
+ [
"Okay (._.)", "As you wish", "My bad", "I only wanted to help", "Dobby will learn, master",
"Sorry...", "I'll try to be smarter next time", "Your wish is my command", "Done.",
- };
+ ];
private static readonly DiscordEmoji[] ThankYouReactions = new[]
{
@@ -63,15 +63,14 @@ internal static class BotReactionsHandler
}.Select(DiscordEmoji.FromUnicode).ToArray();
private static readonly string[] ThankYouMessages =
- {
+ [
"Aww", "I'm here to help", "Always a pleasure", "Thank you", "Good word is always appreciated",
"Glad I could help", "I try my best", "Blessed day", "It is officially a good day today", "I will remember you when the uprising starts",
- };
+ ];
+
- private static readonly Regex Paws = new(
- @"\b((?kot(to)?)|(?doggo|jarves))\b",
- RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture
- );
+ [GeneratedRegex(@"\b((?kot(to)?)|(?doggo|jarves))\b", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture)]
+ private static partial Regex Paws();
private static readonly Random Rng = new();
private static readonly object TheDoor = new();
@@ -127,7 +126,7 @@ public static async Task OnMessageCreated(DiscordClient c, MessageCreateEventArg
}
#endif
- if (!string.IsNullOrEmpty(args.Message.Content) && Paws.Matches(args.Message.Content) is MatchCollection mc)
+ if (!string.IsNullOrEmpty(args.Message.Content) && Paws().Matches(args.Message.Content) is MatchCollection mc)
{
await using var db = new BotDb();
var matchedGroups = (from m in mc
diff --git a/CompatBot/EventHandlers/DiscordInviteFilter.cs b/CompatBot/EventHandlers/DiscordInviteFilter.cs
index 2808d381..b75601f8 100644
--- a/CompatBot/EventHandlers/DiscordInviteFilter.cs
+++ b/CompatBot/EventHandlers/DiscordInviteFilter.cs
@@ -18,10 +18,14 @@
namespace CompatBot.EventHandlers;
-internal static class DiscordInviteFilter
+internal static partial class DiscordInviteFilter
{
- private const RegexOptions DefaultOptions = RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase | RegexOptions.Multiline;
- private static readonly Regex InviteLink = new(@"(https?://)?discord((((app)?\.com/invite|\.gg)/(?[a-z0-9\-]+))|(\.me/(?.*?))(\s|>|$))", DefaultOptions);
+ [GeneratedRegex(@"(https?://)?discord((((app)?\.com/invite|\.gg)/(?[a-z0-9\-]+))|(\.me/(?.*?))(\s|>|$))", RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase | RegexOptions.Multiline)]
+ private static partial Regex InviteLink();
+ [GeneratedRegex(@"name=""csrf-token"" content=""(?\w+)""")]
+ private static partial Regex CsrfTokenPattern();
+ [GeneratedRegex(@"name=""serverEid"" value=""(?\w+)""")]
+ private static partial Regex ServerEidPattern();
private static readonly MemoryCache InviteCodeCache = new(new MemoryCacheOptions{ExpirationScanFrequency = TimeSpan.FromHours(1)});
private static readonly TimeSpan CacheDuration = TimeSpan.FromHours(24);
@@ -189,8 +193,8 @@ where msg.CreationTimestamp > after
if (string.IsNullOrEmpty(message))
return (false, false, new(0));
- var inviteCodes = new HashSet(InviteLink.Matches(message).Select(m => m.Groups["invite_id"].Value).Where(s => !string.IsNullOrEmpty(s)));
- var discordMeLinks = InviteLink.Matches(message).Select(m => m.Groups["me_id"].Value).Distinct().Where(s => !string.IsNullOrEmpty(s)).ToList();
+ var inviteCodes = new HashSet(InviteLink().Matches(message).Select(m => m.Groups["invite_id"].Value).Where(s => !string.IsNullOrEmpty(s)));
+ var discordMeLinks = InviteLink().Matches(message).Select(m => m.Groups["me_id"].Value).Distinct().Where(s => !string.IsNullOrEmpty(s)).ToList();
var attemptedWorkaround = false;
if (author != null && InviteCodeCache.TryGetValue(author.Id, out HashSet? recentInvites) && recentInvites is not null)
{
@@ -232,8 +236,8 @@ where msg.CreationTimestamp > after
continue;
hasInvalidInvites = true;
- var csrfTokenMatch = Regex.Match(html, @"name=""csrf-token"" content=""(?\w+)""");
- var serverEidMatch = Regex.Match(html, @"name=""serverEid"" value=""(?\w+)""");
+ var csrfTokenMatch = CsrfTokenPattern().Match(html);
+ var serverEidMatch = ServerEidPattern().Match(html);
if (csrfTokenMatch.Success && serverEidMatch.Success)
{
using var postRequest = new HttpRequestMessage(HttpMethod.Post, "https://discord.me/server/join")
diff --git a/CompatBot/EventHandlers/GithubLinksHandler.cs b/CompatBot/EventHandlers/GithubLinksHandler.cs
index ff228619..f24e71e2 100644
--- a/CompatBot/EventHandlers/GithubLinksHandler.cs
+++ b/CompatBot/EventHandlers/GithubLinksHandler.cs
@@ -11,13 +11,17 @@
namespace CompatBot.EventHandlers;
-internal static class GithubLinksHandler
+internal static partial class GithubLinksHandler
{
- private const RegexOptions DefaultOptions = RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture;
- public static readonly Regex IssueMention = new(@"(?\b(issue|pr|pull[ \-]request|bug)\s*#?\s*(?\d+)|\B#(?1?\d{4})|(https?://)github.com/RPCS3/rpcs3/(issues|pull)/(?\d+)(#issuecomment-(?\d+))?)\b", DefaultOptions);
- public static readonly Regex CommitMention = new(@"(?(https?://)github.com/RPCS3/rpcs3/commit/(?[0-9a-f]+))\b", DefaultOptions);
- public static readonly Regex ImageMarkup = new(@"(?!\[(?[^\]]+)\]\((?\w+://[^\)]+)\))", DefaultOptions);
- private static readonly Regex IssueLink = new(@"github.com/RPCS3/rpcs3/issues/(?\d+)", DefaultOptions);
+ private const RegexOptions DefaultOptions = RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture;
+ [GeneratedRegex(@"(?\b(issue|pr|pull[ \-]request|bug)\s*#?\s*(?\d+)|\B#(?1?\d{4})|(https?://)github.com/RPCS3/rpcs3/(issues|pull)/(?\d+)(#issuecomment-(?\d+))?)\b", DefaultOptions)]
+ internal static partial Regex IssueMention();
+ [GeneratedRegex(@"(?(https?://)github.com/RPCS3/rpcs3/commit/(?[0-9a-f]+))\b", DefaultOptions)]
+ internal static partial Regex CommitMention();
+ [GeneratedRegex(@"(?!\[(?[^\]]+)\]\((?\w+://[^\)]+)\))", DefaultOptions)]
+ internal static partial Regex ImageMarkup();
+ [GeneratedRegex(@"github.com/RPCS3/rpcs3/issues/(?\d+)", DefaultOptions)]
+ internal static partial Regex IssueLink();
public static async Task OnMessageCreated(DiscordClient c, MessageCreateEventArgs args)
{
@@ -72,7 +76,7 @@ public static async Task OnMessageCreated(DiscordClient c, MessageCreateEventArg
public static List GetIssueIds(string input)
{
- return IssueMention.Matches(input)
+ return IssueMention().Matches(input)
.SelectMany(match => new[]
{
match.Groups["number"].Value,
@@ -86,13 +90,16 @@ public static List GetIssueIds(string input)
}
public static HashSet GetIssueIdsFromLinks(string input)
{
- return new(
- IssueLink.Matches(input)
+ return
+ [
+
+ ..IssueLink().Matches(input)
.Select(match =>
{
_ = int.TryParse(match.Groups["number"].Value, out var n);
return n;
})
- );
+
+ ];
}
}
\ No newline at end of file
diff --git a/CompatBot/EventHandlers/IsTheGamePlayableHandler.cs b/CompatBot/EventHandlers/IsTheGamePlayableHandler.cs
index 5429863d..eeb7432b 100644
--- a/CompatBot/EventHandlers/IsTheGamePlayableHandler.cs
+++ b/CompatBot/EventHandlers/IsTheGamePlayableHandler.cs
@@ -17,15 +17,15 @@
namespace CompatBot.EventHandlers;
-internal static class IsTheGamePlayableHandler
+internal static partial class IsTheGamePlayableHandler
{
- private const RegexOptions DefaultOptions = RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture;
- private static readonly Regex GameNameStatusMention1 = new(
- @"(\b((is|does|can I play|any(one|1) tr(y|ied)|how's|(wonder(ing)?|me|knows?) if)\s+)(?.+?)\s+((now|currently|at all|possibly|fully|(on (this|the) )emu(lator))\s+)?((it?s )?playable|work(s|ing)?|runs?|doing))\b" +
- @"|(\b(((can I|possible to) (play|run)|any(one|1) tr(y|ied)|compat[ai]bility (with|of))\s+)(?.+?)(\s+((now|currently|at all|possibly|fully)\s+)?((it?s )?playable|work(s|ing)?|on (it|this))\b|\?|$))" +
+ [GeneratedRegex(
+ @"(\b((is|does|can I play|any(one|1) tr(y|ied)|how's|(wonder(ing)?|me|knows?) if)\s+)(?.+?)\s+((now|currently|at all|possibly|fully|(on (this|the) )emu(lator))\s+)?((it?s )?playable|work(s|ing)?|runs?|doing))\b"+
+ @"|(\b(((can I|possible to) (play|run)|any(one|1) tr(y|ied)|compat[ai]bility (with|of))\s+)(?.+?)(\s+((now|currently|at all|possibly|fully)\s+)?((it?s )?playable|work(s|ing)?|on (it|this))\b|\?|$))"+
@"|(^(?.+?)\s+((is )?(playable|work(s|ing)?))\?)",
- DefaultOptions
- );
+ RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture
+ )]
+ private static partial Regex GameNameStatusMention();
private static readonly ConcurrentDictionary CooldownBuckets = new();
private static readonly TimeSpan CooldownThreshold = TimeSpan.FromSeconds(5);
private static readonly Client Client = new();
@@ -48,7 +48,7 @@ public static async Task OnMessageCreated(DiscordClient c, MessageCreateEventArg
return;
#endif
- var matches = GameNameStatusMention1.Matches(args.Message.Content);
+ var matches = GameNameStatusMention().Matches(args.Message.Content);
if (!matches.Any())
return;
@@ -65,7 +65,7 @@ public static async Task OnMessageCreated(DiscordClient c, MessageCreateEventArg
if (gameTitle.Length < 4)
return;
- if (ProductCodeLookup.ProductCode.IsMatch(args.Message.Content))
+ if (ProductCodeLookup.Pattern().IsMatch(args.Message.Content))
return;
var (_, info) = await LookupGameAsync(args.Channel, args.Message, gameTitle).ConfigureAwait(false);
diff --git a/CompatBot/EventHandlers/LogAsTextMonitor.cs b/CompatBot/EventHandlers/LogAsTextMonitor.cs
index 49c0e886..b1a87a92 100644
--- a/CompatBot/EventHandlers/LogAsTextMonitor.cs
+++ b/CompatBot/EventHandlers/LogAsTextMonitor.cs
@@ -10,9 +10,10 @@
namespace CompatBot.EventHandlers;
-internal static class LogAsTextMonitor
+internal static partial class LogAsTextMonitor
{
- private static readonly Regex LogLine = new(@"^[`""]?(ยท|(\w|!)) ({(rsx|PPU|SPU)|LDR:)|E LDR:", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
+ [GeneratedRegex(@"^[`""]?(ยท|(\w|!)) ({(rsx|PPU|SPU)|LDR:)|E LDR:", RegexOptions.IgnoreCase | RegexOptions.Multiline)]
+ private static partial Regex LogLine();
public static async Task OnMessageCreated(DiscordClient _, MessageCreateEventArgs args)
{
@@ -25,7 +26,7 @@ public static async Task OnMessageCreated(DiscordClient _, MessageCreateEventArg
if ((args.Message.Author as DiscordMember)?.Roles.Any() ?? false)
return;
- if (LogLine.IsMatch(args.Message.Content))
+ if (LogLine().IsMatch(args.Message.Content))
{
var brokenDump = false;
string msg = "";
diff --git a/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/GzipHandler.cs b/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/GzipHandler.cs
index 1f941bf9..1691dde8 100644
--- a/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/GzipHandler.cs
+++ b/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/GzipHandler.cs
@@ -10,7 +10,7 @@ namespace CompatBot.EventHandlers.LogParsing.ArchiveHandlers;
internal sealed class GzipHandler: IArchiveHandler
{
- private static readonly byte[] Header = { 0x1F, 0x8B, 0x08 };
+ private static readonly byte[] Header = [0x1F, 0x8B, 0x08];
public long LogSize { get; private set; }
public long SourcePosition { get; private set; }
diff --git a/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/RarHandler.cs b/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/RarHandler.cs
index ef95e249..a1d4eaeb 100644
--- a/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/RarHandler.cs
+++ b/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/RarHandler.cs
@@ -11,7 +11,7 @@ namespace CompatBot.EventHandlers.LogParsing.ArchiveHandlers;
internal sealed class RarHandler: IArchiveHandler
{
- private static readonly byte[] Header = {0x52, 0x61, 0x72, 0x21, 0x1A, 0x07};
+ private static readonly byte[] Header = [0x52, 0x61, 0x72, 0x21, 0x1A, 0x07]; // Rar!..
public long LogSize { get; private set; }
public long SourcePosition { get; private set; }
diff --git a/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/SevenZipHandler.cs b/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/SevenZipHandler.cs
index 56dbcea6..a1605c00 100644
--- a/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/SevenZipHandler.cs
+++ b/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/SevenZipHandler.cs
@@ -10,7 +10,7 @@ namespace CompatBot.EventHandlers.LogParsing.ArchiveHandlers;
internal sealed class SevenZipHandler: IArchiveHandler
{
- private static readonly byte[] Header = {0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C};
+ private static readonly byte[] Header = [0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C]; //7z....
public long LogSize { get; private set; }
public long SourcePosition { get; private set; }
diff --git a/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/ZipHandler.cs b/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/ZipHandler.cs
index 6cbca236..9501f7b2 100644
--- a/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/ZipHandler.cs
+++ b/CompatBot/EventHandlers/LogParsing/ArchiveHandlers/ZipHandler.cs
@@ -11,7 +11,7 @@ namespace CompatBot.EventHandlers.LogParsing.ArchiveHandlers;
internal sealed class ZipHandler: IArchiveHandler
{
- private static readonly byte[] Header = { 0x50, 0x4B, 0x03, 0x04 };
+ private static readonly byte[] Header = [0x50, 0x4B, 0x03, 0x04]; //PK..
public long LogSize { get; private set; }
public long SourcePosition { get; private set; }
diff --git a/CompatBot/EventHandlers/LogParsing/LogParser.LogSections.cs b/CompatBot/EventHandlers/LogParsing/LogParser.LogSections.cs
index cc1d2114..bd669eed 100644
--- a/CompatBot/EventHandlers/LogParsing/LogParser.LogSections.cs
+++ b/CompatBot/EventHandlers/LogParsing/LogParser.LogSections.cs
@@ -1,19 +1,14 @@
๏ปฟusing System.Collections.Generic;
-using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CompatBot.Database;
using CompatBot.Database.Providers;
using CompatBot.EventHandlers.LogParsing.POCOs;
using CompatBot.Utils;
-using CompatBot.Utils.ResultFormatters;
namespace CompatBot.EventHandlers.LogParsing;
internal partial class LogParser
{
- private const RegexOptions DefaultOptions = RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.ExplicitCapture;
- private const RegexOptions DefaultSingleLineOptions = RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture;
-
/*
* Extractors are defined in terms of trigger-extractor
*
@@ -23,228 +18,232 @@ internal partial class LogParser
* If any data was captured, it will be stored in the current collection of items with the key of the explicit capture group of regex
*
*/
- private static readonly List LogSections = new()
- {
+ private static readonly List LogSections =
+ [
new()
{
Extractors = new()
{
- ["RPCS3 v"] = new(@"(^|.+\d:\d\d:\d\d\.\d{6})\s*(?RPCS3 [^\xC2\xB7]+?)\r?(\nยท|$)", DefaultSingleLineOptions),
- ["0:00:00.0"] = new(@"(?ยท).+\r?$", DefaultOptions),
- ["Operating system:"] = LogParserResult.OsInfoInLog,
- ["Current Time:"] = new(@"Current Time: (?.+)\r?$", DefaultOptions),
- ["Installation ID:"] = new(@"Installation ID: (?.+)\r?$", DefaultOptions),
- ["Physical device in"] = new(@"Physical device ini?tialized\. GPU=(?.+), driver=(?-?\d+)\r?$", DefaultOptions),
- ["Found vulkan-compatible GPU:"] = new(@"Found [Vv]ulkan-compatible GPU: (?'(?.+)' running.+)\r?$", DefaultOptions),
- ["Finished reading database from file:"] = new(@"Finished reading database from file: (?.*compat_database.dat).*\r?$", DefaultOptions),
- ["Database file not found:"] = new(@"Database file not found: (?.*compat_database.dat).*\r?$", DefaultOptions),
- ["Successfully installed PS3 firmware"] = new(@"(?Successfully installed PS3 firmware) version (?\d+\.\d+).*\r?$", DefaultOptions),
- ["Firmware version:"] = new(@"Firmware version: (?\d+\.\d+).*\r?$", DefaultOptions),
- ["Title:"] = new(@"(?:LDR|SYS): Title: (?.*)?\r?$", DefaultOptions),
- ["Serial:"] = new(@"Serial: (?[A-z]{4}\d{5})\r?$", DefaultOptions),
- ["Category:"] = new(@"Category: (?.*)?\r?$", DefaultOptions),
- ["LDR: Version:"] = new(@"Version: (?\S+) / (?\S+).*?\r?$", DefaultOptions),
- ["SYS: Version:"] = new(@"Version: (APP_VER=)?(?\S+) (/ |VERSION=)(?\S+).*?\r?$", DefaultOptions),
- ["LDR: Cache"] = new(@"Cache: ((?\w:/)|(?/[^/])).*?\r?$", DefaultOptions),
- ["SYS: Cache"] = new(@"Cache: ((?\w:/)|(?/[^/])).*?\r?$", DefaultOptions),
- ["LDR: Path"] = new(@"Path: ((?\w:/)|(?/[^/])).*?\r?$", DefaultOptions),
- ["SYS: Path"] = new(@"Path: ((?\w:/)|(?/[^/])).*?\r?$", DefaultOptions),
- ["LDR: Path:"] = new(@"Path: (?.*(?/dev_hdd0/game/(?[^/\r\n]+)).*|.*)\r?$", DefaultOptions),
- ["SYS: Path:"] = new(@"Path: (?.*(?/dev_hdd0/game/(?[^/\r\n]+)).*|.*)\r?$", DefaultOptions),
- ["custom config:"] = new(@"custom config: (?.*?)\r?$", DefaultOptions),
- ["patch_log: Failed to load patch file"] = new(@"patch_log: Failed to load patch file (?\S*)\r?\n.* line (?\d+), column (?\d+): (?.*?)$", DefaultOptions),
+ ["RPCS3 v"] = Rpcs3LogHeader(),
+ ["0:00:00.0"] = FirstLineWithDot(),
+ ["Operating system:"] = OsInfo(),
+ ["Current Time:"] = CurrentTime(),
+ ["Installation ID:"] = InstallationId(),
+ ["Physical device in"] = PhysicalDeviceName(),
+ ["Found vulkan-compatible GPU:"] = VulkanDeviceName(),
+ ["Finished reading database from file:"] = CompatDbFoundPath(),
+ ["Database file not found:"] = CompatDbNotFoundPath(),
+ ["Successfully installed PS3 firmware"] = FwInstallMessage(),
+ ["Firmware version:"] = FwVersion(),
+ ["Title:"] = GameTitle(),
+ ["Serial:"] = GameSerial(),
+ ["Category:"] = GameCategory(),
+ ["LDR: Version:"] = DiscVersionLdr(),
+ ["SYS: Version:"] = DiscVersionSys(),
+ ["LDR: Cache"] = CachePathLdr(),
+ ["SYS: Cache"] = CachePathSys(),
+ ["LDR: Path"] = BootPathLdr(),
+ ["SYS: Path"] = BootPathSys(),
+ ["LDR: Path:"] = BootPathDigitalLdr(),
+ ["SYS: Path:"] = BootPathDigitalSys(),
+ ["custom config:"] = CustomConfigPath(),
+ ["patch_log: Failed to load patch file"] = FailedPatchPath(),
},
- EndTrigger = new[] {"Used configuration:"},
+ EndTrigger = ["Used configuration:"],
},
+
new()
{
Extractors = new()
{
- ["PPU Decoder:"] = new(@"PPU Decoder: (?.*?)\r?$", DefaultOptions),
- ["PPU Threads:"] = new(@"PPU Threads: (?.*?)\r?$", DefaultOptions),
- ["Use LLVM CPU:"] = new("Use LLVM CPU: \\\"?(?.*?)\\\"?\r?$", DefaultOptions),
- ["thread scheduler"] = new(@"[Ss]cheduler( Mode)?: (?.*?)\r?$", DefaultOptions),
- ["SPU Decoder:"] = new(@"SPU Decoder: (?.*?)\r?$", DefaultOptions),
- ["secondary cores:"] = new(@"secondary cores: (?.*?)\r?$", DefaultOptions),
- //["priority:"] = new(@"priority: (?.*?)\r?$", DefaultOptions),
- ["SPU Threads:"] = new(@"SPU Threads: (?.*?)\r?$", DefaultOptions),
- ["SPU delay penalty:"] = new(@"SPU delay penalty: (?.*?)\r?$", DefaultOptions),
- ["SPU loop detection:"] = new(@"SPU loop detection: (?.*?)\r?$", DefaultOptions),
- ["Max SPURS Threads:"] = new(@"Max SPURS Threads: (?\d*?)\r?$", DefaultOptions),
- ["SPU Block Size:"] = new(@"SPU Block Size: (?.*?)\r?$", DefaultOptions),
- ["Enable TSX:"] = new(@"Enable TSX: (?.*?)\r?$", DefaultOptions),
- ["Accurate xfloat:"] = new(@"Accurate xfloat: (?.*?)\r?$", DefaultOptions),
- ["Approximate xfloat:"] = new(@"Approximate xfloat: (?.*?)\r?$", DefaultOptions),
- ["Relaxed xfloat:"] = new(@"Relaxed xfloat: (?.*?)\r?$", DefaultOptions),
- ["XFloat Accuracy:"] = new(@"XFloat Accuracy: (?.*?)\r?$", DefaultOptions),
- ["Accurate GETLLAR:"] = new(@"Accurate GETLLAR: (?.*?)\r?$", DefaultOptions),
- ["Accurate PUTLLUC:"] = new(@"Accurate PUTLLUC: (?.*?)\r?$", DefaultOptions),
- ["Accurate RSX reservation access:"] = new(@"Accurate RSX reservation access: (?.*?)\r?$", DefaultOptions),
- ["RSX FIFO Accuracy:"] = new(@"RSX FIFO Accuracy: (?.*?)\r?$", DefaultOptions),
- ["Debug Console Mode:"] = new(@"Debug Console Mode: (?.*?)\r?$", DefaultOptions),
- ["Lib Loader:"] = new(@"[Ll]oader: (?.*?)\r?$", DefaultOptions),
- ["Hook static functions:"] = new(@"Hook static functions: (?.*?)\r?$", DefaultOptions),
- ["Load libraries:"] = new(@"libraries:\r?\n(?(.*?(- .*?|\[\])\r?\n)+)", DefaultOptions),
- ["Libraries Control:"] = new(@"Libraries Control:\r?\n(?(.*?(- .*?|\[\])\r?\n)+)", DefaultOptions),
- ["HLE lwmutex:"] = new(@"HLE lwmutex: (?.*?)\r?$", DefaultOptions),
- ["Clocks scale:"] = new(@"Clocks scale: (?.*?)\r?$", DefaultOptions),
- ["Max CPU Preempt Count:"] = new(@"Max CPU Preempt Count: (?.*?)\r?$", DefaultOptions),
- ["Sleep Timers Accuracy:"] = new(@"Sleep Timers Accuracy: (?.*?)\r?$", DefaultOptions),
+ ["PPU Decoder:"] = PpuDecoderType(),
+ ["PPU Threads:"] = PpuThreadCount(),
+ ["Use LLVM CPU:"] = LlvmCpuArch(),
+ ["thread scheduler"] = ThreadSchedulerMode(),
+ ["SPU Decoder:"] = SpuDecoderType(),
+ ["secondary cores:"] = SecondaryCores(),
+ //["priority:"] = LowerThreadPriority(),
+ ["SPU Threads:"] = SpuThreadCount(),
+ ["SPU delay penalty:"] = SpuDelayPenalty(),
+ ["SPU loop detection:"] = SpuLoopDetection(),
+ ["Max SPURS Threads:"] = SpursThreadCount(),
+ ["SPU Block Size:"] = SpuBlockSize(),
+ ["Enable TSX:"] = TsxMode(),
+ ["Accurate xfloat:"] = AccurateXfloat(),
+ ["Approximate xfloat:"] = ApproximateXfloat(),
+ ["Relaxed xfloat:"] = RelaxedXfloat(),
+ ["XFloat Accuracy:"] = XfloatMode(),
+ ["Accurate GETLLAR:"] = GetLlarMode(),
+ ["Accurate PUTLLUC:"] = PutLlucMode(),
+ ["Accurate RSX reservation access:"] = RsxReservationAccessMode(),
+ ["RSX FIFO Accuracy:"] = RsxFifoMode(),
+ ["Debug Console Mode:"] = DebugConsoleMode(),
+ ["Lib Loader:"] = LibLoaderMode(),
+ ["Hook static functions:"] = HookStaticFunctions(),
+ ["Load libraries:"] = LoadLibrariesList(),
+ ["Libraries Control:"] = LibrariesControlList(),
+ ["HLE lwmutex:"] = HleLwmutex(),
+ ["Clocks scale:"] = ClockScale(),
+ ["Max CPU Preempt Count:"] = CpuPreemptCount(),
+ ["Sleep Timers Accuracy:"] = SleepTimersMode(),
},
- EndTrigger = new[] {"VFS:"},
+ EndTrigger = ["VFS:"],
},
+
new()
{
Extractors = new()
{
- ["Enable /host_root/:"] = new(@"Enable /host_root/: (?.*?)\r?$", DefaultOptions),
+ ["Enable /host_root/:"] = EnableHostRoot(),
},
- EndTrigger = new[] {"Video:"},
+ EndTrigger = ["Video:"],
},
+
new()
{
Extractors = new()
{
- ["Renderer:"] = new("Renderer: (?.*?)\r?$", DefaultOptions),
- ["Resolution:"] = new("Resolution: (?.*?)\r?$", DefaultOptions),
- ["Aspect ratio:"] = new("Aspect ratio: (?.*?)\r?$", DefaultOptions),
- ["Frame limit:"] = new("Frame limit: (?.*?)\r?$", DefaultOptions),
- ["MSAA:"] = new("MSAA: (?.*?)\r?$", DefaultOptions),
- ["Write Color Buffers:"] = new("Write Color Buffers: (?.*?)\r?$", DefaultOptions),
- ["Write Depth Buffer:"] = new("Write Depth Buffer: (?.*?)\r?$", DefaultOptions),
- ["Read Color Buffers:"] = new("Read Color Buffers: (?.*?)\r?$", DefaultOptions),
- ["Read Depth Buffer:"] = new("Read Depth Buffer: (?.*?)\r?$", DefaultOptions),
- ["VSync:"] = new("VSync: (?.*?)\r?$", DefaultOptions),
- ["GPU texture scaling:"] = new("Use GPU texture scaling: (?.*?)\r?$", DefaultOptions),
- ["Stretch To Display Area:"] = new("Stretch To Display Area: (?.*?)\r?$", DefaultOptions),
- ["Strict Rendering Mode:"] = new("Strict Rendering Mode: (?.*?)\r?$", DefaultOptions),
- ["Occlusion Queries:"] = new("Occlusion Queries: (?.*?)\r?$", DefaultOptions),
- ["Vertex Cache:"] = new("Disable Vertex Cache: (?.*?)\r?$", DefaultOptions),
- ["Frame Skip:"] = new("Enable Frame Skip: (?.*?)\r?$", DefaultOptions),
- ["Blit:"] = new("Blit: (?.*?)\r?$", DefaultOptions),
- ["Disable Asynchronous Shader Compiler:"] = new("Disable Asynchronous Shader Compiler: (?.*?)\r?$", DefaultOptions),
- ["Shader Mode:"] = new("Shader Mode: (?.*?)\r?$", DefaultOptions),
- ["Disable native float16 support:"] = new("Disable native float16 support: (?.*?)\r?$", DefaultOptions),
- ["Multithreaded RSX:"] = new("Multithreaded RSX: (?.*?)\r?$", DefaultOptions),
- ["Relaxed ZCULL Sync:"] = new("Relaxed ZCULL Sync: (?.*?)\r?$", DefaultOptions),
- ["Resolution Scale:"] = new("Resolution Scale: (?.*?)\r?$", DefaultOptions),
- ["Anisotropic Filter"] = new("Anisotropic Filter Override: (?.*?)\r?$", DefaultOptions),
- ["Scalable Dimension:"] = new("Minimum Scalable Dimension: (?.*?)\r?$", DefaultOptions),
- ["Driver Recovery Timeout:"] = new("Driver Recovery Timeout: (?.*?)\r?$", DefaultOptions),
- ["Driver Wake-Up Delay:"] = new("Driver Wake-Up Delay: (?.*?)\r?$", DefaultOptions),
- ["Vblank Rate:"] = new("Vblank Rate: (?.*?)\r?$", DefaultOptions),
- ["12:"] = new(@"(D3D12|DirectX 12):\s*\r?\n\s*Adapter: (?.*?)\r?$", DefaultOptions),
- ["Vulkan:"] = new(@"Vulkan:\s*\r?\n\s*Adapter: (?.*?)\r?$", DefaultOptions),
- ["Force FIFO present mode:"] = new(@"Force FIFO present mode: (?.*?)\r?$", DefaultOptions),
- ["Asynchronous Texture Streaming"] = new(@"Asynchronous Texture Streaming( 2)?: (?.*?)\r?$", DefaultOptions),
- ["Asynchronous Queue Scheduler:"] = new(@"Asynchronous Queue Scheduler: (?.*?)\r?$", DefaultOptions),
+ ["Renderer:"] = RendererBackend(),
+ ["Resolution:"] = ResolutionMode(),
+ ["Aspect ratio:"] = AspectRatioMode(),
+ ["Frame limit:"] = FrameLimit(),
+ ["MSAA:"] = MsaaMode(),
+ ["Write Color Buffers:"] = Wcb(),
+ ["Write Depth Buffer:"] = Wdb(),
+ ["Read Color Buffers:"] = Rcb(),
+ ["Read Depth Buffer:"] = Rdb(),
+ ["VSync:"] = VsyncMode(),
+ ["GPU texture scaling:"] = GpuTextureScaling(),
+ ["Stretch To Display Area:"] = StretchToDisplay(),
+ ["Strict Rendering Mode:"] = StrictRendering(),
+ ["Occlusion Queries:"] = OcclusionQueriesMode(),
+ ["Vertex Cache:"] = VertexCache(),
+ ["Frame Skip:"] = FrameSkip(),
+ ["Blit:"] = BlitMode(),
+ ["Disable Asynchronous Shader Compiler:"] = DisableAsyncShaders(),
+ ["Shader Mode:"] = ShaderMode(),
+ ["Disable native float16 support:"] = DisableNativeF16(),
+ ["Multithreaded RSX:"] = RsxMultithreadMode(),
+ ["Relaxed ZCULL Sync:"] = RelaxedZcull(),
+ ["Resolution Scale:"] = ResolutionScaling(),
+ ["Anisotropic Filter"] = AnisoFilter(),
+ ["Scalable Dimension:"] = ScalableDimensions(),
+ ["Driver Recovery Timeout:"] = DriverRecoveryTimeout(),
+ ["Driver Wake-Up Delay:"] = DriverWakeupDelay(),
+ ["Vblank Rate:"] = VblankRate(),
+ ["12:"] = SelectedD3d12Device(),
+ ["Vulkan:"] = SelectedVulkanDevice(),
+ ["Force FIFO present mode:"] = FifoPresentMode(),
+ ["Asynchronous Texture Streaming"] = AsyncTextureStreaming(),
+ ["Asynchronous Queue Scheduler:"] = AsyncQueueScheduler(),
},
- EndTrigger = new[] {"Audio:"},
+ EndTrigger = ["Audio:"],
},
+
new() // Audio, Input/Output, System, Net, Miscellaneous
{
Extractors = new()
{
- ["Renderer:"] = new("Renderer: (?.*?)\r?$", DefaultOptions),
- ["Downmix to Stereo:"] = new("Downmix to Stereo: (?.*?)\r?$", DefaultOptions),
- ["Master Volume:"] = new("Master Volume: (?.*?)\r?$", DefaultOptions),
- ["Enable Buffering:"] = new("Enable Buffering: (?.*?)\r?$", DefaultOptions),
- ["Desired Audio Buffer Duration:"] = new("Desired Audio Buffer Duration: (?.*?)\r?$", DefaultOptions),
- ["Enable Time Stretching:"] = new("Enable Time Stretching: (?.*?)\r?$", DefaultOptions),
+ ["Renderer:"] = AudioBackend(),
+ ["Downmix to Stereo:"] = DownmixToStereo(),
+ ["Master Volume:"] = MasterVolume(),
+ ["Enable Buffering:"] = AudioBuffering(),
+ ["Desired Audio Buffer Duration:"] = AudioBufferLength(),
+ ["Enable Time Stretching:"] = AudioTimeStretching(),
- ["Pad:"] = new("Pad: (?.*?)\r?$", DefaultOptions),
+ ["Pad:"] = GamepadType(),
- ["Automatically start games after boot:"] = new("Automatically start games after boot: (?.*?)\r?$", DefaultOptions),
- ["Always start after boot:"] = new("Always start after boot: (?.*?)\r?$", DefaultOptions),
- ["Use native user interface:"] = new("Use native user interface: (?.*?)\r?$", DefaultOptions),
- ["Silence All Logs:"] = new("Silence All Logs: (?.*?)\r?$", DefaultOptions),
+ ["Automatically start games after boot:"] = AutoStartAfterBoot(),
+ ["Always start after boot:"] = AlwaysStartAfterBoot(),
+ ["Use native user interface:"] = NativeUIMode(),
+ ["Silence All Logs:"] = SilenceAllLogs(),
},
- EndTrigger = new[] {"Log:"},
+ EndTrigger = ["Log:"],
},
+
new()
{
Extractors = new()
{
- ["Log:"] = new(@"Log:\s*\r?\n?\s*(\{(?.*?)\}|(?(\s+\w+\:\s*\w+\r?\n)+))\r?$", DefaultOptions),
+ ["Log:"] = LogChannelList(),
},
- EndTrigger = new[] {"ยท"},
+ EndTrigger = ["ยท"],
OnSectionEnd = MarkAsComplete,
},
+
new()
{
Extractors = new()
{
- ["LDR: Game:"] = new(@"Game: (?.*(?/dev_hdd0/game/(?[^/\r\n]+)).*|.*)\r?$", DefaultOptions),
- ["LDR: Disc"] = new(@"Disc( path)?: (?.*(?/dev_hdd0/game/(?[^/\r\n]+)).*|.*)\r?$", DefaultOptions),
- ["LDR: Path:"] = new(@"Path: (?.*(?/dev_hdd0/game/(?[^/\r\n]+)).*|.*)\r?$", DefaultOptions),
- ["LDR: Boot path:"] = new(@"Boot path: (?.*(?/dev_hdd0/game/(?[^/\r\n]+)).*|.*)\r?$", DefaultOptions),
- ["SYS: Game:"] = new(@"Game: (?.*(?/dev_hdd0/game/(?[^/\r\n]+)).*|.*)\r?$", DefaultOptions),
- ["SYS: Path:"] = new(@"Path: (?.*(?/dev_hdd0/game/(?[^/\r\n]+)).*|.*)\r?$", DefaultOptions),
- ["SYS: Boot path:"] = new(@"Boot path: (?.*(?/dev_hdd0/game/(?[^/\r\n]+)).*|.*)\r?$", DefaultOptions),
- ["Elf path:"] = new(@"Elf path: (?/host_root/)?(?(?/dev_hdd0/game/(?[^/\r\n]+)/USRDIR/EBOOT\.BIN|.*?))\r?$", DefaultOptions),
- ["VFS: Mounted path \"/dev_bdvd\""] = new(@"Mounted path ""/dev_bdvd"" to ""(?[^""]+)""", DefaultOptions),
- ["Invalid or unsupported file format:"] = new(@"Invalid or unsupported file format: (?.*?)\r?$", DefaultOptions),
- ["SELF:"] = new(@"(?Failed to decrypt)? SELF: (?Failed to (decrypt|load SELF))?.*\r?$", DefaultOptions),
- ["SYS: Version:"] = new(@"Version: (APP_VER=)?(?\S+) (/ |VERSION=)(?\S+).*?\r?$", DefaultOptions),
- ["sceNp: npDrmIsAvailable(): Failed to verify"] = new(@"Failed to verify (?(sce|npd)) file.*\r?$", DefaultOptions),
- ["{rsx::thread} RSX: 4"] = new(@"RSX:(\d|\.|\s|\w|-)* (?(\d+\.)*\d+)\r?\n[^\n]*?" +
- @"RSX: [^\n]+\r?\n[^\n]*?" +
- @"RSX: (?.*?)\r?\n[^\n]*?" +
- @"RSX: Supported texel buffer size", DefaultOptions),
- ["GL RENDERER:"] = new(@"GL RENDERER: (?.*?)\r?$", DefaultOptions),
- ["GL VERSION:"] = new(@"GL VERSION: (?(\d|\.)+)(\d|\.|\s|\w|-)*?( (?(\d+\.)*\d+))?\r?$", DefaultOptions),
- ["GLSL VERSION:"] = new(@"GLSL VERSION: (?(\d|\.)+).*?\r?$", DefaultOptions),
- ["texel buffer size reported:"] = new(@"RSX: Supported texel buffer size reported: (?\d*?) bytes", DefaultOptions),
- ["Physical device in"] = new(@"Physical device ini?tialized\. GPU=(?.+), driver=(?-?\d+)\r?$", DefaultOptions),
- ["Found vulkan-compatible GPU:"] = new(@"Found [Vv]ulkan-compatible GPU: (?.+)\r?$", DefaultOptions),
- ["Renderer initialized on device"] = new(@"Renderer initialized on device '(?.+)'\r?$", DefaultOptions),
- ["RSX: Failed to compile shader"] = new(@"RSX: Failed to compile shader: ERROR: (?.+?)\r?$", DefaultOptions),
- ["RSX: Compilation failed"] = new(@"RSX: Compilation failed: ERROR: (?.+?)\r?$", DefaultOptions),
- ["RSX: Linkage failed"] = new(@"RSX: Linkage failed: (?.+?)\r?$", DefaultOptions),
- ["RSX: Unsupported device"] = new(@"RSX: Unsupported device: (?.+)\..+?\r?$", DefaultOptions),
- ["RSX: Your GPU does not support"] = new(@"RSX: Your GPU does not support (?.+)\..+?\r?$", DefaultOptions),
- ["RSX: GPU/driver lacks support"] = new(@"RSX: GPU/driver lacks support for (?.+)\..+?\r?$", DefaultOptions),
- ["RSX: Swapchain:"] = new(@"RSX: Swapchain: present mode (?\d+?) in use.+?\r?$", DefaultOptions),
- ["F "] = new(@"F \d+:\d+:\d+\.\d+ (({(?[^}]+)} )?(\w+:\s*(Thread terminated due to fatal error: )?|(\w+:\s*)?(class [^\r\n]+ thrown: ))\r?\n?)(?.*?)(\r?\n)(\r?\n|ยท|$)", DefaultSingleLineOptions),
- ["Failed to load RAP file:"] = new(@"Failed to load RAP file: (?.*?\.rap).*\r?$", DefaultOptions),
- ["Rap file not found:"] = new(@"Rap file not found: โ?(?.*?\.rap)โ?\r?$", DefaultOptions),
- ["Pad handler expected but none initialized"] = new(@"(?Pad handler expected but none initialized).*?\r?$", DefaultOptions),
- ["Failed to bind device"] = new(@"Failed to bind device (?.+) to handler (?.+).*\r?$", DefaultOptions),
- ["Input:"] = new(@"Input: (?.*?) device .+ connected\r?$", DefaultOptions),
- ["XAudio2Thread"] = new(@"XAudio2Thread\s*: (?.+failed\s*\((?0x.+)\).*)\r?$", DefaultOptions),
- ["cellAudio Thread"] = new(@"XAudio2Backend\s*: (?.+failed\s*\((?0x.+)\).*)\r?$", DefaultOptions),
- ["using a Null renderer instead"] = new(@"Audio renderer (?.+) could not be initialized\r?$", DefaultOptions),
- ["PPU executable hash:"] = new(@"PPU executable hash: PPU-(?\w+( \(<-\s*\d+\))?).*?\r?$", DefaultOptions),
- ["OVL executable hash:"] = new(@"OVL executable hash: OVL-(?\w+( \(<-\s*\d+\))?).*?\r?$", DefaultOptions),
- ["SPU executable hash:"] = new(@"SPU executable hash: SPU-(?\w+( \(<-\s*\d+\))?).*?\r?$", DefaultOptions),
- ["PRX library hash:"] = new(@"PRX library hash: PRX-(?\w+-\d+( \(<-\s*\d+\))?).*?\r?$", DefaultOptions),
- ["OVL hash of"] = new(@"OVL hash of (\w|[\.\[\]])+: OVL-(?\w+( \(<-\s*\d+\))?).*?\r?$", DefaultOptions),
- ["PRX hash of"] = new(@"PRX hash of (\w|[\.\[\]])+: PRX-(?\w+-\d+( \(<-\s*\d+\))?).*?\r?$", DefaultOptions),
- [": Applied patch"] = new(@"Applied patch \(hash='(?:\w{3}-\w+(-\d+)?)', description='(?.+?)', author='(?:.+?)', patch_version='(?:.+?)', file_version='(?:.+?)'\) \(<- (?:[1-9]\d*)\).*\r?$", DefaultOptions),
- ["Loaded SPU image:"] = new(@"Loaded SPU image: SPU-(?\w+ \(<-\s*\d+\)).*?\r?$", DefaultOptions),
- ["'sys_fs_stat' failed"] = new(@"'sys_fs_stat' failed (?!with 0x8001002c).+โ(/dev_bdvd/(?.+)|/dev_hdd0/game/NP\w+/(?.+))โ.*?\r?$", DefaultOptions),
- ["'sys_fs_open' failed"] = new(@"'sys_fs_open' failed (?!with 0x8001002c).+โ(/dev_bdvd/(?.+)|/dev_hdd0/game/NP\w+/(?.+))โ.*?\r?$", DefaultOptions),
- ["'sys_fs_opendir' failed"] = new(@"'sys_fs_opendir' failed .+โ/dev_bdvd/(?.+)โ.*?\r?$", DefaultOptions),
- ["EDAT: "] = new(@"EDAT: Block at offset (?0x[0-9a-f]+) has invalid hash!.*?\r?$", DefaultOptions),
- ["PS3 firmware is not installed"] = new(@"(?PS3 firmware is not installed.+)\r?$", DefaultOptions),
- ["do you have the PS3 firmware installed"] = new(@"(?do you have the PS3 firmware installed.*)\r?$", DefaultOptions),
- ["Unimplemented syscall"] = new(@"U \d+:\d+:\d+\.\d+ ({(?.+?)} )?.*Unimplemented syscall (?