Skip to content

Commit

Permalink
Some performance and code optimizations (#955)
Browse files Browse the repository at this point in the history
* upgrade deps, remove wrong ppu hashes

* upgrade compiler packages

will require container pull after build

* replace Regex with compiler-generated versions

* use new collection initialization syntax

* configure global defaults for regex

* bump min amd driver version

fixes #950

* add macos version check

fixes #948

* fix #954 (!sudo log date)
  • Loading branch information
13xforever authored May 18, 2024
1 parent ad21597 commit 72dbc40
Show file tree
Hide file tree
Showing 83 changed files with 1,058 additions and 640 deletions.
2 changes: 1 addition & 1 deletion Clients/CirrusCiClient/CirrusCiClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="StrawberryShake.Server" Version="13.8.1" />
<PackageReference Include="StrawberryShake.Server" Version="13.9.4" />
</ItemGroup>
</Project>
10 changes: 5 additions & 5 deletions Clients/CompatApiClient/ApiConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> ResultAmount = new(){25, 50, 100, 200};
public static readonly List<int> ResultAmount = [25, 50, 100, 200];

public static readonly Dictionary<char, string[]> Directions = new()
{
{'a', new []{"a", "asc", "ascending"}},
{'d', new []{"d", "desc", "descending"} },
{'a', ["a", "asc", "ascending"] },
{'d', ["d", "desc", "descending"] },
};

public static readonly Dictionary<string, int> Statuses = new()
Expand All @@ -58,8 +58,8 @@ public static class ApiConfig

public static readonly Dictionary<char, string[]> 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<string, char> ReverseDirections;
Expand Down
2 changes: 1 addition & 1 deletion Clients/CompatApiClient/CompatApiClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.0" />
<PackageReference Include="NLog" Version="5.2.8" />
<PackageReference Include="NLog" Version="5.3.2" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class CompressionMessageHandler : DelegatingHandler
{
public ICollection<ICompressor> 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;
Expand Down
2 changes: 1 addition & 1 deletion Clients/GithubClient/GithubClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Octokit" Version="9.1.2" />
<PackageReference Include="Octokit" Version="11.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CompatApiClient\CompatApiClient.csproj" />
Expand Down
1 change: 0 additions & 1 deletion Clients/IrdLibraryClient/IrdClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public class IrdClient

private readonly HttpClient client;
private readonly JsonSerializerOptions jsonOptions;
private static readonly Regex IrdFilename = new(@"ird/(?<filename>\w{4}\d{5}-[A-F0-9]+\.ird)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase);

public IrdClient()
{
Expand Down
2 changes: 1 addition & 1 deletion Clients/IrdLibraryClient/IrdLibraryClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DiscUtils.OpticalDisk" Version="0.16.13" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.59" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.61" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.0" />
<PackageReference Include="System.IO.Hashing" Version="8.0.0" />
</ItemGroup>
Expand Down
7 changes: 4 additions & 3 deletions Clients/MediafireClient/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@

namespace MediafireClient;

public sealed class Client
public sealed partial class Client
{
private readonly HttpClient client;
private readonly JsonSerializerOptions jsonOptions;

//var optSecurityToken = "1605819132.376f3d84695f46daa7b69ee67fbc5edb0a00843a8b2d5ac7d3d1b1ad8a4212b0";
//private static readonly Regex SecurityTokenRegex = new(@"(var\s+optSecurityToken|name=""security"" value)\s*=\s*""(?<security_token>.+)""", 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*""(?<direct_link>https?://download\d+\.mediafire\.com/.+)""");
[GeneratedRegex(@"(var\s+optDirectURL|href)\s*=\s*""(?<direct_link>https?://download\d+\.mediafire\.com/.+)""")]
private static partial Regex DirectUrlRegex();

public Client()
{
Expand Down Expand Up @@ -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);
}
Expand Down
28 changes: 16 additions & 12 deletions Clients/PsnClient/PsnClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,35 @@

namespace PsnClient;

public class Client
public partial class Client
{
private readonly HttpClient client;
private readonly JsonSerializerOptions dashedJson;
private readonly JsonSerializerOptions snakeJson;
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(@"(?<id>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(@"(?<id>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=(?<dest>\d+);ImageVersion=(?<image>[0-9a-f]+);SystemSoftwareVersion=(?<version>\d+\.\d+);CDN=(?<url>http[^;]+);CDN_Timeout=(?<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()
{
Expand Down Expand Up @@ -117,15 +121,15 @@ public Client()
tries++;
}
if (response.StatusCode == HttpStatusCode.Redirect)
return new(0);
return [];
}

using (response)
try
{
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<string>();
foreach (Match m in matches)
if (m.Groups["id"].Value is {Length: >0} id)
Expand Down Expand Up @@ -345,7 +349,7 @@ public async Task<List<FirmwareInfo>> 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();
Expand Down Expand Up @@ -419,7 +423,7 @@ private async Task<string> 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;
Expand Down
2 changes: 1 addition & 1 deletion Clients/PsnClient/Utils/TmdbHasher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static string GetTitleHash(string productId)
public static byte[] FromHexString(this string hexString)
{
if (hexString.Length == 0)
return Array.Empty<byte>();
return [];

if (hexString.Length % 2 != 0)
throw new ArgumentException("Invalid hex string format: odd number of octets", nameof(hexString));
Expand Down
6 changes: 3 additions & 3 deletions CompatBot/Commands/BotStats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ["🙀", "😿", "😾",];
}
20 changes: 10 additions & 10 deletions CompatBot/Commands/CompatList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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(?<version>\d+\.\d+\.\d+)-(?<build>\d+)-(?<commit>[0-9a-f]+)\b",
RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture
);
[GeneratedRegex(@"v(?<version>\d+\.\d+\.\d+)-(?<build>\d+)-(?<commit>[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()
{
Expand Down Expand Up @@ -247,7 +247,7 @@ public static async Task<bool> 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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -597,7 +597,7 @@ public static async Task ImportMetacriticScoresAsync()
}
}

var scoreList = JsonSerializer.Deserialize<List<Metacritic>>(json) ?? new();
var scoreList = JsonSerializer.Deserialize<List<Metacritic>>(json) ?? [];

Config.Log.Debug($"Importing {scoreList.Count} Metacritic items");
var duplicates = new List<Metacritic>();
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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)
Expand Down
19 changes: 14 additions & 5 deletions CompatBot/Commands/ContentFilters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@

namespace CompatBot.Commands.Converters;

internal sealed class TextOnlyDiscordChannelConverter : IArgumentConverter<DiscordChannel>
internal sealed partial class TextOnlyDiscordChannelConverter : IArgumentConverter<DiscordChannel>
{
private static Regex ChannelRegex { get; } = new(@"^<#(\d+)>$", RegexOptions.ECMAScript | RegexOptions.Compiled);
[GeneratedRegex(@"^<#(\d+)>$", RegexOptions.ECMAScript)]
private static partial Regex ChannelRegex();

Task<Optional<DiscordChannel>> IArgumentConverter<DiscordChannel>.ConvertAsync(string value, CommandContext ctx)
=> ConvertAsync(value, ctx);

public static async Task<Optional<DiscordChannel>> ConvertAsync(string value, CommandContext ctx)
{
var guildList = new List<DiscordGuild>(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
Expand All @@ -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 = (
Expand Down
9 changes: 5 additions & 4 deletions CompatBot/Commands/EventsBaseCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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(@"((?<days>\d+)(\.|d\s*))?((?<hours>\d+)(\:|h\s*))?((?<mins>\d+)m?)?",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture);

[GeneratedRegex(@"((?<days>\d+)(\.|d\s*))?((?<hours>\d+)(\:|h\s*))?((?<mins>\d+)m?)?", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture)]
private static partial Regex Duration();

protected static async Task NearestEvent(CommandContext ctx, string? eventName = null)
{
Expand Down Expand Up @@ -546,7 +547,7 @@ protected static async Task List(CommandContext ctx, string? eventName = null, i

private static async Task<TimeSpan?> TryParseTimeSpanAsync(CommandContext ctx, string duration, bool react = true)
{
var d = Duration.Match(duration);
var d = Duration().Match(duration);
if (!d.Success)
{
if (react)
Expand Down
3 changes: 2 additions & 1 deletion CompatBot/Commands/Explain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 72dbc40

Please sign in to comment.