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();
}
}
}
|