From 0fb79b763d797d70d2eb6d847b0bf711c9927337 Mon Sep 17 00:00:00 2001 From: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Date: Sun, 19 Mar 2023 04:53:00 -0300 Subject: Improvements, changes and fixes (#611) --- src/plugins/apiContextMenu.ts | 46 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) (limited to 'src/plugins/apiContextMenu.ts') diff --git a/src/plugins/apiContextMenu.ts b/src/plugins/apiContextMenu.ts index 1874f5f..88a1eb9 100644 --- a/src/plugins/apiContextMenu.ts +++ b/src/plugins/apiContextMenu.ts @@ -18,9 +18,28 @@ import { Settings } from "@api/settings"; import { Devs } from "@utils/constants"; -import definePlugin from "@utils/types"; +import definePlugin, { type PatchReplacement } from "@utils/types"; import { addListener, removeListener } from "@webpack"; +/** + * The last var name corresponding to the Context Menu API (Discord, not ours) module + */ +let lastVarName = ""; + +/** + * @param target The patch replacement object + * @param exportKey The key exporting the build Context Menu component function + */ +function makeReplacementProxy(target: PatchReplacement, exportKey: string) { + return new Proxy(target, { + get(_, p) { + if (p === "match") return RegExp(`${exportKey},{(?<=${lastVarName}\\.${exportKey},{)`, "g"); + // @ts-expect-error + return Reflect.get(...arguments); + } + }); +} + function listener(exports: any, id: number) { if (!Settings.plugins.ContextMenuAPI.enabled) return removeListener(listener); @@ -37,13 +56,24 @@ function listener(exports: any, id: number) { all: true, noWarn: true, find: "navId:", - replacement: [{ - match: RegExp(`${id}(?<=(\\i)=.+?).+$`), - replace: (code, varName) => { - const regex = RegExp(`${key},{(?<=${varName}\\.${key},{)`, "g"); - return code.replace(regex, "$&contextMenuApiArguments:arguments,"); - } - }] + replacement: [ + { + // Set the lastVarName for our proxy to use + match: RegExp(`${id}(?<=(\\i)=.+?)`), + replace: (id, varName) => { + lastVarName = varName; + return id; + } + }, + /** + * We are using a proxy here to utilize the whole code the patcher gives us, instead of matching the entire module (which is super slow) + * Our proxy returns the corresponding match for that module utilizing lastVarName, which is set by the patch before + */ + makeReplacementProxy({ + match: "", // Needed to canonicalizeDescriptor + replace: "$&contextMenuApiArguments:arguments,", + }, key) + ] }); removeListener(listener); -- cgit