Skip to content
This repository has been archived by the owner on Jun 14, 2023. It is now read-only.

Commit

Permalink
Move desktop menu button patching code into an SMM service
Browse files Browse the repository at this point in the history
  • Loading branch information
coolavery committed Jul 31, 2022
1 parent 6a20d03 commit 955a955
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export class MenuInjectorDesktop implements MenuInjector {

libaryContainer.appendChild(menuContainer);

addModsButton(showMenuPage);
addModsButton(this.smm, showMenuPage);

// Make sure mods button gets shown
const interval = setInterval(() => {
Expand Down
18 changes: 13 additions & 5 deletions injected/src/menu-manager/desktop/mods-button.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { logoIcon } from '../../assets/assets';
import { patchExportFromContents } from '../../patch/module-utils';
import { hasClassContaining } from '../../patch/react';
import { SMM } from '../../smm';

export const addModsButton = async (onClick: () => void) => {
await patchExportFromContents({
const hasClassContaining = (substr: string, createElementArgs: any[]) => {
return (
createElementArgs.length >= 1 &&
createElementArgs[1] &&
createElementArgs[1].className &&
createElementArgs[1].className.includes(substr)
);
};

export const addModsButton = async (smm: SMM, onClick: () => void) => {
await smm.Patch.patchExportFromContents({
contents: [
'useState',
'useEffect',
Expand Down Expand Up @@ -56,7 +64,7 @@ export const addModsButton = async (onClick: () => void) => {
},
});

await patchExportFromContents({
await smm.Patch.patchExportFromContents({
contents: [
'useState',
'useEffect',
Expand Down
143 changes: 0 additions & 143 deletions injected/src/patch/module-utils.ts

This file was deleted.

11 changes: 0 additions & 11 deletions injected/src/patch/react.ts

This file was deleted.

113 changes: 113 additions & 0 deletions injected/src/services/patch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { uuidv4 } from '../util';
import { Service } from './service';

export class Patch extends Service {
private cachedExports: Record<string, string[]> = {};
private patches: Record<
string,
Record<
string,
{
callbacks: ((
origFunc: (...args: any[]) => any,
module: any,
...args: any[]
) => any)[];
}
>
> = {};

// modified from https://stackoverflow.com/a/70600070
private getModules() {
return new Promise<any>((resolve) => {
const id = uuidv4();
window.webpackJsonp.push([
id,
{
[id]: (...args: any[]) => {
resolve(args);
},
},
[[id]],
]);
});
}

private async getModuleExportsContaining(...contents: string[]) {
const modules = (await this.getModules())[2].c;
for (const module of Object.values<{ exports?: Record<string, any> }>(
modules
)) {
if (!module.exports) {
continue;
}

const keys = Object.keys(module.exports);

if (contents.every((content) => keys.includes(content))) {
return module.exports;
}
}
}

async patchExportFromContents({
contents,
export: exportName,
callback,
}: {
contents: string[];
export: string;
callback: (
origFunc: (...args: any[]) => any,
module: any,
...args: any[]
) => any;
}) {
let module: any | undefined;
let moduleId: string | undefined;

for (const [_moduleId, moduleContents] of Object.entries(
this.cachedExports
)) {
if (
contents.every((content) =>
Object.keys(moduleContents).includes(content)
)
) {
module = moduleContents;
moduleId = _moduleId;
break;
}
}

module ??= await this.getModuleExportsContaining(...contents);
moduleId ??= uuidv4();

if (!module) {
return undefined;
}

this.cachedExports[moduleId] = module;

this.patches[moduleId] ??= {};
if (!this.patches[moduleId][exportName]) {
this.patches[moduleId][exportName] = {
callbacks: [],
};

const origExport = module[exportName];
module[exportName] = (...args: any[]) => {
for (const cb of this.patches[moduleId!][exportName].callbacks) {
const res = cb(origExport, module, ...args);
if (res) {
return res;
}
}

return origExport(...args);
};
}

this.patches[moduleId][exportName].callbacks.push(callback);
}
}
3 changes: 3 additions & 0 deletions injected/src/smm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { FS } from './services/fs';
import { Inject } from './services/inject';
import { IPC } from './services/ipc';
import { Network } from './services/network';
import { Patch } from './services/patch';
import { Plugins } from './services/plugins';
import { Store } from './services/store';
import { Toast } from './services/toast';
Expand Down Expand Up @@ -121,6 +122,7 @@ export class SMM extends EventTarget {
readonly Store: Store;
readonly ButtonInterceptors: ButtonInterceptors;
readonly Apps: Apps;
readonly Patch: Patch;

readonly serverPort: string;

Expand Down Expand Up @@ -160,6 +162,7 @@ export class SMM extends EventTarget {
this.Store = new Store(this);
this.ButtonInterceptors = new ButtonInterceptors(this);
this.Apps = new Apps(this);
this.Patch = new Patch(this);

if (entry === 'library') {
this.MenuManager = new MenuManager(this);
Expand Down

0 comments on commit 955a955

Please sign in to comment.