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 ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { handleComponentFailed } from "@components/handleComponentFailed";
|
||||
import { findByCodeLazy } from "@webpack";
|
||||
import { Forms, SettingsRouter, Text } from "@webpack/common";
|
||||
import { Forms, SettingsRouter, TabBar, Text } from "@webpack/common";
|
||||
|
||||
import BackupRestoreTab from "./BackupRestoreTab";
|
||||
import PluginsTab from "./PluginsTab";
|
||||
|
@ -32,8 +31,6 @@ import VencordSettings from "./VencordTab";
|
|||
|
||||
const cl = classNameFactory("vc-settings-");
|
||||
|
||||
const TabBar = findByCodeLazy('[role="tab"][aria-disabled="false"]');
|
||||
|
||||
interface SettingsProps {
|
||||
tab: string;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ if (IS_VENCORD_DESKTOP || !IS_VANILLA) {
|
|||
case "renderer.js.map":
|
||||
case "preload.js.map":
|
||||
case "patcher.js.map": // doubt
|
||||
case "main.js.map":
|
||||
cb(join(__dirname, url));
|
||||
break;
|
||||
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",
|
||||
},
|
||||
},
|
||||
{
|
||||
find: ".colorPickerFooter",
|
||||
replacement: {
|
||||
match: /function (\i).{0,200}\.colorPickerFooter/,
|
||||
replace: "$self.ColorPicker=$1;$&"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
options: {
|
||||
|
|
|
@ -238,7 +238,7 @@ export default definePlugin({
|
|||
name: "EmoteCloner",
|
||||
description: "Adds a Clone context menu item to emotes to clone them your own server",
|
||||
authors: [Devs.Ven, Devs.Nuckyz],
|
||||
dependencies: ["MenuItemDeobfuscatorAPI", "ContextMenuAPI"],
|
||||
dependencies: ["ContextMenuAPI"],
|
||||
|
||||
start() {
|
||||
addContextMenuPatch("message", messageContextMenuPatch);
|
||||
|
|
|
@ -76,7 +76,7 @@ export default definePlugin({
|
|||
name: "MessageLogger",
|
||||
description: "Temporarily logs deleted and edited messages.",
|
||||
authors: [Devs.rushii, Devs.Ven],
|
||||
dependencies: ["ContextMenuAPI", "MenuItemDeobfuscatorAPI"],
|
||||
dependencies: ["ContextMenuAPI"],
|
||||
|
||||
start() {
|
||||
addDeleteStyle();
|
||||
|
|
|
@ -76,7 +76,7 @@ export default definePlugin({
|
|||
name: "ReverseImageSearch",
|
||||
description: "Adds ImageSearch to image context menus",
|
||||
authors: [Devs.Ven, Devs.Nuckyz],
|
||||
dependencies: ["MenuItemDeobfuscatorAPI", "ContextMenuAPI"],
|
||||
dependencies: ["ContextMenuAPI"],
|
||||
patches: [
|
||||
{
|
||||
find: ".Messages.MESSAGE_ACTIONS_MENU_LABEL",
|
||||
|
|
|
@ -39,7 +39,6 @@ export default definePlugin({
|
|||
name: "SpotifyControls",
|
||||
description: "Spotify Controls",
|
||||
authors: [Devs.Ven, Devs.afn, Devs.KraXen72],
|
||||
dependencies: ["MenuItemDeobfuscatorAPI"],
|
||||
options: {
|
||||
hoverControls: {
|
||||
description: "Show controls on hover",
|
||||
|
|
|
@ -35,8 +35,6 @@ export default definePlugin({
|
|||
authors: [Devs.Ven],
|
||||
description: "Makes Avatars/Banners in user profiles clickable, and adds Guild Context Menu Entries to View Banner/Icon.",
|
||||
|
||||
dependencies: ["MenuItemDeobfuscatorAPI"],
|
||||
|
||||
openImage(url: string) {
|
||||
const u = new URL(url);
|
||||
u.searchParams.set("size", "512");
|
||||
|
|
|
@ -17,40 +17,37 @@
|
|||
*/
|
||||
|
||||
// eslint-disable-next-line path-alias/no-relative
|
||||
import { filters, findByPropsLazy } from "../webpack";
|
||||
import { filters, findByPropsLazy, waitFor } from "@webpack";
|
||||
|
||||
import { waitForComponent } from "./internal";
|
||||
import * as t from "./types/components";
|
||||
|
||||
export const Forms = {
|
||||
FormTitle: waitForComponent<t.FormTitle>("FormTitle", filters.byCode("errorSeparator")),
|
||||
FormSection: waitForComponent<t.FormSection>("FormSection", filters.byCode("titleClassName", "sectionTitle")),
|
||||
FormDivider: waitForComponent<t.FormDivider>("FormDivider", m => {
|
||||
if (typeof m !== "function") return false;
|
||||
const s = m.toString();
|
||||
return s.length < 200 && s.includes(".divider");
|
||||
}),
|
||||
FormText: waitForComponent<t.FormText>("FormText", m => m.Types?.INPUT_PLACEHOLDER),
|
||||
export let Forms = {} as {
|
||||
FormTitle: t.FormTitle,
|
||||
FormSection: t.FormSection,
|
||||
FormDivider: t.FormDivider,
|
||||
FormText: t.FormText,
|
||||
};
|
||||
|
||||
export const Card = waitForComponent<t.Card>("Card", m => m.Types?.PRIMARY && m.defaultProps);
|
||||
export const Button = waitForComponent<t.Button>("Button", ["Hovers", "Looks", "Sizes"]);
|
||||
export const Switch = waitForComponent<t.Switch>("Switch", filters.byCode("tooltipNote", "ringTarget"));
|
||||
export const Tooltip = waitForComponent<t.Tooltip>("Tooltip", filters.byCode("shouldShowTooltip:!1", "clickableOnMobile||"));
|
||||
export let Card: t.Card;
|
||||
export let Button: t.Button;
|
||||
export let Switch: t.Switch;
|
||||
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 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 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/>.
|
||||
*/
|
||||
|
||||
import { proxyLazy } from "@utils/proxyLazy";
|
||||
|
||||
// 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";
|
||||
|
||||
export const Menu: t.Menu = proxyLazy(() => {
|
||||
const hasDeobfuscator = Vencord.Settings.plugins.MenuItemDeobfuscatorAPI.enabled;
|
||||
const menuItems = ["MenuSeparator", "MenuGroup", "MenuItem", "MenuCheckboxItem", "MenuRadioItem", "MenuControlItem"];
|
||||
export let Menu = {} as t.Menu;
|
||||
|
||||
const map = mapMangledModule("♫ ⊂(。◕‿‿◕。⊂) ♪", {
|
||||
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;
|
||||
});
|
||||
waitFor("MenuItem", m => Menu = m);
|
||||
|
||||
export const ContextMenu: t.ContextMenuApi = mapMangledModuleLazy('type:"CONTEXT_MENU_OPEN"', {
|
||||
open: filters.byCode("stopPropagation"),
|
||||
|
|
|
@ -109,6 +109,8 @@ export const find = traceFunction("find", function find(filter: FilterFn, getDef
|
|||
if (!isWaitFor) {
|
||||
const err = new Error("Didn't find module matching this filter");
|
||||
if (IS_DEV) {
|
||||
logger.error(err);
|
||||
logger.error(filter);
|
||||
if (!devToolsOpen)
|
||||
// Strict behaviour in DevBuilds to fail early and make sure the issue is found
|
||||
throw err;
|
||||
|
|
Loading…
Reference in a new issue