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
|