WebpackPatcher: Improve getBuildNumber; Allow reporter to check for buildNumber

Allows replacements to define noWarn too
This commit is contained in:
Nuckyz 2025-02-21 01:14:11 -03:00
parent dd714ff3c2
commit 3e524f9d92
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
2 changed files with 40 additions and 34 deletions

View file

@ -41,7 +41,12 @@ export interface PatchReplacement {
match: string | RegExp; match: string | RegExp;
/** The replacement string or function which returns the string for the patch replacement */ /** The replacement string or function which returns the string for the patch replacement */
replace: string | ReplaceFn; replace: string | ReplaceFn;
/** A function which returns whether this patch replacement should be applied */ /** Do not warn if this replacement did no changes */
noWarn?: boolean;
/**
* A function which returns whether this patch replacement should be applied.
* This is ran before patches are registered, so if this returns false, the patch will never be registered.
*/
predicate?(): boolean; predicate?(): boolean;
/** The minimum build number for this patch to be applied */ /** The minimum build number for this patch to be applied */
fromBuild?: number; fromBuild?: number;
@ -61,7 +66,10 @@ export interface Patch {
noWarn?: boolean; noWarn?: boolean;
/** Only apply this set of replacements if all of them succeed. Use this if your replacements depend on each other */ /** Only apply this set of replacements if all of them succeed. Use this if your replacements depend on each other */
group?: boolean; group?: boolean;
/** A function which returns whether this patch should be applied */ /**
* A function which returns whether this patch replacement should be applied.
* This is ran before patches are registered, so if this returns false, the patch will never be registered.
*/
predicate?(): boolean; predicate?(): boolean;
/** The minimum build number for this patch to be applied */ /** The minimum build number for this patch to be applied */
fromBuild?: number; fromBuild?: number;

View file

@ -12,8 +12,8 @@ import { canonicalizeReplacement } from "@utils/patches";
import { Patch, PatchReplacement } from "@utils/types"; import { Patch, PatchReplacement } from "@utils/types";
import { traceFunctionWithResults } from "../debug/Tracer"; import { traceFunctionWithResults } from "../debug/Tracer";
import { _blacklistBadModules, _initWebpack, factoryListeners, findModuleId, moduleListeners, waitForSubscriptions, wreq } from "./webpack"; import { _blacklistBadModules, _initWebpack, factoryListeners, findModuleFactory, moduleListeners, waitForSubscriptions, wreq } from "./webpack";
import { AnyModuleFactory, AnyWebpackRequire, MaybePatchedModuleFactory, ModuleExports, PatchedModuleFactory, WebpackRequire } from "./wreq.d"; import { AnyModuleFactory, AnyWebpackRequire, MaybePatchedModuleFactory, PatchedModuleFactory, WebpackRequire } from "./wreq.d";
export const patches = [] as Patch[]; export const patches = [] as Patch[];
@ -27,28 +27,26 @@ export const patchTimings = [] as Array<[plugin: string, moduleId: PropertyKey,
export const getBuildNumber = makeLazy(() => { export const getBuildNumber = makeLazy(() => {
try { try {
try { function matchBuildNumber(factoryStr: string) {
if (wreq.m[128014]?.toString().includes("Trying to open a changelog for an invalid build number")) { const buildNumberMatch = factoryStr.match(/.concat\("(\d+?)"\)/);
const hardcodedGetBuildNumber = wreq(128014).b as () => number; if (buildNumberMatch == null) {
return -1;
if (typeof hardcodedGetBuildNumber === "function" && typeof hardcodedGetBuildNumber() === "number") {
return hardcodedGetBuildNumber();
}
} }
} catch { }
const moduleId = findModuleId("Trying to open a changelog for an invalid build number"); return Number(buildNumberMatch[1]);
if (moduleId == null) {
return -1;
} }
const exports = Object.values<ModuleExports>(wreq(moduleId)); const hardcodedFactoryStr = String(wreq.m[128014]);
if (exports.length !== 1 || typeof exports[0] !== "function") { if (hardcodedFactoryStr.includes("Trying to open a changelog for an invalid build number")) {
return -1; const hardcodedBuildNumber = matchBuildNumber(hardcodedFactoryStr);
if (hardcodedBuildNumber !== -1) {
return hardcodedBuildNumber;
}
} }
const buildNumber = exports[0](); const moduleFactory = findModuleFactory("Trying to open a changelog for an invalid build number");
return typeof buildNumber === "number" ? buildNumber : -1; return matchBuildNumber(String(moduleFactory));
} catch { } catch {
return -1; return -1;
} }
@ -122,12 +120,12 @@ define(Function.prototype, "m", {
return; return;
} }
patchThisInstance();
if (wreq == null && this.c != null) { if (wreq == null && this.c != null) {
logger.info("Main WebpackInstance found" + interpolateIfDefined` in ${fileName}` + ", initializing internal references to WebpackRequire"); logger.info("Main WebpackInstance found" + interpolateIfDefined` in ${fileName}` + ", initializing internal references to WebpackRequire");
_initWebpack(this as WebpackRequire); _initWebpack(this as WebpackRequire);
} }
patchThisInstance();
} }
}); });
@ -478,23 +476,23 @@ function patchFactory(moduleId: PropertyKey, originalFactory: AnyModuleFactory):
for (let i = 0; i < patches.length; i++) { for (let i = 0; i < patches.length; i++) {
const patch = patches[i]; const patch = patches[i];
const moduleMatches = typeof patch.find === "string" const buildNumber = getBuildNumber();
? code.includes(patch.find) const shouldCheckBuildNumber = buildNumber !== -1;
: (patch.find.global && (patch.find.lastIndex = 0), patch.find.test(code));
if (!moduleMatches) {
continue;
}
// Eager patches cannot retrieve the build number because this code runs before the module for it is loaded
const buildNumber = Settings.eagerPatches ? -1 : getBuildNumber();
const shouldCheckBuildNumber = !Settings.eagerPatches && buildNumber !== -1;
if ( if (
shouldCheckBuildNumber && shouldCheckBuildNumber &&
(patch.fromBuild != null && buildNumber < patch.fromBuild) || (patch.fromBuild != null && buildNumber < patch.fromBuild) ||
(patch.toBuild != null && buildNumber > patch.toBuild) (patch.toBuild != null && buildNumber > patch.toBuild)
) { ) {
patches.splice(i--, 1);
continue;
}
const moduleMatches = typeof patch.find === "string"
? code.includes(patch.find)
: (patch.find.global && (patch.find.lastIndex = 0), patch.find.test(code));
if (!moduleMatches) {
continue; continue;
} }
@ -536,7 +534,7 @@ function patchFactory(moduleId: PropertyKey, originalFactory: AnyModuleFactory):
} }
if (newCode === code) { if (newCode === code) {
if (!patch.noWarn) { if (!(patch.noWarn || replacement.noWarn)) {
logger.warn(`Patch by ${patch.plugin} had no effect (Module id is ${String(moduleId)}): ${replacement.match}`); logger.warn(`Patch by ${patch.plugin} had no effect (Module id is ${String(moduleId)}): ${replacement.match}`);
if (IS_DEV) { if (IS_DEV) {
logger.debug("Function Source:\n", code); logger.debug("Function Source:\n", code);