More work on the base
* Exported utilities in the `common` module * Added build tool to bundle the client. * Make injector, preload, client run * Add WIP inject script * Add our own packaging util.
This commit is contained in:
parent
73116fbd34
commit
a4ed32bb4d
12
package.json
12
package.json
|
@ -2,8 +2,14 @@
|
|||
"name": "betterdiscord",
|
||||
"version": "2.0.0",
|
||||
"description": "",
|
||||
"main": "./packages/injector/dist/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "pnpm build:injector && pnpm build:preload && pnpm build:preload",
|
||||
"build:injector": "node ./scripts/build.js prod injector",
|
||||
"build:preload": "node ./scripts/build.js prod preload",
|
||||
"build:client": "node ./scripts/build.js prod client",
|
||||
"build:packager": "node ./scripts/build.js prod packager"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
|
@ -12,6 +18,8 @@
|
|||
"@typescript-eslint/eslint-plugin": "^5.38.1",
|
||||
"@typescript-eslint/parser": "^5.38.1",
|
||||
"eslint": "^8.24.0",
|
||||
"typescript": "^4.8.4"
|
||||
"typescript": "^4.8.4",
|
||||
"esbuild": "^0.15.10",
|
||||
"esbuild-plugin-replace": "^1.3.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,14 @@
|
|||
"name": "@betterdiscord/client",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.ts",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "esbuild src/index.ts --bundle --outfile=dist/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@betterdiscord/common": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.15.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
console.log("Hello from @betterdiscord/client");
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"name": "@betterdiscord/common",
|
||||
"private": true
|
||||
}
|
||||
"private": true,
|
||||
"main": "src/index.ts"
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export * as IPCEvents from "./ipc";
|
|
@ -0,0 +1 @@
|
|||
export const GET_PRELOAD = "BD_GET_PRELOAD";
|
|
@ -0,0 +1,2 @@
|
|||
export * as Utilities from "./utils";
|
||||
export * from "./constants";
|
|
@ -34,4 +34,4 @@ export default function findInTree(tree: ObjectLiteral | null, searchFilter: Tre
|
|||
}
|
||||
}
|
||||
return tempReturn;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
export {default as clone} from "./clone";
|
||||
export {default as debounce} from "./debounce";
|
||||
export {default as extend} from "./extend";
|
||||
export {default as findInTree} from "./findintree";
|
||||
export {default as formatString} from "./format";
|
||||
export {default as Logger} from "./logger";
|
||||
export {default as memoizeObject} from "./memoize";
|
|
@ -2,8 +2,15 @@
|
|||
"name": "@betterdiscord/injector",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.ts",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "esbuild src/index.ts --bundle --outfile=dist/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@betterdiscord/common": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.15.10",
|
||||
"standalone-electron-types": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/// <reference types="standalone-electron-types" />
|
||||
|
||||
import BrowserWindowPatcher from "./patchers/browserwindow";
|
||||
import "./ipc";
|
||||
|
||||
if (!process.argv.includes("--vanilla")) {
|
||||
BrowserWindowPatcher.apply();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
import "./preload.ts";
|
|
@ -0,0 +1,6 @@
|
|||
import {ipcMain as IPC, BrowserWindow} from "electron/main";
|
||||
import {IPCEvents} from "@betterdiscord/common";
|
||||
|
||||
IPC.on(IPCEvents.GET_PRELOAD, event => {
|
||||
event.returnValue = (<any>BrowserWindow.fromWebContents(event.sender))?.__originalPreload ?? "NOT_FOUND";
|
||||
});
|
|
@ -0,0 +1,35 @@
|
|||
import electron from "electron/main";
|
||||
import path from "path";
|
||||
|
||||
const preloadPath = path.resolve(...<string[]>[
|
||||
__dirname, "..",
|
||||
process.env.DEVELOPMENT && "..",
|
||||
"preload", "dist", "index.js"
|
||||
].filter(Boolean));
|
||||
|
||||
class BrowserWindow extends electron.BrowserWindow {
|
||||
__originalPreload: string = "";
|
||||
|
||||
constructor(options: Electron.BrowserWindowConstructorOptions) {
|
||||
// @ts-expect-error
|
||||
if (!options || !options.webPreferences || !options.webPreferences.preload || !options.title) super(options);
|
||||
else {
|
||||
const originalPreload = <string>options.webPreferences.preload;
|
||||
|
||||
options.webPreferences.preload = preloadPath;
|
||||
|
||||
super(options);
|
||||
|
||||
this.__originalPreload = originalPreload;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default class BrowserWindowPatcher {
|
||||
public static apply(): void {
|
||||
const electronPath = require.resolve("electron");
|
||||
|
||||
delete require.cache[electronPath]?.exports;
|
||||
(<any>require.cache[electronPath]).exports = {...electron, BrowserWindow};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "packager",
|
||||
"description": "",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
import fs from "fs";
|
||||
import path from "path";
|
||||
import Bundle, {ArchiveEntry} from "./modules/bundle";
|
||||
import {Decoder, Encoder, concatBuffers, panic} from "./modules/utils";
|
||||
|
||||
export const pattern = [0x539, 0x45];
|
||||
|
||||
export const extractContents = (input: Buffer | Uint8Array) => {
|
||||
const view = new DataView(input.buffer);
|
||||
|
||||
if (view.getUint32(0) !== pattern[0] || view.getUint32(4) !== pattern[1]) {
|
||||
throw "Not a valid BD package. (pattern does not match)";
|
||||
}
|
||||
|
||||
const headLength = view.getUint32(8);
|
||||
const header = Decoder.decode(input.slice(0x10, 0x10 + headLength).buffer);
|
||||
|
||||
const head = JSON.parse(header);
|
||||
|
||||
return new Bundle(input.slice(0x10), head, headLength);
|
||||
};
|
||||
|
||||
export const create = (location: string) => {
|
||||
if (!fs.existsSync(location)) return null;
|
||||
|
||||
const bundle = (sub: string, list: ArchiveEntry, {files = [] as Buffer[], offset = 0} = {}): [Buffer[], ArchiveEntry, number] | undefined => {
|
||||
const stats = fs.statSync(sub);
|
||||
|
||||
if (stats.isFile()) {
|
||||
const content = fs.readFileSync(sub);
|
||||
|
||||
files.push(content);
|
||||
|
||||
list.files[path.basename(sub)] = {
|
||||
size: String(content.length),
|
||||
offset: String(offset)
|
||||
}
|
||||
|
||||
offset += content.length;
|
||||
|
||||
return [files, list, offset];
|
||||
}
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
if (sub !== location) {
|
||||
list = (<ArchiveEntry["files"]><unknown>list)[path.basename(sub)] = {files: {}};
|
||||
}
|
||||
|
||||
for (const file of fs.readdirSync(sub, {withFileTypes: true})) {
|
||||
const [, , newOffset] = bundle(path.join(sub, file.name), list, {
|
||||
files,
|
||||
offset
|
||||
}) as [never, never, number];
|
||||
|
||||
offset = newOffset;
|
||||
}
|
||||
|
||||
return [files, list, offset];
|
||||
}
|
||||
|
||||
panic(`Unknown dirent ${sub}`);
|
||||
};
|
||||
|
||||
const head = {files: {}};
|
||||
const [files] = bundle(location, head) as Array<Buffer[]>;
|
||||
const headerBuf = Encoder.encode(JSON.stringify(head));
|
||||
const fileBuf = concatBuffers(files.flat());
|
||||
const buffer = new Uint8Array(0x10);
|
||||
const view = new DataView(buffer.buffer);
|
||||
|
||||
view.setUint32(0, pattern[0]);
|
||||
view.setUint32(4, pattern[1]);
|
||||
view.setUint32(8, headerBuf.length);
|
||||
|
||||
return concatBuffers([
|
||||
buffer,
|
||||
headerBuf,
|
||||
fileBuf
|
||||
]);
|
||||
};
|
|
@ -0,0 +1,65 @@
|
|||
import {Decoder} from "./utils";
|
||||
|
||||
export type ArchiveFile = {
|
||||
size: string,
|
||||
offset: string
|
||||
};
|
||||
|
||||
export type ArchiveEntry = {
|
||||
files: {[key: string]: ArchiveEntry | ArchiveFile}
|
||||
};
|
||||
|
||||
export type ArchiveHeader = {
|
||||
files: ArchiveEntry
|
||||
};
|
||||
|
||||
export default class Bundle {
|
||||
buffer: Buffer | Uint8Array;
|
||||
offsets: ArchiveEntry;
|
||||
bodyOffset = 0;
|
||||
|
||||
constructor(buf: Buffer | Uint8Array, header: ArchiveEntry, bodyOffset: number) {
|
||||
this.bodyOffset = bodyOffset;
|
||||
this.offsets = header;
|
||||
this.buffer = buf;
|
||||
}
|
||||
|
||||
readDir(dest: string, raw?: false): string[];
|
||||
readDir(dest: string, raw?: true): ArchiveEntry["files"];
|
||||
readDir(dest = "", raw?: boolean): ArchiveEntry["files"] | string[] {
|
||||
const split = dest.split(/\\|\//);
|
||||
let current = this.offsets.files;
|
||||
|
||||
if (split.length > 1) for (const item of split) {
|
||||
if (!current) throw "No such file or directory.";
|
||||
if (item === ".") continue;
|
||||
|
||||
const keys = Object.keys(current);
|
||||
const target = keys.find(k => k.toLowerCase() === item.toLowerCase());
|
||||
|
||||
if (!target || !(<ArchiveEntry>current[target]).files) throw "ENOENT";
|
||||
|
||||
current = (<ArchiveEntry>current[target]).files;
|
||||
}
|
||||
|
||||
return raw ? current : Object.keys(current);
|
||||
}
|
||||
|
||||
readFile(dest = "", string?: boolean) {
|
||||
const split = dest.split(/\\|\//);
|
||||
const last = <string>split.pop();
|
||||
const file = <ArchiveFile>this.readDir(split.join("/"), true)[last];
|
||||
|
||||
if (!file) throw "No such file found.";
|
||||
|
||||
const offset = this.bodyOffset + Number(file.offset);
|
||||
|
||||
return string
|
||||
? Decoder.decode(this.buffer.subarray(offset, offset + Number(file.size)).buffer)
|
||||
: this.buffer.subarray(offset, offset + Number(file.size));
|
||||
}
|
||||
|
||||
hasFile(dest: string) {
|
||||
return !!this.readFile(dest);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
export const Decoder = new TextDecoder();
|
||||
export const Encoder = new TextEncoder();
|
||||
|
||||
export const panic = (message: any) => {throw "PANIC: " + message;};
|
||||
|
||||
export const concatBuffers = (list: (Buffer | Uint8Array)[], length?: number) => {
|
||||
if (typeof(length) === "undefined") {
|
||||
length = 0;
|
||||
for (const item of list) {
|
||||
if (!item.length) continue;
|
||||
length += item.length;
|
||||
}
|
||||
}
|
||||
|
||||
const buffer = new Uint8Array(length);
|
||||
let pos = 0;
|
||||
|
||||
for (const item of list) {
|
||||
buffer.set(item, pos);
|
||||
pos += item.length;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
|
@ -2,8 +2,14 @@
|
|||
"name": "@betterdiscord/preload",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.ts",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "esbuild src/index.ts --bundle --outfile=dist/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@betterdiscord/common": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.15.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import Client from "./modules/client";
|
||||
import DiscordPreload from "./modules/preload";
|
||||
|
||||
console.log("Hello from @betterdiscord/preload.");
|
||||
|
||||
Client.load();
|
||||
DiscordPreload.load();
|
||||
|
||||
window.require = require;
|
|
@ -0,0 +1,15 @@
|
|||
import {webFrame} from "electron/renderer";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
export default class Client {
|
||||
public static load(): void {
|
||||
const clientPath = path.resolve(...<string[]>[
|
||||
__dirname, "..",
|
||||
process.env.DEVELOPMENT && "..",
|
||||
"client", "dist", "index.js"
|
||||
].filter(Boolean));
|
||||
|
||||
webFrame.top?.executeJavaScript(fs.readFileSync(clientPath, "utf8"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import {ipcRenderer as IPC} from "electron/renderer";
|
||||
import {IPCEvents} from "@betterdiscord/common";
|
||||
|
||||
export default class DiscordPreload {
|
||||
public static load(): void {
|
||||
const originalPreload = IPC.sendSync(IPCEvents.GET_PRELOAD);
|
||||
|
||||
if (originalPreload !== "NOT_FOUND") {
|
||||
require(originalPreload);
|
||||
} else {
|
||||
console.error("[BetterDiscord~Preload] Original preload.js wasn't found.");
|
||||
}
|
||||
}
|
||||
}
|
317
pnpm-lock.yaml
317
pnpm-lock.yaml
|
@ -1,21 +1,77 @@
|
|||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
'@types/node': ^18.7.23
|
||||
'@typescript-eslint/eslint-plugin': ^5.38.1
|
||||
'@typescript-eslint/parser': ^5.38.1
|
||||
eslint: ^8.24.0
|
||||
typescript: ^4.8.4
|
||||
importers:
|
||||
|
||||
devDependencies:
|
||||
'@types/node': 18.7.23
|
||||
'@typescript-eslint/eslint-plugin': 5.38.1_c7qepppml3d4ahu5cnfwqe6ltq
|
||||
'@typescript-eslint/parser': 5.38.1_ypn2ylkkyfa5i233caldtndbqa
|
||||
eslint: 8.24.0
|
||||
typescript: 4.8.4
|
||||
.:
|
||||
specifiers:
|
||||
'@types/node': ^18.7.23
|
||||
'@typescript-eslint/eslint-plugin': ^5.38.1
|
||||
'@typescript-eslint/parser': ^5.38.1
|
||||
esbuild: ^0.15.10
|
||||
esbuild-plugin-replace: ^1.3.0
|
||||
eslint: ^8.24.0
|
||||
typescript: ^4.8.4
|
||||
devDependencies:
|
||||
'@types/node': 18.7.23
|
||||
'@typescript-eslint/eslint-plugin': 5.38.1_c7qepppml3d4ahu5cnfwqe6ltq
|
||||
'@typescript-eslint/parser': 5.38.1_ypn2ylkkyfa5i233caldtndbqa
|
||||
esbuild: 0.15.10
|
||||
esbuild-plugin-replace: 1.3.0
|
||||
eslint: 8.24.0
|
||||
typescript: 4.8.4
|
||||
|
||||
packages/client:
|
||||
specifiers:
|
||||
'@betterdiscord/common': workspace:*
|
||||
esbuild: ^0.15.10
|
||||
dependencies:
|
||||
'@betterdiscord/common': link:../common
|
||||
devDependencies:
|
||||
esbuild: 0.15.10
|
||||
|
||||
packages/common:
|
||||
specifiers: {}
|
||||
|
||||
packages/injector:
|
||||
specifiers:
|
||||
'@betterdiscord/common': workspace:*
|
||||
esbuild: ^0.15.10
|
||||
standalone-electron-types: ^1.0.0
|
||||
dependencies:
|
||||
'@betterdiscord/common': link:../common
|
||||
devDependencies:
|
||||
esbuild: 0.15.10
|
||||
standalone-electron-types: 1.0.0
|
||||
|
||||
packages/preload:
|
||||
specifiers:
|
||||
'@betterdiscord/common': workspace:*
|
||||
esbuild: ^0.15.10
|
||||
dependencies:
|
||||
'@betterdiscord/common': link:../common
|
||||
devDependencies:
|
||||
esbuild: 0.15.10
|
||||
|
||||
packages:
|
||||
|
||||
/@esbuild/android-arm/0.15.10:
|
||||
resolution: {integrity: sha512-FNONeQPy/ox+5NBkcSbYJxoXj9GWu8gVGJTVmUyoOCKQFDTrHVKgNSzChdNt0I8Aj/iKcsDf2r9BFwv+FSNUXg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-loong64/0.15.10:
|
||||
resolution: {integrity: sha512-w0Ou3Z83LOYEkwaui2M8VwIp+nLi/NA60lBLMvaJ+vXVMcsARYdEzLNE7RSm4+lSg4zq4d7fAVuzk7PNQ5JFgg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@eslint/eslintrc/1.3.2:
|
||||
resolution: {integrity: sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
@ -82,6 +138,10 @@ packages:
|
|||
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
|
||||
dev: true
|
||||
|
||||
/@types/node/18.11.18:
|
||||
resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==}
|
||||
dev: true
|
||||
|
||||
/@types/node/18.7.23:
|
||||
resolution: {integrity: sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg==}
|
||||
dev: true
|
||||
|
@ -341,6 +401,222 @@ packages:
|
|||
esutils: 2.0.3
|
||||
dev: true
|
||||
|
||||
/esbuild-android-64/0.15.10:
|
||||
resolution: {integrity: sha512-UI7krF8OYO1N7JYTgLT9ML5j4+45ra3amLZKx7LO3lmLt1Ibn8t3aZbX5Pu4BjWiqDuJ3m/hsvhPhK/5Y/YpnA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-android-arm64/0.15.10:
|
||||
resolution: {integrity: sha512-EOt55D6xBk5O05AK8brXUbZmoFj4chM8u3riGflLa6ziEoVvNjRdD7Cnp82NHQGfSHgYR06XsPI8/sMuA/cUwg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-64/0.15.10:
|
||||
resolution: {integrity: sha512-hbDJugTicqIm+WKZgp208d7FcXcaK8j2c0l+fqSJ3d2AzQAfjEYDRM3Z2oMeqSJ9uFxyj/muSACLdix7oTstRA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-arm64/0.15.10:
|
||||
resolution: {integrity: sha512-M1t5+Kj4IgSbYmunf2BB6EKLkWUq+XlqaFRiGOk8bmBapu9bCDrxjf4kUnWn59Dka3I27EiuHBKd1rSO4osLFQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-64/0.15.10:
|
||||
resolution: {integrity: sha512-KMBFMa7C8oc97nqDdoZwtDBX7gfpolkk6Bcmj6YFMrtCMVgoU/x2DI1p74DmYl7CSS6Ppa3xgemrLrr5IjIn0w==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-arm64/0.15.10:
|
||||
resolution: {integrity: sha512-m2KNbuCX13yQqLlbSojFMHpewbn8wW5uDS6DxRpmaZKzyq8Dbsku6hHvh2U+BcLwWY4mpgXzFUoENEf7IcioGg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-32/0.15.10:
|
||||
resolution: {integrity: sha512-guXrwSYFAvNkuQ39FNeV4sNkNms1bLlA5vF1H0cazZBOLdLFIny6BhT+TUbK/hdByMQhtWQ5jI9VAmPKbVPu1w==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-64/0.15.10:
|
||||
resolution: {integrity: sha512-jd8XfaSJeucMpD63YNMO1JCrdJhckHWcMv6O233bL4l6ogQKQOxBYSRP/XLWP+6kVTu0obXovuckJDcA0DKtQA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm/0.15.10:
|
||||
resolution: {integrity: sha512-6N8vThLL/Lysy9y4Ex8XoLQAlbZKUyExCWyayGi2KgTBelKpPgj6RZnUaKri0dHNPGgReJriKVU6+KDGQwn10A==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm64/0.15.10:
|
||||
resolution: {integrity: sha512-GByBi4fgkvZFTHFDYNftu1DQ1GzR23jws0oWyCfhnI7eMOe+wgwWrc78dbNk709Ivdr/evefm2PJiUBMiusS1A==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-mips64le/0.15.10:
|
||||
resolution: {integrity: sha512-BxP+LbaGVGIdQNJUNF7qpYjEGWb0YyHVSKqYKrn+pTwH/SiHUxFyJYSP3pqkku61olQiSBnSmWZ+YUpj78Tw7Q==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-ppc64le/0.15.10:
|
||||
resolution: {integrity: sha512-LoSQCd6498PmninNgqd/BR7z3Bsk/mabImBWuQ4wQgmQEeanzWd5BQU2aNi9mBURCLgyheuZS6Xhrw5luw3OkQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-riscv64/0.15.10:
|
||||
resolution: {integrity: sha512-Lrl9Cr2YROvPV4wmZ1/g48httE8z/5SCiXIyebiB5N8VT7pX3t6meI7TQVHw/wQpqP/AF4SksDuFImPTM7Z32Q==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-s390x/0.15.10:
|
||||
resolution: {integrity: sha512-ReP+6q3eLVVP2lpRrvl5EodKX7EZ1bS1/z5j6hsluAlZP5aHhk6ghT6Cq3IANvvDdscMMCB4QEbI+AjtvoOFpA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-netbsd-64/0.15.10:
|
||||
resolution: {integrity: sha512-iGDYtJCMCqldMskQ4eIV+QSS/CuT7xyy9i2/FjpKvxAuCzrESZXiA1L64YNj6/afuzfBe9i8m/uDkFHy257hTw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-openbsd-64/0.15.10:
|
||||
resolution: {integrity: sha512-ftMMIwHWrnrYnvuJQRJs/Smlcb28F9ICGde/P3FUTCgDDM0N7WA0o9uOR38f5Xe2/OhNCgkjNeb7QeaE3cyWkQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-plugin-replace/1.3.0:
|
||||
resolution: {integrity: sha512-i9v5FDfKUaxzpCLn+avq3I6lxJDL5616/tzP93/GFAI7REFwkMTy/pilEIvqlH8RTVpjlwJDOqUOYvJOf5jnXg==}
|
||||
dependencies:
|
||||
magic-string: 0.25.9
|
||||
dev: true
|
||||
|
||||
/esbuild-sunos-64/0.15.10:
|
||||
resolution: {integrity: sha512-mf7hBL9Uo2gcy2r3rUFMjVpTaGpFJJE5QTDDqUFf1632FxteYANffDZmKbqX0PfeQ2XjUDE604IcE7OJeoHiyg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-32/0.15.10:
|
||||
resolution: {integrity: sha512-ttFVo+Cg8b5+qHmZHbEc8Vl17kCleHhLzgT8X04y8zudEApo0PxPg9Mz8Z2cKH1bCYlve1XL8LkyXGFjtUYeGg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-64/0.15.10:
|
||||
resolution: {integrity: sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-arm64/0.15.10:
|
||||
resolution: {integrity: sha512-S+th4F+F8VLsHLR0zrUcG+Et4hx0RKgK1eyHc08kztmLOES8BWwMiaGdoW9hiXuzznXQ0I/Fg904MNbr11Nktw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild/0.15.10:
|
||||
resolution: {integrity: sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@esbuild/android-arm': 0.15.10
|
||||
'@esbuild/linux-loong64': 0.15.10
|
||||
esbuild-android-64: 0.15.10
|
||||
esbuild-android-arm64: 0.15.10
|
||||
esbuild-darwin-64: 0.15.10
|
||||
esbuild-darwin-arm64: 0.15.10
|
||||
esbuild-freebsd-64: 0.15.10
|
||||
esbuild-freebsd-arm64: 0.15.10
|
||||
esbuild-linux-32: 0.15.10
|
||||
esbuild-linux-64: 0.15.10
|
||||
esbuild-linux-arm: 0.15.10
|
||||
esbuild-linux-arm64: 0.15.10
|
||||
esbuild-linux-mips64le: 0.15.10
|
||||
esbuild-linux-ppc64le: 0.15.10
|
||||
esbuild-linux-riscv64: 0.15.10
|
||||
esbuild-linux-s390x: 0.15.10
|
||||
esbuild-netbsd-64: 0.15.10
|
||||
esbuild-openbsd-64: 0.15.10
|
||||
esbuild-sunos-64: 0.15.10
|
||||
esbuild-windows-32: 0.15.10
|
||||
esbuild-windows-64: 0.15.10
|
||||
esbuild-windows-arm64: 0.15.10
|
||||
dev: true
|
||||
|
||||
/escape-string-regexp/4.0.0:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -683,6 +959,12 @@ packages:
|
|||
yallist: 4.0.0
|
||||
dev: true
|
||||
|
||||
/magic-string/0.25.9:
|
||||
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
|
||||
dependencies:
|
||||
sourcemap-codec: 1.4.8
|
||||
dev: true
|
||||
|
||||
/merge2/1.4.1:
|
||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
@ -841,6 +1123,17 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/sourcemap-codec/1.4.8:
|
||||
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
|
||||
deprecated: Please use @jridgewell/sourcemap-codec instead
|
||||
dev: true
|
||||
|
||||
/standalone-electron-types/1.0.0:
|
||||
resolution: {integrity: sha512-0HOi/tlTz3mjWhsAz4uRbpQcHMZ+ifj1JzWW9nugykOHClBBG77ps8QinrzX1eow4Iw2pnC+RFaSYRgufF4BOg==}
|
||||
dependencies:
|
||||
'@types/node': 18.11.18
|
||||
dev: true
|
||||
|
||||
/strip-ansi/6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
const {build} = require("esbuild");
|
||||
const {replace} = require("esbuild-plugin-replace");
|
||||
const path = require("path");
|
||||
|
||||
const [mode, packagesToBuild] = process.argv.slice(2);
|
||||
const isDevelopment = mode !== "prod";
|
||||
|
||||
const packages = packagesToBuild ? packagesToBuild.split(",") : ["packager", "injector", "preload", "client"];
|
||||
|
||||
const buildPackage = id => {
|
||||
const base = path.resolve(process.cwd(), "packages", id);
|
||||
|
||||
/**@type {import("esbuild").BuildOptions} */
|
||||
const config = {
|
||||
entryPoints: [path.resolve(base, "src", "index.ts")],
|
||||
bundle: true,
|
||||
external: require("module").builtinModules.concat("electron"),
|
||||
outfile: path.resolve(base, "dist", "index.js"),
|
||||
format: id === "client" ? "iife" : "cjs",
|
||||
watch: isDevelopment,
|
||||
minify: !isDevelopment,
|
||||
plugins: [
|
||||
replace({
|
||||
"process.env.DEVELOPMENT": JSON.stringify(isDevelopment)
|
||||
})
|
||||
],
|
||||
keepNames: true
|
||||
};
|
||||
|
||||
return build(config);
|
||||
};
|
||||
|
||||
const label = `Built ${packages.length} packages in`;
|
||||
|
||||
console.clear();
|
||||
console.time(label);
|
||||
Promise.all(packages.map(buildPackage))
|
||||
.then(() => {
|
||||
console.timeEnd(label);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Build failed:", err);
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
// TODO: Make it work with release builds.
|
||||
|
||||
const args = process.argv;
|
||||
const releaseInput = /*useBdRelease ? args[3] && args[3].toLowerCase() : */args[2] && args[2].toLowerCase();
|
||||
const release = releaseInput === "canary" ? "Discord Canary" : releaseInput === "ptb" ? "Discord PTB" : "Discord";
|
||||
const bdPath = /*useBdRelease ?*/ path.resolve(__dirname, "..")/* : path.resolve(__dirname, "..", "dist")*/;
|
||||
const discordPath = (function() {
|
||||
let resourcePath = "";
|
||||
if (process.platform === "win32") {
|
||||
const basedir = path.join(process.env.LOCALAPPDATA, release.replace(/ /g, ""));
|
||||
if (!fs.existsSync(basedir)) throw new Error(`Cannot find directory for ${release}`);
|
||||
const version = fs.readdirSync(basedir).filter(f => fs.lstatSync(path.join(basedir, f)).isDirectory() && f.split(".").length > 1).sort().reverse()[0];
|
||||
// To account for discord_desktop_core-1 or any other number
|
||||
const coreWrap = fs.readdirSync(path.join(basedir, version, "modules")).filter(e => e.indexOf("discord_desktop_core") === 0).sort().reverse()[0];
|
||||
resourcePath = path.join(basedir, version, "modules", coreWrap, "discord_desktop_core");
|
||||
}
|
||||
else {
|
||||
let userData = process.env.XDG_CONFIG_HOME ? process.env.XDG_CONFIG_HOME : path.join(process.env.HOME, ".config");
|
||||
if (process.platform === "darwin") userData = path.join(process.env.HOME, "Library", "Application Support");
|
||||
const basedir = path.join(userData, release.toLowerCase().replace(" ", ""));
|
||||
if (!fs.existsSync(basedir)) return "";
|
||||
const version = fs.readdirSync(basedir).filter(f => fs.lstatSync(path.join(basedir, f)).isDirectory() && f.split(".").length > 1).sort().reverse()[0];
|
||||
if (!version) return "";
|
||||
resourcePath = path.join(basedir, version, "modules", "discord_desktop_core");
|
||||
}
|
||||
|
||||
if (fs.existsSync(resourcePath)) return resourcePath;
|
||||
return "";
|
||||
})();
|
||||
|
||||
if (!fs.existsSync(discordPath)) throw new Error(`Cannot find directory for ${release}`);
|
||||
|
||||
const indexJs = path.join(discordPath, "index.js");
|
||||
if (fs.existsSync(indexJs)) fs.unlinkSync(indexJs);
|
||||
|
||||
fs.writeFileSync(indexJs, `require(${JSON.stringify(bdPath)});\nmodule.exports = require("./core.asar");`);
|
||||
|
||||
console.log(`Injection successful, please restart ${release}.`);
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
/* Language and Environment */
|
||||
"target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"module": "esNext",
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
"jsx": "react-jsx", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
|
@ -42,4 +45,4 @@
|
|||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
},
|
||||
// "include": ["./src/types.ts"]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue