Fix Vencord
This commit is contained in:
parent
2e6dfaa879
commit
f092f434fe
12 changed files with 42 additions and 141 deletions
|
@ -21,8 +21,7 @@ import "./settingsStyles.css";
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { handleComponentFailed } from "@components/handleComponentFailed";
|
import { handleComponentFailed } from "@components/handleComponentFailed";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { Forms, SettingsRouter, TabBar, Text } from "@webpack/common";
|
||||||
import { Forms, SettingsRouter, Text } from "@webpack/common";
|
|
||||||
|
|
||||||
import BackupRestoreTab from "./BackupRestoreTab";
|
import BackupRestoreTab from "./BackupRestoreTab";
|
||||||
import PluginsTab from "./PluginsTab";
|
import PluginsTab from "./PluginsTab";
|
||||||
|
@ -32,8 +31,6 @@ import VencordSettings from "./VencordTab";
|
||||||
|
|
||||||
const cl = classNameFactory("vc-settings-");
|
const cl = classNameFactory("vc-settings-");
|
||||||
|
|
||||||
const TabBar = findByCodeLazy('[role="tab"][aria-disabled="false"]');
|
|
||||||
|
|
||||||
interface SettingsProps {
|
interface SettingsProps {
|
||||||
tab: string;
|
tab: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ if (IS_VENCORD_DESKTOP || !IS_VANILLA) {
|
||||||
case "renderer.js.map":
|
case "renderer.js.map":
|
||||||
case "preload.js.map":
|
case "preload.js.map":
|
||||||
case "patcher.js.map": // doubt
|
case "patcher.js.map": // doubt
|
||||||
|
case "main.js.map":
|
||||||
cb(join(__dirname, url));
|
cb(join(__dirname, url));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a modification for Discord's desktop app
|
|
||||||
* Copyright (c) 2022 Vendicated and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { migratePluginSettings } from "@api/settings";
|
|
||||||
import { Devs } from "@utils/constants";
|
|
||||||
import definePlugin from "@utils/types";
|
|
||||||
|
|
||||||
// duplicate values have multiple branches with different types. Just include all to be safe
|
|
||||||
const nameMap = {
|
|
||||||
radio: "MenuRadioItem",
|
|
||||||
separator: "MenuSeparator",
|
|
||||||
checkbox: "MenuCheckboxItem",
|
|
||||||
groupstart: "MenuGroup",
|
|
||||||
|
|
||||||
control: "MenuControlItem",
|
|
||||||
compositecontrol: "MenuControlItem",
|
|
||||||
|
|
||||||
item: "MenuItem",
|
|
||||||
customitem: "MenuItem",
|
|
||||||
};
|
|
||||||
|
|
||||||
migratePluginSettings("MenuItemDeobfuscatorAPI", "MenuItemDeobfuscatorApi");
|
|
||||||
export default definePlugin({
|
|
||||||
name: "MenuItemDeobfuscatorAPI",
|
|
||||||
description: "Deobfuscates Discord's Menu Item module",
|
|
||||||
authors: [Devs.Ven],
|
|
||||||
patches: [
|
|
||||||
{
|
|
||||||
find: '"Menu API',
|
|
||||||
replacement: {
|
|
||||||
match: /function.{0,80}type===(\i)\).{0,50}navigable:.+?Menu API/s,
|
|
||||||
replace: (m, mod) => {
|
|
||||||
let nicenNames = "";
|
|
||||||
const redefines = [] as string[];
|
|
||||||
// if (t.type === m.MenuItem)
|
|
||||||
const typeCheckRe = /\(.{1,3}\.type===(.{1,5})\)/g;
|
|
||||||
// push({type:"item"})
|
|
||||||
const pushTypeRe = /type:"(\w+)"/g;
|
|
||||||
|
|
||||||
let typeMatch: RegExpExecArray | null;
|
|
||||||
// for each if (t.type === ...)
|
|
||||||
while ((typeMatch = typeCheckRe.exec(m)) !== null) {
|
|
||||||
// extract the current menu item
|
|
||||||
const item = typeMatch[1];
|
|
||||||
// Set the starting index of the second regex to that of the first to start
|
|
||||||
// matching from after the if
|
|
||||||
pushTypeRe.lastIndex = typeCheckRe.lastIndex;
|
|
||||||
// extract the first type: "..."
|
|
||||||
const type = pushTypeRe.exec(m)?.[1];
|
|
||||||
if (type && type in nameMap) {
|
|
||||||
const name = nameMap[type];
|
|
||||||
nicenNames += `Object.defineProperty(${item},"name",{value:"${name}"});`;
|
|
||||||
redefines.push(`${name}:${item}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (redefines.length < 6) {
|
|
||||||
console.warn("[ApiMenuItemDeobfuscator] Expected to at least remap 6 items, only remapped", redefines.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge all our redefines with the actual module
|
|
||||||
return `${nicenNames}Object.assign(${mod},{${redefines.join(",")}});${m}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
|
@ -45,6 +45,13 @@ export default definePlugin({
|
||||||
replace: "true",
|
replace: "true",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
find: ".colorPickerFooter",
|
||||||
|
replacement: {
|
||||||
|
match: /function (\i).{0,200}\.colorPickerFooter/,
|
||||||
|
replace: "$self.ColorPicker=$1;$&"
|
||||||
|
}
|
||||||
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
options: {
|
options: {
|
||||||
|
|
|
@ -238,7 +238,7 @@ export default definePlugin({
|
||||||
name: "EmoteCloner",
|
name: "EmoteCloner",
|
||||||
description: "Adds a Clone context menu item to emotes to clone them your own server",
|
description: "Adds a Clone context menu item to emotes to clone them your own server",
|
||||||
authors: [Devs.Ven, Devs.Nuckyz],
|
authors: [Devs.Ven, Devs.Nuckyz],
|
||||||
dependencies: ["MenuItemDeobfuscatorAPI", "ContextMenuAPI"],
|
dependencies: ["ContextMenuAPI"],
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
addContextMenuPatch("message", messageContextMenuPatch);
|
addContextMenuPatch("message", messageContextMenuPatch);
|
||||||
|
|
|
@ -76,7 +76,7 @@ export default definePlugin({
|
||||||
name: "MessageLogger",
|
name: "MessageLogger",
|
||||||
description: "Temporarily logs deleted and edited messages.",
|
description: "Temporarily logs deleted and edited messages.",
|
||||||
authors: [Devs.rushii, Devs.Ven],
|
authors: [Devs.rushii, Devs.Ven],
|
||||||
dependencies: ["ContextMenuAPI", "MenuItemDeobfuscatorAPI"],
|
dependencies: ["ContextMenuAPI"],
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
addDeleteStyle();
|
addDeleteStyle();
|
||||||
|
|
|
@ -76,7 +76,7 @@ export default definePlugin({
|
||||||
name: "ReverseImageSearch",
|
name: "ReverseImageSearch",
|
||||||
description: "Adds ImageSearch to image context menus",
|
description: "Adds ImageSearch to image context menus",
|
||||||
authors: [Devs.Ven, Devs.Nuckyz],
|
authors: [Devs.Ven, Devs.Nuckyz],
|
||||||
dependencies: ["MenuItemDeobfuscatorAPI", "ContextMenuAPI"],
|
dependencies: ["ContextMenuAPI"],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".Messages.MESSAGE_ACTIONS_MENU_LABEL",
|
find: ".Messages.MESSAGE_ACTIONS_MENU_LABEL",
|
||||||
|
|
|
@ -39,7 +39,6 @@ export default definePlugin({
|
||||||
name: "SpotifyControls",
|
name: "SpotifyControls",
|
||||||
description: "Spotify Controls",
|
description: "Spotify Controls",
|
||||||
authors: [Devs.Ven, Devs.afn, Devs.KraXen72],
|
authors: [Devs.Ven, Devs.afn, Devs.KraXen72],
|
||||||
dependencies: ["MenuItemDeobfuscatorAPI"],
|
|
||||||
options: {
|
options: {
|
||||||
hoverControls: {
|
hoverControls: {
|
||||||
description: "Show controls on hover",
|
description: "Show controls on hover",
|
||||||
|
|
|
@ -35,8 +35,6 @@ export default definePlugin({
|
||||||
authors: [Devs.Ven],
|
authors: [Devs.Ven],
|
||||||
description: "Makes Avatars/Banners in user profiles clickable, and adds Guild Context Menu Entries to View Banner/Icon.",
|
description: "Makes Avatars/Banners in user profiles clickable, and adds Guild Context Menu Entries to View Banner/Icon.",
|
||||||
|
|
||||||
dependencies: ["MenuItemDeobfuscatorAPI"],
|
|
||||||
|
|
||||||
openImage(url: string) {
|
openImage(url: string) {
|
||||||
const u = new URL(url);
|
const u = new URL(url);
|
||||||
u.searchParams.set("size", "512");
|
u.searchParams.set("size", "512");
|
||||||
|
|
|
@ -17,40 +17,37 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// eslint-disable-next-line path-alias/no-relative
|
// eslint-disable-next-line path-alias/no-relative
|
||||||
import { filters, findByPropsLazy } from "../webpack";
|
import { filters, findByPropsLazy, waitFor } from "@webpack";
|
||||||
|
|
||||||
import { waitForComponent } from "./internal";
|
import { waitForComponent } from "./internal";
|
||||||
import * as t from "./types/components";
|
import * as t from "./types/components";
|
||||||
|
|
||||||
export const Forms = {
|
export let Forms = {} as {
|
||||||
FormTitle: waitForComponent<t.FormTitle>("FormTitle", filters.byCode("errorSeparator")),
|
FormTitle: t.FormTitle,
|
||||||
FormSection: waitForComponent<t.FormSection>("FormSection", filters.byCode("titleClassName", "sectionTitle")),
|
FormSection: t.FormSection,
|
||||||
FormDivider: waitForComponent<t.FormDivider>("FormDivider", m => {
|
FormDivider: t.FormDivider,
|
||||||
if (typeof m !== "function") return false;
|
FormText: t.FormText,
|
||||||
const s = m.toString();
|
|
||||||
return s.length < 200 && s.includes(".divider");
|
|
||||||
}),
|
|
||||||
FormText: waitForComponent<t.FormText>("FormText", m => m.Types?.INPUT_PLACEHOLDER),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Card = waitForComponent<t.Card>("Card", m => m.Types?.PRIMARY && m.defaultProps);
|
export let Card: t.Card;
|
||||||
export const Button = waitForComponent<t.Button>("Button", ["Hovers", "Looks", "Sizes"]);
|
export let Button: t.Button;
|
||||||
export const Switch = waitForComponent<t.Switch>("Switch", filters.byCode("tooltipNote", "ringTarget"));
|
export let Switch: t.Switch;
|
||||||
export const Tooltip = waitForComponent<t.Tooltip>("Tooltip", filters.byCode("shouldShowTooltip:!1", "clickableOnMobile||"));
|
export let Tooltip: t.Tooltip;
|
||||||
|
export let TextInput: t.TextInput;
|
||||||
|
export let TextArea: t.TextArea;
|
||||||
|
export let Text: t.Text;
|
||||||
|
export let Select: t.Select;
|
||||||
|
export let SearchableSelect: t.SearchableSelect;
|
||||||
|
export let Slider: t.Slider;
|
||||||
|
export let ButtonLooks: t.ButtonLooks;
|
||||||
|
export let TabBar: any;
|
||||||
|
|
||||||
export const Timestamp = waitForComponent<t.Timestamp>("Timestamp", filters.byCode(".Messages.MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL.format"));
|
export const Timestamp = waitForComponent<t.Timestamp>("Timestamp", filters.byCode(".Messages.MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL.format"));
|
||||||
export const TextInput = waitForComponent<t.TextInput>("TextInput", ["defaultProps", "Sizes", "contextType"]);
|
|
||||||
export const TextArea = waitForComponent<t.TextArea>("TextArea", filters.byCode("handleSetRef", "textArea"));
|
|
||||||
export const Text = waitForComponent<t.Text>("Text", m => {
|
|
||||||
if (typeof m !== "function") return false;
|
|
||||||
const s = m.toString();
|
|
||||||
return (s.length < 1500 && s.includes("data-text-variant") && s.includes("always-white"));
|
|
||||||
});
|
|
||||||
export const Select = waitForComponent<t.Select>("Select", filters.byCode("optionClassName", "popoutPosition", "autoFocus", "maxVisibleItems"));
|
|
||||||
const searchableSelectFilter = filters.byCode("autoFocus", ".Messages.SELECT");
|
|
||||||
export const SearchableSelect = waitForComponent<t.SearchableSelect>("SearchableSelect", m =>
|
|
||||||
m.render && searchableSelectFilter(m.render)
|
|
||||||
);
|
|
||||||
export const Slider = waitForComponent<t.Slider>("Slider", filters.byCode("closestMarkerIndex", "stickToMarkers"));
|
|
||||||
export const Flex = waitForComponent<t.Flex>("Flex", ["Justify", "Align", "Wrap"]);
|
export const Flex = waitForComponent<t.Flex>("Flex", ["Justify", "Align", "Wrap"]);
|
||||||
|
|
||||||
export const ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent") as Record<string, string>;
|
export const ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent") as Record<string, string>;
|
||||||
export const ButtonLooks: t.ButtonLooks = findByPropsLazy("BLANK", "FILLED", "INVERTED");
|
|
||||||
|
waitFor("FormItem", m => {
|
||||||
|
({ Card, Button, FormSwitch: Switch, Tooltip, TextInput, TextArea, Text, Select, SearchableSelect, Slider, ButtonLooks, TabBar } = m);
|
||||||
|
Forms = m;
|
||||||
|
});
|
||||||
|
|
|
@ -16,32 +16,14 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { proxyLazy } from "@utils/proxyLazy";
|
|
||||||
|
|
||||||
// eslint-disable-next-line path-alias/no-relative
|
// eslint-disable-next-line path-alias/no-relative
|
||||||
import { filters, mapMangledModule, mapMangledModuleLazy } from "../webpack";
|
import { filters, mapMangledModuleLazy, waitFor } from "../webpack";
|
||||||
import type * as t from "./types/menu";
|
import type * as t from "./types/menu";
|
||||||
|
|
||||||
export const Menu: t.Menu = proxyLazy(() => {
|
export let Menu = {} as t.Menu;
|
||||||
const hasDeobfuscator = Vencord.Settings.plugins.MenuItemDeobfuscatorAPI.enabled;
|
|
||||||
const menuItems = ["MenuSeparator", "MenuGroup", "MenuItem", "MenuCheckboxItem", "MenuRadioItem", "MenuControlItem"];
|
|
||||||
|
|
||||||
const map = mapMangledModule("♫ ⊂(。◕‿‿◕。⊂) ♪", {
|
waitFor("MenuItem", m => Menu = m);
|
||||||
ContextMenu: filters.byCode("getContainerProps"),
|
|
||||||
...Object.fromEntries((hasDeobfuscator ? menuItems : []).map(s => [s, (m: any) => m.name === s]))
|
|
||||||
}) as t.Menu;
|
|
||||||
|
|
||||||
if (!hasDeobfuscator) {
|
|
||||||
for (const m of menuItems)
|
|
||||||
Object.defineProperty(map, m, {
|
|
||||||
get() {
|
|
||||||
throw new Error("MenuItemDeobfuscator must be enabled to use this.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ContextMenu: t.ContextMenuApi = mapMangledModuleLazy('type:"CONTEXT_MENU_OPEN"', {
|
export const ContextMenu: t.ContextMenuApi = mapMangledModuleLazy('type:"CONTEXT_MENU_OPEN"', {
|
||||||
open: filters.byCode("stopPropagation"),
|
open: filters.byCode("stopPropagation"),
|
||||||
|
|
|
@ -109,6 +109,8 @@ export const find = traceFunction("find", function find(filter: FilterFn, getDef
|
||||||
if (!isWaitFor) {
|
if (!isWaitFor) {
|
||||||
const err = new Error("Didn't find module matching this filter");
|
const err = new Error("Didn't find module matching this filter");
|
||||||
if (IS_DEV) {
|
if (IS_DEV) {
|
||||||
|
logger.error(err);
|
||||||
|
logger.error(filter);
|
||||||
if (!devToolsOpen)
|
if (!devToolsOpen)
|
||||||
// Strict behaviour in DevBuilds to fail early and make sure the issue is found
|
// Strict behaviour in DevBuilds to fail early and make sure the issue is found
|
||||||
throw err;
|
throw err;
|
||||||
|
|
Loading…
Reference in a new issue