Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some performance and code optimizations #955

Merged
merged 8 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading