Fix Vencord

This commit is contained in:
Vendicated 2023-04-04 21:09:47 +02:00
parent 2e6dfaa879
commit f092f434fe
No known key found for this signature in database
GPG Key ID: A1DC0CFB5615D905
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;