Fix entry webpack modules not being patched
This commit is contained in:
		
							parent
							
								
									25f101602d
								
							
						
					
					
						commit
						e4701769a5
					
				
					 1 changed files with 189 additions and 163 deletions
				
			
		|  | @ -53,17 +53,65 @@ if (window[WEBPACK_CHUNK]) { | |||
|         }, | ||||
|         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 handlePush(chunk: any) { | ||||
|         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 { patches } = Vencord.Plugins; | ||||
| 
 | ||||
|             for (const id in modules) { | ||||
|                 let mod = modules[id]; | ||||
|     for (const id in factories) { | ||||
|         let mod = factories[id]; | ||||
|         // Discords Webpack chunks for some ungodly reason contain random
 | ||||
|         // newlines. Cyn recommended this workaround and it seems to work fine,
 | ||||
|         // however this could potentially break code, so if anything goes weird,
 | ||||
|  | @ -80,7 +128,7 @@ function patchPush(webpackGlobal: any) { | |||
|         const originalMod = mod; | ||||
|         const patchedBy = new Set(); | ||||
| 
 | ||||
|                 const factory = modules[id] = function (module, exports, require) { | ||||
|         const factory = factories[id] = function (module, exports, require) { | ||||
|             try { | ||||
|                 mod(module, exports, require); | ||||
|             } 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