Fix entry webpack modules not being patched
This commit is contained in:
parent
25f101602d
commit
e4701769a5
|
@ -53,17 +53,65 @@ if (window[WEBPACK_CHUNK]) {
|
||||||
},
|
},
|
||||||
configurable: true
|
configurable: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// wreq.m is the webpack module factory.
|
||||||
|
// normally, this is populated via webpackGlobal.push, which we patch below.
|
||||||
|
// However, Discord has their .m prepopulated.
|
||||||
|
// Thus, we use this hack to immediately access their wreq.m and patch all already existing factories
|
||||||
|
Object.defineProperty(Function.prototype, "m", {
|
||||||
|
set(v: any) {
|
||||||
|
// When using react devtools or other extensions, we may also catch their webpack here.
|
||||||
|
// This ensures we actually got the right one
|
||||||
|
if (new Error().stack?.includes("discord.com")) {
|
||||||
|
logger.info("Found webpack module factory");
|
||||||
|
patchFactories(v);
|
||||||
|
|
||||||
|
delete (Function.prototype as any).m;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.defineProperty(this, "m", {
|
||||||
|
value: v,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function patchPush(webpackGlobal: any) {
|
function patchPush(webpackGlobal: any) {
|
||||||
function handlePush(chunk: any) {
|
function handlePush(chunk: any) {
|
||||||
try {
|
try {
|
||||||
const modules = chunk[1];
|
patchFactories(chunk[1]);
|
||||||
|
} catch (err) {
|
||||||
|
logger.error("Error in handlePush", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return handlePush.$$vencordOriginal.call(webpackGlobal, chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePush.$$vencordOriginal = webpackGlobal.push;
|
||||||
|
// Webpack overwrites .push with its own push like so: `d.push = n.bind(null, d.push.bind(d));`
|
||||||
|
// it wraps the old push (`d.push.bind(d)`). this old push is in this case our handlePush.
|
||||||
|
// If we then repatched the new push, we would end up with recursive patching, which leads to our patches
|
||||||
|
// being applied multiple times.
|
||||||
|
// Thus, override bind to use the original push
|
||||||
|
handlePush.bind = (...args: unknown[]) => handlePush.$$vencordOriginal.bind(...args);
|
||||||
|
|
||||||
|
Object.defineProperty(webpackGlobal, "push", {
|
||||||
|
get: () => handlePush,
|
||||||
|
set(v) {
|
||||||
|
handlePush.$$vencordOriginal = v;
|
||||||
|
},
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function patchFactories(factories: Record<string | number, (module: { exports: any; }, exports: any, require: any) => void>) {
|
||||||
const { subscriptions, listeners } = Vencord.Webpack;
|
const { subscriptions, listeners } = Vencord.Webpack;
|
||||||
const { patches } = Vencord.Plugins;
|
const { patches } = Vencord.Plugins;
|
||||||
|
|
||||||
for (const id in modules) {
|
for (const id in factories) {
|
||||||
let mod = modules[id];
|
let mod = factories[id];
|
||||||
// Discords Webpack chunks for some ungodly reason contain random
|
// Discords Webpack chunks for some ungodly reason contain random
|
||||||
// newlines. Cyn recommended this workaround and it seems to work fine,
|
// newlines. Cyn recommended this workaround and it seems to work fine,
|
||||||
// however this could potentially break code, so if anything goes weird,
|
// however this could potentially break code, so if anything goes weird,
|
||||||
|
@ -80,7 +128,7 @@ function patchPush(webpackGlobal: any) {
|
||||||
const originalMod = mod;
|
const originalMod = mod;
|
||||||
const patchedBy = new Set();
|
const patchedBy = new Set();
|
||||||
|
|
||||||
const factory = modules[id] = function (module, exports, require) {
|
const factory = factories[id] = function (module, exports, require) {
|
||||||
try {
|
try {
|
||||||
mod(module, exports, require);
|
mod(module, exports, require);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -221,26 +269,4 @@ function patchPush(webpackGlobal: any) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
logger.error("Error in handlePush", err);
|
|
||||||
}
|
|
||||||
|
|
||||||
return handlePush.$$vencordOriginal.call(webpackGlobal, chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePush.$$vencordOriginal = webpackGlobal.push;
|
|
||||||
// Webpack overwrites .push with its own push like so: `d.push = n.bind(null, d.push.bind(d));`
|
|
||||||
// it wraps the old push (`d.push.bind(d)`). this old push is in this case our handlePush.
|
|
||||||
// If we then repatched the new push, we would end up with recursive patching, which leads to our patches
|
|
||||||
// being applied multiple times.
|
|
||||||
// Thus, override bind to use the original push
|
|
||||||
handlePush.bind = (...args: unknown[]) => handlePush.$$vencordOriginal.bind(...args);
|
|
||||||
|
|
||||||
Object.defineProperty(webpackGlobal, "push", {
|
|
||||||
get: () => handlePush,
|
|
||||||
set(v) {
|
|
||||||
handlePush.$$vencordOriginal = v;
|
|
||||||
},
|
|
||||||
configurable: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue