Fix not restoring some original factories

This commit is contained in:
Nuckyz 2024-06-01 19:38:01 -03:00
parent ac6a21374f
commit 61e1eada01
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
2 changed files with 39 additions and 16 deletions

View file

@ -111,14 +111,14 @@ export async function loadLazyChunks() {
Webpack.factoryListeners.add(factory => { Webpack.factoryListeners.add(factory => {
let isResolved = false; let isResolved = false;
searchAndLoadLazyChunks(factory.toString()).then(() => isResolved = true); searchAndLoadLazyChunks(String(factory)).then(() => isResolved = true);
chunksSearchPromises.push(() => isResolved); chunksSearchPromises.push(() => isResolved);
}); });
for (const factoryId in wreq.m) { for (const factoryId in wreq.m) {
let isResolved = false; let isResolved = false;
searchAndLoadLazyChunks(wreq.m[factoryId].toString()).then(() => isResolved = true); searchAndLoadLazyChunks(String(wreq.m[factoryId])).then(() => isResolved = true);
chunksSearchPromises.push(() => isResolved); chunksSearchPromises.push(() => isResolved);
} }

View file

@ -88,6 +88,10 @@ define(Function.prototype, "O", {
// Patch the pre-populated factories // Patch the pre-populated factories
for (const id in this.m) { for (const id in this.m) {
if (updateExistingFactory(this.m, id, this.m[id])) {
continue;
}
defineModulesFactoryGetter(id, Settings.eagerPatches ? patchFactory(id, this.m[id]) : this.m[id]); defineModulesFactoryGetter(id, Settings.eagerPatches ? patchFactory(id, this.m[id]) : this.m[id]);
} }
@ -140,6 +144,35 @@ function defineModulesFactoryGetter(id: PropertyKey, factory: PatchedModuleFacto
} }
} }
/**
* Update a factory that exists in any Webpack instance with a new original factory.
*
* @target The module factories where this new original factory is being set
* @param id The id of the module
* @param newFactory The new original factory
* @returns Whether the original factory was updated, or false if it doesn't exist in any Webpack instance
*/
function updateExistingFactory(target: AnyWebpackRequire["m"], id: PropertyKey, newFactory: ModuleFactory) {
let existingFactory: TypedPropertyDescriptor<PatchedModuleFactory> | undefined;
for (const wreq of allWebpackInstances) {
if (Reflect.getOwnPropertyDescriptor(wreq.m, id) != null) {
existingFactory = Reflect.getOwnPropertyDescriptor(wreq.m, id);
break;
}
}
if (existingFactory != null) {
// If existingFactory exists in any Webpack instance, its either wrapped in defineModuleFactoryGetter, or it has already been required.
// So define the descriptor of it on this current Webpack instance, call Reflect.set with the new original,
// and let the correct logic apply (normal set, or defineModuleFactoryGetter setter)
Reflect.defineProperty(target, id, existingFactory);
return Reflect.set(target, id, newFactory, target);
}
return false;
}
const moduleFactoriesHandler: ProxyHandler<PatchedModuleFactories> = { const moduleFactoriesHandler: ProxyHandler<PatchedModuleFactories> = {
/* /*
If Discord ever decides to set module factories using the variable of the modules object directly instead of wreq.m, we need to switch the proxy to the prototype If Discord ever decides to set module factories using the variable of the modules object directly instead of wreq.m, we need to switch the proxy to the prototype
@ -163,23 +196,13 @@ const moduleFactoriesHandler: ProxyHandler<PatchedModuleFactories> = {
return define(target, p, { value: newValue }); return define(target, p, { value: newValue });
} }
const existingFactory = Reflect.get(target, p, receiver); if (updateExistingFactory(target, p, newValue)) {
if (!Settings.eagerPatches) {
// If existingFactory exists, its either wrapped in defineModuleFactoryGetter, or it has already been required
// so call Reflect.set with the new original and let the correct logic apply (normal set, or defineModuleFactoryGetter setter)
if (existingFactory != null) {
return Reflect.set(target, p, newValue, receiver);
}
// eagerPatches are disabled, so the factory argument should be the original
defineModulesFactoryGetter(p, newValue);
return true; return true;
} }
// Check if this factory is already patched if (!Settings.eagerPatches) {
if (existingFactory?.$$vencordOriginal != null) { // eagerPatches are disabled, so the factory argument should be the original
existingFactory.$$vencordOriginal = newValue; defineModulesFactoryGetter(p, newValue);
return true; return true;
} }