From 483bc13a31ab2ba878ff8d9002b0a8671a640ec8 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Mon, 29 Aug 2022 22:05:22 +0200 Subject: [PATCH] Finish rewrite --- README.md | 9 +++++++++ build.mjs | 3 ++- src/Vencord.ts | 8 +++----- src/api/MessageClicks.ts | 17 ++++++++++++++++ src/api/index.ts | 1 + src/globals.d.ts | 1 + src/plugins/STFU.ts | 10 +++++++++ src/plugins/apiMessageClicks.ts | 16 +++++++++++++++ src/plugins/bar.ts | 10 --------- src/plugins/clientInfo.ts | 17 ++++++++++++++++ src/plugins/experiments.ts | 14 +++++++++++++ src/plugins/foo.ts | 10 --------- src/plugins/messageActions.ts | 36 +++++++++++++++++++++++++++++++++ src/plugins/noTrack.ts | 31 ++++++++++++++++++++++++++++ src/utils/types.ts | 11 +++++++--- 15 files changed, 165 insertions(+), 29 deletions(-) create mode 100644 README.md create mode 100644 src/api/MessageClicks.ts create mode 100644 src/api/index.ts create mode 100644 src/plugins/STFU.ts create mode 100644 src/plugins/apiMessageClicks.ts delete mode 100644 src/plugins/bar.ts create mode 100644 src/plugins/clientInfo.ts create mode 100644 src/plugins/experiments.ts delete mode 100644 src/plugins/foo.ts create mode 100644 src/plugins/messageActions.ts create mode 100644 src/plugins/noTrack.ts diff --git a/README.md b/README.md new file mode 100644 index 000000000..574df7c40 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Vencord + +My own Discord Desktop mod :) + +## Features + +- Proper context isolation -> Works in newer Electron versions +- Inline patches: Patch Discord's code with regex replacements! See [the experiments plugin](src/plugins/experiments.ts) for an example. While being more complex, this is more powerful than monkey patching since you can patch only small parts of functions instead of fully replacing them, access non exported/local variables and even replace constants (like in the aforementioned experiments patch!) +- Custom Css: Manually edit `%appdata%/Vencord/settings/quickCss.css` / `~/.config/Vencord/settings/quickCss.css` with your favourite editor and the client will automatically apply your changes diff --git a/build.mjs b/build.mjs index 0993eaeed..2b1550ad7 100755 --- a/build.mjs +++ b/build.mjs @@ -97,7 +97,8 @@ await Promise.all([ globPlugins ], sourcemap: "inline", - watch + watch, + minify: true }) ]).then(res => { const took = performance.now() - begin; diff --git a/src/Vencord.ts b/src/Vencord.ts index 091421e12..e80413327 100644 --- a/src/Vencord.ts +++ b/src/Vencord.ts @@ -1,8 +1,6 @@ -import * as plugins from "./plugins"; -import * as WP from "./utils/webpack"; +export * as Plugins from "./plugins"; +export * as Webpack from "./utils/webpack"; +export * as Api from "./api"; import "./utils/patchWebpack"; import "./utils/quickCss"; - -export const Webpack = WP; -export const Plugins = plugins; \ No newline at end of file diff --git a/src/api/MessageClicks.ts b/src/api/MessageClicks.ts new file mode 100644 index 000000000..476896d85 --- /dev/null +++ b/src/api/MessageClicks.ts @@ -0,0 +1,17 @@ +type Listener = (message, channel, event) => void; + +const listeners = new Set(); + +export function _handleClick(message, channel, event) { + for (const listener of listeners) { + listener(message, channel, event); + } +} + +export function addListener(listener: Listener) { + listeners.add(listener); +} + +export function removeListener(listener: Listener) { + return listeners.delete(listener); +} \ No newline at end of file diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 000000000..6688927a6 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1 @@ +export * as MessageClicks from "./MessageClicks"; \ No newline at end of file diff --git a/src/globals.d.ts b/src/globals.d.ts index 02ea08808..131ec4eb3 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -10,6 +10,7 @@ declare global { push(chunk: any): any; pop(): any; }; + [k: PropertyKey]: any; } } diff --git a/src/plugins/STFU.ts b/src/plugins/STFU.ts new file mode 100644 index 000000000..63dd7ef82 --- /dev/null +++ b/src/plugins/STFU.ts @@ -0,0 +1,10 @@ +import definePlugin from "../utils/types"; + +export default definePlugin({ + name: "STFU", + description: "Disabled the fat warning in the DevTools console", + author: "Vendicated", + start() { + window.DiscordNative.window.setDevtoolsCallbacks(null, null); + } +}); \ No newline at end of file diff --git a/src/plugins/apiMessageClicks.ts b/src/plugins/apiMessageClicks.ts new file mode 100644 index 000000000..7155b943a --- /dev/null +++ b/src/plugins/apiMessageClicks.ts @@ -0,0 +1,16 @@ +import definePlugin from "../utils/types"; + +export default definePlugin({ + name: "MessageClicksApi", + description: "Api required by anything using message click actions", + author: "Vendicated", + patches: [{ + find: "if(e.altKey){", + replacement: { + match: /\.useClickMessage=function\((.{1,2}),(.{1,2})\).+?function\((.{1,2})\){/, + replace: (m, message, channel, event) => + // the message param is shadowed by the event param, so need to alias them + `${m.replace("{", `{var _msg=${message};var _chan=${channel};`)}Vencord.Api.MessageClicks._handleClick(_msg, _chan, ${event});` + } + }] +}); diff --git a/src/plugins/bar.ts b/src/plugins/bar.ts deleted file mode 100644 index 76d1a8fb7..000000000 --- a/src/plugins/bar.ts +++ /dev/null @@ -1,10 +0,0 @@ -import definePlugin from '../utils/types'; - -export default definePlugin({ - name: "bar", - description: "Just to test", - author: ["Vendicated"], - start() { - console.log("bar"); - } -}); \ No newline at end of file diff --git a/src/plugins/clientInfo.ts b/src/plugins/clientInfo.ts new file mode 100644 index 000000000..77cc70c7c --- /dev/null +++ b/src/plugins/clientInfo.ts @@ -0,0 +1,17 @@ +import definePlugin from "../utils/types"; + +export default definePlugin({ + name: "ClientInfo", + description: "Adds extra info to Client Info in settings", + author: "Vendicated", + patches: [{ + find: "default.versionHash", + replacement: { + match: /\w\.createElement.+?["']Host ["'].+?\):null/, + replace: m => { + const idx = m.indexOf("Host") - 1; + return `${m},${m.slice(0, idx)}"Vencord ".repeat(50),"1.0.0")," ")`; + } + } + }] +}); \ No newline at end of file diff --git a/src/plugins/experiments.ts b/src/plugins/experiments.ts new file mode 100644 index 000000000..9db2e0585 --- /dev/null +++ b/src/plugins/experiments.ts @@ -0,0 +1,14 @@ +import definePlugin from '../utils/types'; + +export default definePlugin({ + name: "Experiments", + author: "Vendicated", + description: "Enable Experiments", + patches: [{ + find: "Object.defineProperties(this,{isDeveloper", + replacement: { + match: /(?<={isDeveloper:\{[^}]+,get:function\(\)\{return )\w/, + replace: "true" + } + }] +}); diff --git a/src/plugins/foo.ts b/src/plugins/foo.ts deleted file mode 100644 index f365b31a8..000000000 --- a/src/plugins/foo.ts +++ /dev/null @@ -1,10 +0,0 @@ -import definePlugin from "../utils/types"; - -export default definePlugin({ - name: "foo", - description: "Just to test", - author: ["Vendicated"], - start() { - console.log("foo"); - } -}); \ No newline at end of file diff --git a/src/plugins/messageActions.ts b/src/plugins/messageActions.ts new file mode 100644 index 000000000..c2857cbd5 --- /dev/null +++ b/src/plugins/messageActions.ts @@ -0,0 +1,36 @@ +import { MessageClicks } from "../api"; +import definePlugin from "../utils/types"; +import { find, findByProps } from "../utils/webpack"; + +export default definePlugin({ + name: "MessageQuickActions", + description: "Quick Delete, Quick edit", + author: "Vendicated", + start() { + const { deleteMessage, startEditMessage } = findByProps("deleteMessage"); + const { can } = findByProps("can", "initialize"); + const { Permissions: { MANAGE_MESSAGES } } = find(m => m.Permissions?.MANAGE_MESSAGES); + const { getCurrentUser } = findByProps("getCurrentUser"); + + let isDeletePressed = false; + document.addEventListener("keydown", e => { + if (e.key === "Backspace") isDeletePressed = true; + }); + document.addEventListener("keyup", e => { + if (e.key === "Backspace") isDeletePressed = false; + }); + + MessageClicks.addListener((msg, chan, event) => { + const isMe = msg.author.id === getCurrentUser().id; + if (!isDeletePressed) { + if (isMe && event.detail >= 2) { + startEditMessage(chan.id, msg.id, msg.content); + event.preventDefault(); + } + } else if (isMe || can(MANAGE_MESSAGES, chan)) { + deleteMessage(chan.id, msg.id); + event.preventDefault(); + } + }); + } +}); \ No newline at end of file diff --git a/src/plugins/noTrack.ts b/src/plugins/noTrack.ts new file mode 100644 index 000000000..6d3a0ba92 --- /dev/null +++ b/src/plugins/noTrack.ts @@ -0,0 +1,31 @@ +import definePlugin from "../utils/types"; +import { findByProps } from "../utils/webpack"; + +const DO_NOTHING = () => void 0; + +export default definePlugin({ + name: "NoTrack", + description: "Disable Discord's tracking and crash reporting", + author: "Vendicated", + start() { + findByProps("getSuperPropertiesBase64", "track").track = DO_NOTHING; + findByProps("submitLiveCrashReport").submitLiveCrashReport = DO_NOTHING; + findByProps("AnalyticsActionHandlers").AnalyticsActionHandlers.handleTrack = DO_NOTHING; + + const sentry = window.__SENTRY__; + sentry.logger.disable(); + + sentry.hub.addBreadcrumb = DO_NOTHING; + sentry.hub.getClient().close(0); + sentry.hub.getScope().clear(); + + const c = console; + for (const method in c) { + if (c[method].__sentry_original__) + c[method] = c[method].__sentry_original__; + if (c[method].__REACT_DEVTOOLS_ORIGINAL_METHOD__?.__sentry_original__) + c[method].__REACT_DEVTOOLS_ORIGINAL_METHOD__ = c[method].__REACT_DEVTOOLS_ORIGINAL_METHOD__.__sentry_original__; + } + } + +}); \ No newline at end of file diff --git a/src/utils/types.ts b/src/utils/types.ts index 6268d2930..282ca0e4f 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -1,5 +1,5 @@ // exists to export default definePlugin({...}) -export default function definePlugin(p: Plugin) { +export default function definePlugin(p: PluginDef) { return p; } @@ -17,7 +17,12 @@ export interface Patch { export interface Plugin { name: string; description: string; - author: string[]; + author: string; start?(): void; patches?: Patch[]; -} \ No newline at end of file +} + +// @ts-ignore lole +interface PluginDef extends Plugin { + patches?: Omit[]; +} \ No newline at end of file