summary refs log tree commit diff
path: root/ReferenceClientProxyImplementation
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/CompactSingleExportPathPatch.cs70
-rw-r--r--ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSciencePatch.cs2
-rw-r--r--ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSelfXssPatch.cs23
-rw-r--r--ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSentryPatch.cs31
-rw-r--r--ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/RemoveSourceMapReferencesPatch.cs25
-rw-r--r--ReferenceClientProxyImplementation/Patches/Implementations/PatchSet.cs60
-rw-r--r--ReferenceClientProxyImplementation/Program.cs8
-rw-r--r--ReferenceClientProxyImplementation/ReferenceClientProxyImplementation.csproj2
-rw-r--r--ReferenceClientProxyImplementation/Tasks/Startup/InitClientStoreTask.cs143
-rw-r--r--ReferenceClientProxyImplementation/Tasks/Tasks.cs2
10 files changed, 313 insertions, 53 deletions
diff --git a/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/CompactSingleExportPathPatch.cs b/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/CompactSingleExportPathPatch.cs
new file mode 100644

index 0000000..9cf8102 --- /dev/null +++ b/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/CompactSingleExportPathPatch.cs
@@ -0,0 +1,70 @@ +using System.Text; +using System.Text.RegularExpressions; +using ArcaneLibs.Extensions; + +namespace ReferenceClientProxyImplementation.Patches.Implementations.JSPatches; + +public partial class CompactSingleExportPathPatch : IPatch +{ + public int GetOrder() => 2; + + public string GetName() => "Patch single path export function to be more compact"; + public bool Applies(string relativeName, byte[] content) => relativeName.EndsWith(".js"); + + public async Task<byte[]> Execute(string relativePath, byte[] content) + { + var stringContent = Encoding.UTF8.GetString(content); + + // stringContent = SimpleSingleParamExportRegex().Replace( + // stringContent, + // m => + // $"{m.Groups[1].Value}({m.Groups[2].Value}) {{ {m.Groups[2].Value}.exports = \"{m.Groups[3].Value}\"; }}," + // ); + + var fnSigLength = new Dictionary<int, int>(); + var lastMatchIdx = new Dictionary<int, int>(); + stringContent = SimpleMultiParamExportRegex().Replace( + stringContent, + m => + { + // might aswell make it aligned... + int argCnt = m.Groups["fnParams"].Value.CountInstances(","); + lastMatchIdx.TryAdd(argCnt, 0); + fnSigLength.TryAdd(argCnt, 0); + + if (m.Index - lastMatchIdx[argCnt] > 1000) fnSigLength[argCnt] = 0; + lastMatchIdx[argCnt] = m.Index; + var currentFnSigLength = m.Groups["fnName"].Length + m.Groups["fnParams"].Length + 2; + if (currentFnSigLength > fnSigLength[argCnt]) fnSigLength[argCnt] = currentFnSigLength; + return + $"{m.Groups["fnName"].Value}({m.Groups["fnParams"].Value})".PadLeft(fnSigLength[argCnt]) + + $" {{ {m.Groups["exportTarget"].Value}.exports = {m.Groups["exportImpl"].Value}; }},"; + }); + + return Encoding.UTF8.GetBytes(stringContent); + } + + /* + * 12345(e) { + * "use strict"; + * e.exports = "/abcdef.svg"; + * } + */ + [GeneratedRegex(@"(\d+)\((.)\) {(?:\n\s+""use strict"";)?\n\s+\2\.exports = ""([/a-z0-9\.]+)"";\n\s+},", + RegexOptions.Compiled)] + private static partial Regex SimpleSingleParamExportRegex(); + + /* + * 12345(e, t, n) { + * "use strict"; + * e.exports = n.p + "/abcdef.svg"; + * } + */ + [GeneratedRegex(""" + (?<fnName>[a-zA-Z0-9]+)\((?<fnParams>[a-zA-Z0-9\s,]*)\) { + (?:\s+"use strict";)? + \s+(?<exportTarget>[a-zA-Z0-9]+)\.exports = (?<exportImpl>[^;]+?); + \s+}, + """, RegexOptions.Compiled)] + private static partial Regex SimpleMultiParamExportRegex(); +} \ No newline at end of file diff --git a/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSciencePatch.cs b/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSciencePatch.cs
index c44bf95..2e1c102 100644 --- a/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSciencePatch.cs +++ b/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSciencePatch.cs
@@ -13,6 +13,8 @@ public partial class DisableSciencePatch : IPatch { var stringContent = Encoding.UTF8.GetString(content); var match = HandleTrackDefinitionRegex().Match(stringContent); + if (match.Length == 0) return content; + Console.WriteLine($"DisableSciencePatch: found science at {match.Index}(+{match.Length})"); stringContent = stringContent.Insert(match.Index + match.Length, @" return (new Promise(() => { }), false); // ReferenceClientProxyImplementation: Disable /science calls "); diff --git a/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSelfXssPatch.cs b/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSelfXssPatch.cs new file mode 100644
index 0000000..59746f4 --- /dev/null +++ b/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSelfXssPatch.cs
@@ -0,0 +1,23 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace ReferenceClientProxyImplementation.Patches.Implementations.JSPatches; + +public partial class DisableSelfXssPatch : IPatch { + public int GetOrder() => 0; + + public string GetName() => "JS: Disable self-xss warnings"; + public bool Applies(string relativeName, byte[] content) => relativeName.EndsWith(".js"); + + public async Task<byte[]> Execute(string _, byte[] content) { + var stringContent = Encoding.UTF8.GetString(content); + + stringContent = SelfXssNullCheckRegex().Replace(stringContent, "false"); + + return Encoding.UTF8.GetBytes(stringContent); + } + + [GeneratedRegex(@"null != [a-zA-Z0-9]+\.[a-zA-Z0-9]+\.Messages\.SELF_XSS_HEADER", RegexOptions.Compiled)] + private static partial Regex SelfXssNullCheckRegex(); + +} \ No newline at end of file diff --git a/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSentryPatch.cs b/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSentryPatch.cs new file mode 100644
index 0000000..7424a32 --- /dev/null +++ b/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/DisableSentryPatch.cs
@@ -0,0 +1,31 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace ReferenceClientProxyImplementation.Patches.Implementations.JSPatches; + +public partial class DisableSentryPatch : IPatch { + public int GetOrder() => 0; + + public string GetName() => "JS: Disable sentry"; + public bool Applies(string relativeName, byte[] content) => relativeName.StartsWith("assets/sentry.") && relativeName.EndsWith(".js"); + + public async Task<byte[]> Execute(string _, byte[] content) { + var stringContent = Encoding.UTF8.GetString(content); + + stringContent = SentryInitRegex().Replace(stringContent, "window.DiscordSentry = undefined;"); + stringContent = SentryConsoleHookRegex().Replace( + stringContent, + m => m.Value.Replace(" &&", " && false &&") + ); + + return Encoding.UTF8.GetBytes(stringContent); + } + + [GeneratedRegex(@"window\.DiscordSentry =", RegexOptions.Compiled)] + private static partial Regex SentryInitRegex(); + + // hopefully specific enough? + [GeneratedRegex(@"function ([a-zA-Z0-9]+)\(\) {\n\s+""console"" in ([a-zA-Z0-9]+) &&\n\s+([a-zA-Z0-9]+)\.forEach\(", RegexOptions.Compiled)] + private static partial Regex SentryConsoleHookRegex(); + +} \ No newline at end of file diff --git a/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/RemoveSourceMapReferencesPatch.cs b/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/RemoveSourceMapReferencesPatch.cs new file mode 100644
index 0000000..7fefc14 --- /dev/null +++ b/ReferenceClientProxyImplementation/Patches/Implementations/JSPatches/RemoveSourceMapReferencesPatch.cs
@@ -0,0 +1,25 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace ReferenceClientProxyImplementation.Patches.Implementations.JSPatches; + +public partial class RemoveSourceMapReferencesPatch : IPatch +{ + public int GetOrder() => 0; + + public string GetName() => "JS: Disable sentry"; + + public bool Applies(string relativeName, byte[] content) => relativeName.EndsWith(".js"); + + public async Task<byte[]> Execute(string _, byte[] content) + { + var stringContent = Encoding.UTF8.GetString(content); + + stringContent = SourceMapUrlRegex().Replace(stringContent, ""); + + return Encoding.UTF8.GetBytes(stringContent); + } + + [GeneratedRegex(@"//# sourceMappingURL.*\n", RegexOptions.Compiled)] + private static partial Regex SourceMapUrlRegex(); +} \ No newline at end of file diff --git a/ReferenceClientProxyImplementation/Patches/Implementations/PatchSet.cs b/ReferenceClientProxyImplementation/Patches/Implementations/PatchSet.cs
index c3dba59..5840e03 100644 --- a/ReferenceClientProxyImplementation/Patches/Implementations/PatchSet.cs +++ b/ReferenceClientProxyImplementation/Patches/Implementations/PatchSet.cs
@@ -1,26 +1,64 @@ +using System.Collections.Concurrent; + namespace ReferenceClientProxyImplementation.Patches.Implementations; -public class PatchSet(IServiceProvider sp) { +public class PatchSet(IServiceProvider sp) +{ + public ConcurrentDictionary<string, PatchState> ActivePatchStates { get; } = []; public List<IPatch> Patches { get; } = sp.GetServices<IPatch>().OrderBy(x => x.GetOrder()).ToList(); - public async Task<byte[]> ApplyPatches(string relativeName, byte[] content) { + public async Task<byte[]> ApplyPatches(string relativeName, byte[] content) + { var i = 0; var patches = Patches .Where(p => p.Applies(relativeName, content)) .OrderBy(p => p.GetOrder()) .ToList(); - foreach (var patch in patches) { - if (patch.Applies(relativeName, content)) { - var defaultColor = Console.ForegroundColor; - Console.ForegroundColor = ConsoleColor.DarkBlue; - Console.Write("==> "); - Console.ForegroundColor = ConsoleColor.DarkGray; - Console.WriteLine($"Running task {++i}/{patches.Count}: {patch.GetName()} (Type<{patch.GetType().Name}>)"); - Console.ForegroundColor = defaultColor; - content = await patch.Execute(relativeName, content); + + if (!patches.Any()) + { + Console.WriteLine($"No patches required for {relativeName}!"); + return content; + } + + lock (ActivePatchStates) + ActivePatchStates[relativeName] = new() + { + CurrentPatch = patches[0].GetName(), + CurrentPatchIndex = 0, + TotalPatchCount = patches.Count + }; + + foreach (var patch in patches) + { + // if (patch.Applies(relativeName, content)) { + lock (ActivePatchStates) + { + ActivePatchStates[relativeName].CurrentPatchIndex = patches.IndexOf(patch); + ActivePatchStates[relativeName].CurrentPatch = patch.GetName(); } + + var defaultColor = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.DarkBlue; + Console.Write($"{relativeName,32} ==> "); + Console.ForegroundColor = ConsoleColor.DarkGray; + Console.WriteLine($"Running task {++i}/{patches.Count}: {patch.GetName()} (Type<{patch.GetType().Name}>)"); + Console.ForegroundColor = defaultColor; + content = await patch.Execute(relativeName, content); + // } } + lock (ActivePatchStates) + ActivePatchStates.Remove(relativeName, out _); + Console.WriteLine($"Finished patching {relativeName}, {ActivePatchStates.Count} files still processing"); + return content; } +} + +public class PatchState +{ + public required string CurrentPatch { get; set; } + public int CurrentPatchIndex { get; set; } = 0; + public required int TotalPatchCount { get; set; } } \ No newline at end of file diff --git a/ReferenceClientProxyImplementation/Program.cs b/ReferenceClientProxyImplementation/Program.cs
index c35248b..eb27118 100644 --- a/ReferenceClientProxyImplementation/Program.cs +++ b/ReferenceClientProxyImplementation/Program.cs
@@ -37,7 +37,6 @@ builder.Host.ConfigureHostOptions(host => { builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); builder.Services.AddHttpLogging(o => { o.LoggingFields = HttpLoggingFields.All; }); builder.Services.AddLogging(o => { if (SystemdHelpers.IsSystemdService()) @@ -64,15 +63,8 @@ builder.Services.AddSingleton<ClientStoreService>(); var app = builder.Build(); -// -if (app.Environment.IsDevelopment()) { - app.UseSwagger(); - app.UseSwaggerUI(); -} - app.UseHttpLogging(); app.UseRouting(); -// app.UseSentryTracing(); // app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); diff --git a/ReferenceClientProxyImplementation/ReferenceClientProxyImplementation.csproj b/ReferenceClientProxyImplementation/ReferenceClientProxyImplementation.csproj
index 14bdb55..50b314d 100644 --- a/ReferenceClientProxyImplementation/ReferenceClientProxyImplementation.csproj +++ b/ReferenceClientProxyImplementation/ReferenceClientProxyImplementation.csproj
@@ -18,8 +18,6 @@ <PackageReference Include="ArcaneLibs" Version="1.0.0-preview.20250630-114950"/> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.6"/> <PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="9.0.6"/> - <PackageReference Include="Sentry.AspNetCore" Version="5.11.2"/> - <PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.1"/> </ItemGroup> <ItemGroup> diff --git a/ReferenceClientProxyImplementation/Tasks/Startup/InitClientStoreTask.cs b/ReferenceClientProxyImplementation/Tasks/Startup/InitClientStoreTask.cs
index 4aeab96..42d9d51 100644 --- a/ReferenceClientProxyImplementation/Tasks/Startup/InitClientStoreTask.cs +++ b/ReferenceClientProxyImplementation/Tasks/Startup/InitClientStoreTask.cs
@@ -1,40 +1,97 @@ using System.Diagnostics; using System.Text; using System.Text.RegularExpressions; +using AngleSharp.Html.Parser; using ArcaneLibs.Extensions; using ReferenceClientProxyImplementation.Configuration; +using ReferenceClientProxyImplementation.Services; namespace ReferenceClientProxyImplementation.Tasks.Startup; -public partial class InitClientStoreService(ProxyConfiguration proxyConfig) : ITask { +public partial class InitClientStoreService(ProxyConfiguration proxyConfig, ClientStoreService clientStore) : ITask +{ public int GetOrder() => 0; public string GetName() => "Get client revision"; - public async Task Execute() { - switch (proxyConfig.TestClient.Revision) { + public async Task Execute() + { + switch (proxyConfig.TestClient.Revision) + { case "canary": proxyConfig.TestClient.RevisionBaseUrl = "https://canary.discord.com"; - proxyConfig.TestClient.RevisionPath = await GetRevisionPathFromUrl("canary", "https://canary.discord.com/app"); + proxyConfig.TestClient.RevisionPath = + await GetRevisionPathFromUrl("canary", "https://canary.discord.com/app"); break; case "ptb": proxyConfig.TestClient.RevisionBaseUrl = "https://ptb.discord.com"; - proxyConfig.TestClient.RevisionPath = await GetRevisionPathFromUrl("ptb", "https://ptb.discord.com/app"); + proxyConfig.TestClient.RevisionPath = + await GetRevisionPathFromUrl("ptb", "https://ptb.discord.com/app"); break; case "stable": proxyConfig.TestClient.RevisionBaseUrl = "https://discord.com"; proxyConfig.TestClient.RevisionPath = await GetRevisionPathFromUrl("stable", "https://discord.com/app"); break; default: - if (proxyConfig.TestClient.RevisionPath == null) { + if (proxyConfig.TestClient.RevisionPath == null) + { throw new Exception("Test client revision path is not set!"); } break; } + + var hp = new HtmlParser(); + { + Console.WriteLine("Parsing app.html content"); + var appDocument = hp.ParseDocument(await clientStore.GetPatchedClientAsset("app.html")); + Console.WriteLine("Parsed app.html content"); + if (appDocument.Head is null) Console.WriteLine("No head element???"); + else if (appDocument.Head.Children.Length == 0) Console.WriteLine("Head element has no children????"); + else Console.WriteLine($"Checking {appDocument.Head.Children.Length} children...."); + List<string> toDownload = []; + foreach (var child in appDocument.Head.Children) + { + if (child.TagName.ToLower() == "link" && child.GetAttribute("rel") == "stylesheet") + { + var name = child.GetAttribute("href"); + Console.WriteLine($"Found stylesheet {name} in app.html"); + toDownload.Add(name!); + } + else if (child.TagName.ToLower() == "link" && child.GetAttribute("rel") == "preload" && + child.GetAttribute("as") == "script") + { + var name = child.GetAttribute("href"); + Console.WriteLine($"Found preload script {name} in app.html"); + toDownload.Add(name!); + } + else if (child.TagName.ToLower() == "script" && child.HasAttribute("defer")) + { + var name = child.GetAttribute("src"); + Console.WriteLine($"Found deferred script {name} in app.html"); + toDownload.Add(name!); + } + else + { + Console.WriteLine($"wtf is a {child.TagName} ({child.OuterHtml})"); + } + } + + var patchSem = new SemaphoreSlim(8, 8); + var tasks = toDownload.Distinct().Select(async x => + { + await clientStore.GetOrDownloadRawAsset(x); + await patchSem.WaitAsync(); + var res = await clientStore.GetPatchedClientAsset(x); + await res.DisposeAsync(); + patchSem.Release(); + }).ToList(); + await Task.WhenAll(tasks); + } } - private async Task<string> GetRevisionPathFromUrl(string rev, string url) { + private async Task<string> GetRevisionPathFromUrl(string rev, string url) + { using var hc = new HttpClient(); using var response = await hc.GetAsync(url); var content = await response.Content.ReadAsStringAsync(); @@ -42,16 +99,23 @@ public partial class InitClientStoreService(ProxyConfiguration proxyConfig) : IT var hash = System.Security.Cryptography.SHA256.HashData(Encoding.UTF8.GetBytes(normalisedContent)); var knownHashes = await GetKnownRevisionHashes("src/app.html"); var currentRevisionFilePath = Path.Combine(proxyConfig.AssetCache.DiskCacheBaseDirectory, "currentRevision"); - var previousRevision = Path.Exists(currentRevisionFilePath) ? await File.ReadAllTextAsync(currentRevisionFilePath) : ""; + var previousRevision = Path.Exists(currentRevisionFilePath) + ? await File.ReadAllTextAsync(currentRevisionFilePath) + : ""; var revisionName = rev; - if (knownHashes.Any(x => x.Value.SequenceEqual(hash))) { - Console.WriteLine($"[InitClientStoreTask] Found known revision '{rev}' with hash {hash.AsHexString().Replace(" ", "")}!"); + if (knownHashes.Any(x => x.Value.SequenceEqual(hash))) + { + Console.WriteLine( + $"[InitClientStoreTask] Found known revision '{rev}' with hash {hash.AsHexString().Replace(" ", "")}!"); revisionName = knownHashes.First(x => x.Value.SequenceEqual(hash)).Key; } - else { - Console.WriteLine($"[InitClientStoreTask] No known revision found for hash {hash.AsHexString().Replace(" ", "")}, creating new revision directory!"); - if (response.Headers.Contains("X-Build-Id")) { + else + { + Console.WriteLine( + $"[InitClientStoreTask] No known revision found for hash {hash.AsHexString().Replace(" ", "")}, creating new revision directory!"); + if (response.Headers.Contains("X-Build-Id")) + { revisionName = "buildId_" + response.Headers.GetValues("X-Build-Id").FirstOrDefault(); Console.WriteLine("[InitClientStoreTask] Using build ID from X-Build-Id header: " + revisionName); } @@ -61,44 +125,57 @@ public partial class InitClientStoreService(ProxyConfiguration proxyConfig) : IT Console.WriteLine($"[InitClientStoreTask] Saving revision '{revisionName}' to {revisionPath}..."); PrepareRevisionDirectory(revisionPath); await File.WriteAllTextAsync(Path.Combine(revisionPath, "src", "app.html"), content); - await File.WriteAllTextAsync(Path.Combine(proxyConfig.AssetCache.DiskCacheBaseDirectory, "currentRevision"), revisionName); + await File.WriteAllTextAsync(Path.Combine(proxyConfig.AssetCache.DiskCacheBaseDirectory, "currentRevision"), + revisionName); //also download dev page using var devResponse = await hc.GetAsync(url.Replace("/app", "/developers/applications")); var devContent = await devResponse.Content.ReadAsStringAsync(); await File.WriteAllTextAsync(Path.Combine(revisionPath, "src", "developers.html"), devContent); - + //...and popout using var popoutResponse = await hc.GetAsync(url.Replace("/app", "/popout")); var popoutContent = await popoutResponse.Content.ReadAsStringAsync(); await File.WriteAllTextAsync(Path.Combine(revisionPath, "src", "popout.html"), popoutContent); - - if (proxyConfig.AssetCache.DitchPatchedOnStartup) { + + if (proxyConfig.AssetCache.DitchPatchedOnStartup) + { Directory.Delete(Path.Combine(revisionPath, "patched"), true); Directory.CreateDirectory(Path.Combine(revisionPath, "patched")); } - if (previousRevision != revisionName || true) { - foreach (var argv in proxyConfig.AssetCache.ExecOnRevisionChange) { - try { - var psi = new ProcessStartInfo(argv[0], argv[1..].Select(a => a.Replace("{revisionPath}", revisionPath))) { + if (previousRevision != revisionName || true) + { + foreach (var argv in proxyConfig.AssetCache.ExecOnRevisionChange) + { + try + { + var psi = new ProcessStartInfo(argv[0], + argv[1..].Select(a => a.Replace("{revisionPath}", revisionPath))) + { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using var process = Process.Start(psi); - if (process != null) { + if (process != null) + { _ = process.StandardOutput.ReadToEndAsync(); _ = process.StandardError.ReadToEndAsync(); - Console.WriteLine($"[InitClientStoreTask] Executing post-revision change command: {argv[0]} {string.Join(" ", argv[1..])}"); + Console.WriteLine( + $"[InitClientStoreTask] Executing post-revision change command: {argv[0]} {string.Join(" ", argv[1..])}"); } - else { - Console.WriteLine($"[InitClientStoreTask] Failed to start post-revision change command: {argv[0]} {string.Join(" ", argv[1..])}"); + else + { + Console.WriteLine( + $"[InitClientStoreTask] Failed to start post-revision change command: {argv[0]} {string.Join(" ", argv[1..])}"); } } - catch (Exception e) { - Console.WriteLine($"[InitClientStoreTask] Failed to start post-revision change command: {argv[0]} {string.Join(" ", argv[1..])}\n{e}"); + catch (Exception e) + { + Console.WriteLine( + $"[InitClientStoreTask] Failed to start post-revision change command: {argv[0]} {string.Join(" ", argv[1..])}\n{e}"); } } } @@ -106,14 +183,16 @@ public partial class InitClientStoreService(ProxyConfiguration proxyConfig) : IT return revisionPath; } - private static void PrepareRevisionDirectory(string revisionPath, bool dropPatched = false) { + private static void PrepareRevisionDirectory(string revisionPath, bool dropPatched = false) + { Directory.CreateDirectory(revisionPath); Directory.CreateDirectory(Path.Combine(revisionPath, "src")); Directory.CreateDirectory(Path.Combine(revisionPath, "formatted")); Directory.CreateDirectory(Path.Combine(revisionPath, "patched")); } - private async Task<Dictionary<string, byte[]>> GetKnownRevisionHashes(string file) { + private async Task<Dictionary<string, byte[]>> GetKnownRevisionHashes(string file) + { if (!Directory.Exists(proxyConfig.AssetCache.DiskCacheBaseDirectory)) Directory.CreateDirectory(proxyConfig.AssetCache.DiskCacheBaseDirectory); @@ -130,9 +209,11 @@ public partial class InitClientStoreService(ProxyConfiguration proxyConfig) : IT ); } - private async Task<(string RevisionId, byte[] Hash)?> GetKnownRevisionHash(string dir, string file) { + private async Task<(string RevisionId, byte[] Hash)?> GetKnownRevisionHash(string dir, string file) + { var hashFile = Path.Combine(dir, file); - if (File.Exists(hashFile)) { + if (File.Exists(hashFile)) + { var content = StripNonces(await File.ReadAllTextAsync(hashFile)); var hash = System.Security.Cryptography.SHA256.HashData(Encoding.UTF8.GetBytes(content)); var result = (new DirectoryInfo(dir).Name, hash); diff --git a/ReferenceClientProxyImplementation/Tasks/Tasks.cs b/ReferenceClientProxyImplementation/Tasks/Tasks.cs
index 5038002..6f0425c 100644 --- a/ReferenceClientProxyImplementation/Tasks/Tasks.cs +++ b/ReferenceClientProxyImplementation/Tasks/Tasks.cs
@@ -16,7 +16,7 @@ public class Tasks(IServiceProvider serviceProvider) : BackgroundService { Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine($"Running task {++i}/{tasks.Count}: {task.GetName()} (Type<{task.GetType().Name}>)"); Console.ForegroundColor = defaultColor; - task.Execute(); + await task.Execute(); } } }