Skip to content
This repository has been archived by the owner on May 26, 2024. It is now read-only.

Commit

Permalink
Proper unpatching
Browse files Browse the repository at this point in the history
  • Loading branch information
pylixonly committed Jan 13, 2024
1 parent a9372c0 commit 7b38196
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 70 deletions.
2 changes: 1 addition & 1 deletion build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ console.log(`Building with commit hash "${commitHash}", isRelease=${isRelease}`)

// import commitHash from "~commit-hash";
const constantsMap = {
"commit-hash": () => JSON.parse(commitHash),
"commit-hash": () => JSON.stringify(commitHash),
"module-definition-hash": async () => {
const defs = await readFile("src/internal-metro/requireDef.ts");
return JSON.stringify(createHash("sha256").update(defs).digest("hex"));
Expand Down
35 changes: 14 additions & 21 deletions src/core/api/Patcher.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// this is very horrid
import { waitForModule } from "@metro";
import { after, before, instead } from "spitroast";

type Unpatcher = () => (void | boolean);
Expand All @@ -14,6 +15,7 @@ export default class Patcher {
identifier: string;
patches: Unpatcher[] = [];
stopped = false;
__contextedPatches?: Unpatcher[] = void 0;

constructor(identifier: string) {
if (!identifier || typeof identifier !== "string") {
Expand All @@ -32,38 +34,29 @@ export default class Patcher {
after = <T>(parent: NonPrimitive<T>, method: string, patch: AfterCallback) => this.addUnpatcher(after(method, parent, patch));
instead = <T>(parent: NonPrimitive<T>, method: string, patch: InsteadCallback) => this.addUnpatcher(instead(method, parent, patch));

// private waitAndPatch<P extends "before" | "after" | "instead">(
// patchType: P,
// filter: FilterFn,
// method: string,
// patch: Parameters<typeof Patcher.prototype[typeof patchType]>[2],
// ) {
// let unpatch: Unpatcher;
// const unwaiter = waitForModule(filter, module => {
// if (this.stopped) return false;
// unpatch = this[patchType](module, method, <any>patch);
// });
waitAndPatch = (name: string, callback: (exports: any, module: any, id: number) => void) => {
const patches = new Array<Unpatcher>;
const cancelWait = waitForModule(name, (exp, m, id) => {
this.__contextedPatches = patches;
callback(exp, m, id);
this.__contextedPatches = undefined;
});

// return () => (this.addUnpatcher(unwaiter), unpatch());
// }

// patch = (filter: FilterFn) => ({
// before: (method: string, patch: BeforeCallback) => this.waitAndPatch("before", filter, method, patch),
// after: (method: string, patch: AfterCallback) => this.waitAndPatch("after", filter, method, patch),
// instead: (method: string, patch: InsteadCallback) => this.waitAndPatch("instead", filter, method, patch),
// });
return () => (cancelWait(), patches.forEach(p => p?.()));
};

addUnpatcher = (callback: Unpatcher) => {
if (this.stopped) return () => false;
if (typeof callback !== "function") {
throw new Error("Unpatcher must be a function");
}

this.__contextedPatches?.push(callback);
this.patches.push(callback);
return callback;
};

unpatchAllAndStop() {
unpatchAllAndStop = () => {
let success = true;
this.stopped = true;

Expand All @@ -77,5 +70,5 @@ export default class Patcher {

patchesInstances.delete(this.identifier);
return success;
}
};
}
4 changes: 3 additions & 1 deletion src/core/patches/experiments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const ExperimentStore = requireMetroDefaultLazy("ExperimentStore");

export default async function patchExperiments() {
try {
FluxDispatcher.subscribe("CONNECTION_OPEN", () => {
const cancel = FluxDispatcher.subscribe("CONNECTION_OPEN", () => {
UserStore.getCurrentUser().flags |= 1;
UserStore._dispatcher._actionHandlers
._computeOrderedActionHandlers("OVERLAY_INITIALIZE")
Expand All @@ -17,6 +17,8 @@ export default async function patchExperiments() {
});
});
});

return () => cancel();
} catch (err) {
console.error("An error occurred while patching experiments", err);
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/patches/idle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ export default async function patchIdle() {
}
});

return patcher.unpatchAllAndStop;
return () => patcher.unpatchAllAndStop();
}
7 changes: 3 additions & 4 deletions src/core/patches/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Good luck reading this!
import Patcher from "@api/Patcher";
import { waitForModule } from "@metro";
import { I18n, NavigationNative, TabsNavigationRef } from "@metro/common";
import { lazyNavigate } from "@utils";
import { resolveAssets } from "@utils/assets";
Expand All @@ -16,7 +15,7 @@ const icons = resolveAssets({

// @ts-expect-error
export const sections = window.__pyoncord_sections_patch = {
[`Pyoncord (${commitHash})`.trimEnd()]: [
[`Pyoncord (${commitHash})`]: [
["PYONCORD", "Pyoncord", () => import("@ui/screens/General"), icons.Discord],
["PYONCORD_PLUGINS", "Plugins", () => import("@ui/screens/Plugins"), icons.Wrench]
]
Expand All @@ -36,7 +35,7 @@ const CustomPageRenderer = React.memo(() => {
});

export default function patchSettings() {
waitForModule("SettingConstants", module => {
patcher.waitAndPatch("SettingConstants", module => {
module.SETTING_RENDERER_CONFIG.PYONCORD_CUSTOM_PAGE = {
type: "route",
title: () => "Blah?",
Expand All @@ -62,7 +61,7 @@ export default function patchSettings() {
}
});

waitForModule("modules/main_tabs_v2/native/settings/renderer/SettingListRenderer.tsx", module => {
patcher.waitAndPatch("modules/main_tabs_v2/native/settings/renderer/SettingListRenderer.tsx", module => {
patcher.before(module.SearchableSettingsList, "type", ([{ sections: res }]) => {
if (res.__pyonMarkDirty) return;
res.__pyonMarkDirty = true;
Expand Down
42 changes: 0 additions & 42 deletions src/core/patches/theme.ts

This file was deleted.

0 comments on commit 7b38196

Please sign in to comment.