From 3505adad6d8453e37cf361cbfc43cf474d2474f9 Mon Sep 17 00:00:00 2001 From: vee Date: Wed, 19 Jun 2024 07:16:29 +0200 Subject: [PATCH 1/7] final batch of fixes ~ we are SO BACK!! (#2598) * Fix ImplicitRelationships * performance fixes * fix false pos * fix super reaction tweaks * Fix PermissionFreeWill * Fix AlwaysTrust * clean ups * Fix ImageLink * Fix ValidReply * Fix ShowHiddenChannels partially and race conditions related to exports * fix bucnh of webpack finds * Fix FriendsSince, RevealAllSpoilers * finish show hidden channels * read if cute * doomsday fix: ClientTheme (#2597) * fix friendinvites * fix extractAndLoadChunks * bleh * fix FakeNitro * fake nitro part 2 * and part 3 * bump to v1.9.0 * remove dead settings patch * fix ForceOwnerCrown * fix decor lazy load --------- Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Co-authored-by: rushii <33725716+rushiiMachine@users.noreply.github.com> --- package.json | 2 +- src/debug/loadLazyChunks.ts | 2 +- src/plugins/_api/messageEvents.ts | 4 +- src/plugins/_core/settings.tsx | 7 --- src/plugins/alwaysTrust/index.ts | 2 +- src/plugins/banger/index.ts | 2 +- src/plugins/betterFolders/index.tsx | 4 +- src/plugins/betterSettings/index.tsx | 8 ++-- src/plugins/clientTheme/index.tsx | 4 +- src/plugins/crashHandler/index.ts | 13 +++--- src/plugins/decor/ui/index.ts | 2 +- .../decor/ui/modals/CreateDecorationModal.tsx | 7 ++- src/plugins/emoteCloner/index.tsx | 6 +-- src/plugins/experiments/index.tsx | 10 +++-- src/plugins/fakeNitro/index.tsx | 28 ++++++------ src/plugins/fakeProfileThemes/index.tsx | 2 +- src/plugins/forceOwnerCrown/index.ts | 2 +- src/plugins/friendInvites/index.ts | 44 +------------------ src/plugins/friendsSince/index.tsx | 16 ++++--- src/plugins/friendsSince/styles.css | 12 +++++ src/plugins/gifPaste/index.ts | 6 +-- src/plugins/greetStickerPicker/index.tsx | 4 +- src/plugins/imageLink/index.ts | 3 +- src/plugins/implicitRelationships/index.ts | 14 ++---- src/plugins/index.ts | 1 - src/plugins/maskedLinkPaste/index.ts | 2 +- src/plugins/newGuildSettings/index.tsx | 4 +- src/plugins/pauseInvitesForever/index.tsx | 4 +- src/plugins/permissionFreeWill/index.ts | 8 ++-- .../pinDms/components/CreateCategoryModal.tsx | 2 +- src/plugins/revealAllSpoilers/index.ts | 2 +- .../reviewDB/components/ReviewComponent.tsx | 2 +- src/plugins/seeSummaries/index.tsx | 2 +- src/plugins/showHiddenChannels/index.tsx | 18 ++++---- src/plugins/superReactionTweaks/index.ts | 4 +- src/plugins/validReply/index.ts | 4 +- src/webpack/common/types/utils.d.ts | 1 + src/webpack/common/utils.ts | 11 ++++- src/webpack/webpack.ts | 8 ++-- 39 files changed, 126 insertions(+), 151 deletions(-) create mode 100644 src/plugins/friendsSince/styles.css diff --git a/package.json b/package.json index 1bc01bac..e80c3970 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.8.9", + "version": "1.9.0", "description": "The cutest Discord client mod", "homepage": "https://github.com/Vendicated/Vencord#readme", "bugs": { diff --git a/src/debug/loadLazyChunks.ts b/src/debug/loadLazyChunks.ts index 0aeae732..64c3e0ea 100644 --- a/src/debug/loadLazyChunks.ts +++ b/src/debug/loadLazyChunks.ts @@ -25,7 +25,7 @@ export async function loadLazyChunks() { // True if resolved, false otherwise const chunksSearchPromises = [] as Array<() => boolean>; - const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("[^)]+?"\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"([^)]+?)"\)\)/g); + const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/g); async function searchAndLoadLazyChunks(factoryCode: string) { const lazyChunks = factoryCode.matchAll(LazyChunkRegex); diff --git a/src/plugins/_api/messageEvents.ts b/src/plugins/_api/messageEvents.ts index 2f31398c..0347d544 100644 --- a/src/plugins/_api/messageEvents.ts +++ b/src/plugins/_api/messageEvents.ts @@ -35,11 +35,11 @@ export default definePlugin({ } }, { - find: ".handleSendMessage", + find: ".handleSendMessage,onResize", replacement: { // props.chatInputType...then((function(isMessageValid)... var parsedMessage = b.c.parse(channel,... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); // Lookbehind: validateMessage)({openWarningPopout:..., type: i.props.chatInputType, content: t, stickers: r, ...}).then((function(isMessageValid) - match: /(type:this\.props\.chatInputType.+?\.then\()(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.\i\(\i\);)(?<=\)\(({.+?})\)\.then.+?)/, + match: /(type:this\.props\.chatInputType.+?\.then\()(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptionsForReply\(\i\);)(?<=\)\(({.+?})\)\.then.+?)/, // props.chatInputType...then((async function(isMessageValid)... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); if(await Vencord.api...) return { shoudClear:true, shouldRefocus:true }; replace: (_, rest1, rest2, parsedMessage, channel, replyOptions, extra) => "" + `${rest1}async ${rest2}` + diff --git a/src/plugins/_core/settings.tsx b/src/plugins/_core/settings.tsx index 85300862..50cd6f04 100644 --- a/src/plugins/_core/settings.tsx +++ b/src/plugins/_core/settings.tsx @@ -84,13 +84,6 @@ export default definePlugin({ replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}` } }, - { - find: "useDefaultUserSettingsSections:function", - replacement: { - match: /(?<=useDefaultUserSettingsSections:function\(\){return )(\i)\}/, - replace: "$self.wrapSettingsHook($1)}" - } - }, { find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL", replacement: { diff --git a/src/plugins/alwaysTrust/index.ts b/src/plugins/alwaysTrust/index.ts index b195e8eb..7484a619 100644 --- a/src/plugins/alwaysTrust/index.ts +++ b/src/plugins/alwaysTrust/index.ts @@ -49,7 +49,7 @@ export default definePlugin({ predicate: () => settings.store.domain }, { - find: "isSuspiciousDownload:", + find: "bitbucket.org", replacement: { match: /function \i\(\i\){(?=.{0,60}\.parse\(\i\))/, replace: "$&return null;" diff --git a/src/plugins/banger/index.ts b/src/plugins/banger/index.ts index 11ced3bd..7e0d2df7 100644 --- a/src/plugins/banger/index.ts +++ b/src/plugins/banger/index.ts @@ -27,7 +27,7 @@ export default definePlugin({ { find: "BAN_CONFIRM_TITLE.", replacement: { - match: /src:\i\(\d+\)/g, + match: /src:\i\("?\d+"?\)/g, replace: "src: Vencord.Settings.plugins.BANger.source" } } diff --git a/src/plugins/betterFolders/index.tsx b/src/plugins/betterFolders/index.tsx index 59e55111..d0e8cf34 100644 --- a/src/plugins/betterFolders/index.tsx +++ b/src/plugins/betterFolders/index.tsx @@ -144,8 +144,8 @@ export default definePlugin({ replacement: [ { // Modify the expanded state to instead return the list of expanded folders - match: /(\i\).{0,20}=>)(\i\.\i)\.isFolderExpanded\(\i\)/, - replace: (_, rest, ExpandedGuildFolderStore) => `${rest}${ExpandedGuildFolderStore}.getExpandedFolders()`, + match: /(\],\(\)=>)(\i\.\i)\.isFolderExpanded\(\i\)\)/, + replace: (_, rest, ExpandedGuildFolderStore) => `${rest}${ExpandedGuildFolderStore}.getExpandedFolders())`, }, { // Modify the expanded prop to use the boolean if the above patch fails, or check if the folder is expanded from the list if it succeeds diff --git a/src/plugins/betterSettings/index.tsx b/src/plugins/betterSettings/index.tsx index 6d8d9855..6a3ded3c 100644 --- a/src/plugins/betterSettings/index.tsx +++ b/src/plugins/betterSettings/index.tsx @@ -88,7 +88,7 @@ export default definePlugin({ predicate: () => settings.store.disableFade }, { // Lazy-load contents - match: /createPromise:\(\)=>([^:}]*?),webpackId:\d+,name:(?!="CollectiblesShop")"[^"]+"/g, + match: /createPromise:\(\)=>([^:}]*?),webpackId:"?\d+"?,name:(?!="CollectiblesShop")"[^"]+"/g, replace: "$&,_:$1", predicate: () => settings.store.eagerLoad } @@ -111,7 +111,7 @@ export default definePlugin({ { // Load menu TOC eagerly find: "Messages.USER_SETTINGS_WITH_BUILD_OVERRIDE.format", replacement: { - match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?\i\.\i\).{0,100}?(await Promise\.all[^};]*?\)\)).*?,(?=\1\(this)/, + match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?null!=\i&&.{0,100}?(await Promise\.all[^};]*?\)\)).*?,(?=\1\(this)/, replace: "$&(async ()=>$2)()," }, predicate: () => settings.store.eagerLoad @@ -119,8 +119,8 @@ export default definePlugin({ { // Settings cog context menu find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL", replacement: { - match: /\(0,\i.\i\)\(\)(?=\.filter\(\i=>\{let\{section:\i\}=)/, - replace: "$self.wrapMenu($&)" + match: /(EXPERIMENTS:.+?)(\(0,\i.\i\)\(\))(?=\.filter\(\i=>\{let\{section:\i\}=)/, + replace: "$1$self.wrapMenu($2)" } } ], diff --git a/src/plugins/clientTheme/index.tsx b/src/plugins/clientTheme/index.tsx index 4e07daf4..b36a2cb8 100644 --- a/src/plugins/clientTheme/index.tsx +++ b/src/plugins/clientTheme/index.tsx @@ -11,7 +11,7 @@ import { Devs } from "@utils/constants"; import { Margins } from "@utils/margins"; import { classes } from "@utils/misc"; import definePlugin, { OptionType, StartAt } from "@utils/types"; -import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; +import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; import { Button, Forms, useStateFromStores } from "@webpack/common"; const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); @@ -30,7 +30,7 @@ function onPickColor(color: number) { updateColorVars(hexColor); } -const { saveClientTheme } = findByPropsLazy("saveClientTheme"); +const saveClientTheme = findByCodeLazy('type:"UNSYNCED_USER_SETTINGS_UPDATE",settings:{useSystemTheme:"system"==='); function setTheme(theme: string) { saveClientTheme({ theme }); diff --git a/src/plugins/crashHandler/index.ts b/src/plugins/crashHandler/index.ts index 3297ca30..ab881e60 100644 --- a/src/plugins/crashHandler/index.ts +++ b/src/plugins/crashHandler/index.ts @@ -24,20 +24,19 @@ import { closeAllModals } from "@utils/modal"; import definePlugin, { OptionType } from "@utils/types"; import { maybePromptToUpdate } from "@utils/updater"; import { filters, findBulk, proxyLazyWebpack } from "@webpack"; -import { DraftType, FluxDispatcher, NavigationRouter, SelectedChannelStore } from "@webpack/common"; +import { DraftType, ExpressionPickerStore, FluxDispatcher, NavigationRouter, SelectedChannelStore } from "@webpack/common"; const CrashHandlerLogger = new Logger("CrashHandler"); -const { ModalStack, DraftManager, closeExpressionPicker } = proxyLazyWebpack(() => { - const [ModalStack, DraftManager, ExpressionManager] = findBulk( +const { ModalStack, DraftManager } = proxyLazyWebpack(() => { + const [ModalStack, DraftManager] = findBulk( filters.byProps("pushLazy", "popAll"), filters.byProps("clearDraft", "saveDraft"), - filters.byProps("closeExpressionPicker", "openExpressionPicker"),); + ); return { ModalStack, - DraftManager, - closeExpressionPicker: ExpressionManager?.closeExpressionPicker, + DraftManager }; }); @@ -144,7 +143,7 @@ export default definePlugin({ CrashHandlerLogger.debug("Failed to clear drafts.", err); } try { - closeExpressionPicker(); + ExpressionPickerStore.closeExpressionPicker(); } catch (err) { CrashHandlerLogger.debug("Failed to close expression picker.", err); diff --git a/src/plugins/decor/ui/index.ts b/src/plugins/decor/ui/index.ts index 0ead602e..c7846364 100644 --- a/src/plugins/decor/ui/index.ts +++ b/src/plugins/decor/ui/index.ts @@ -10,5 +10,5 @@ import { extractAndLoadChunksLazy, findByPropsLazy } from "@webpack"; export const cl = classNameFactory("vc-decor-"); export const DecorationModalStyles = findByPropsLazy("modalFooterShopButton"); -export const requireAvatarDecorationModal = extractAndLoadChunksLazy(["openAvatarDecorationModal:"]); +export const requireAvatarDecorationModal = extractAndLoadChunksLazy([".COLLECTIBLES_SHOP_FULLSCREEN&&"]); export const requireCreateStickerModal = extractAndLoadChunksLazy(["stickerInspected]:"]); diff --git a/src/plugins/decor/ui/modals/CreateDecorationModal.tsx b/src/plugins/decor/ui/modals/CreateDecorationModal.tsx index 0dcf855e..f5596f39 100644 --- a/src/plugins/decor/ui/modals/CreateDecorationModal.tsx +++ b/src/plugins/decor/ui/modals/CreateDecorationModal.tsx @@ -9,7 +9,7 @@ import { Link } from "@components/Link"; import { openInviteModal } from "@utils/discord"; import { Margins } from "@utils/margins"; import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; -import { findByPropsLazy, findComponentByCodeLazy } from "@webpack"; +import { filters, findComponentByCodeLazy, mapMangledModuleLazy } from "@webpack"; import { Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Text, TextInput, useEffect, useMemo, UserStore, useState } from "@webpack/common"; import { GUILD_ID, INVITE_KEY, RAW_SKU_ID } from "../../lib/constants"; @@ -19,7 +19,10 @@ import { AvatarDecorationModalPreview } from "../components"; const FileUpload = findComponentByCodeLazy("fileUploadInput,"); -const { default: HelpMessage, HelpMessageTypes } = findByPropsLazy("HelpMessageTypes"); +const { HelpMessage, HelpMessageTypes } = mapMangledModuleLazy('POSITIVE=3]="POSITIVE', { + HelpMessageTypes: filters.byProps("POSITIVE", "WARNING"), + HelpMessage: filters.byCode(".iconDiv") +}); function useObjectURL(object: Blob | MediaSource | null) { const [url, setUrl] = useState(null); diff --git a/src/plugins/emoteCloner/index.tsx b/src/plugins/emoteCloner/index.tsx index b456c351..6dd3eb30 100644 --- a/src/plugins/emoteCloner/index.tsx +++ b/src/plugins/emoteCloner/index.tsx @@ -23,12 +23,12 @@ import { Logger } from "@utils/Logger"; import { Margins } from "@utils/margins"; import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal"; import definePlugin from "@utils/types"; -import { findByPropsLazy, findStoreLazy } from "@webpack"; +import { findByCodeLazy, findStoreLazy } from "@webpack"; import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common"; import { Promisable } from "type-fest"; const StickersStore = findStoreLazy("StickersStore"); -const EmojiManager = findByPropsLazy("fetchEmoji", "uploadEmoji", "deleteEmoji"); +const uploadEmoji = findByCodeLazy(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START"); interface Sticker { t: "Sticker"; @@ -106,7 +106,7 @@ async function cloneEmoji(guildId: string, emoji: Emoji) { reader.readAsDataURL(data); }); - return EmojiManager.uploadEmoji({ + return uploadEmoji({ guildId, name: emoji.name.split("~")[0], image: dataUrl diff --git a/src/plugins/experiments/index.tsx b/src/plugins/experiments/index.tsx index 9cb22521..4cf8439b 100644 --- a/src/plugins/experiments/index.tsx +++ b/src/plugins/experiments/index.tsx @@ -28,7 +28,7 @@ import { Forms, React } from "@webpack/common"; import hideBugReport from "./hideBugReport.css?managed"; -const KbdStyles = findByPropsLazy("key", "removeBuildOverride"); +const KbdStyles = findByPropsLazy("key", "combo"); const settings = definePluginSettings({ toolbarDevMenu: { @@ -106,9 +106,11 @@ export default definePlugin({ More Information You can open Discord's DevTools via {" "} - {modKey} +{" "} - {altKey} +{" "} - O{" "} +
+ {modKey} +{" "} + {altKey} +{" "} + O{" "} +
); diff --git a/src/plugins/fakeNitro/index.tsx b/src/plugins/fakeNitro/index.tsx index cdf74d15..76c8f364 100644 --- a/src/plugins/fakeNitro/index.tsx +++ b/src/plugins/fakeNitro/index.tsx @@ -37,8 +37,8 @@ const StickerStore = findStoreLazy("StickersStore") as { }; const UserSettingsProtoStore = findStoreLazy("UserSettingsProtoStore"); -const ProtoUtils = findByPropsLazy("BINARY_READ_OPTIONS"); -const RoleSubscriptionEmojiUtils = findByPropsLazy("isUnusableRoleSubscriptionEmoji"); + +const BINARY_READ_OPTIONS = findByPropsLazy("readerFactory"); function searchProtoClassField(localName: string, protoClass: any) { const field = protoClass?.fields?.find((field: any) => field.localName === localName); @@ -49,7 +49,7 @@ function searchProtoClassField(localName: string, protoClass: any) { } const PreloadedUserSettingsActionCreators = proxyLazyWebpack(() => UserSettingsActionCreators.PreloadedUserSettingsActionCreators); -const AppearanceSettingsActionCreators = proxyLazyWebpack(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators.ProtoClass)); +const AppearanceSettingsActionCreators = proxyLazyWebpack(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators)); const ClientThemeSettingsActionsCreators = proxyLazyWebpack(() => searchProtoClassField("clientThemeSettings", AppearanceSettingsActionCreators)); @@ -234,15 +234,16 @@ export default definePlugin({ } ] }, + // FIXME // Allows the usage of subscription-locked emojis - { - find: "isUnusableRoleSubscriptionEmoji:function", + /* { + find: ".getUserIsAdmin(", replacement: { - match: /isUnusableRoleSubscriptionEmoji:function/, + match: /(?=.+?\.getUserIsAdmin\((?<=function (\i)\(\i,\i\){.+?))(\i):function\(\){return \1}/, // Replace the original export with a func that always returns false and alias the original - replace: "isUnusableRoleSubscriptionEmoji:()=>()=>false,isUnusableRoleSubscriptionEmojiOriginal:function" + replace: "$2:()=>()=>false,isUnusableRoleSubscriptionEmojiOriginal:function(){return $1}" } - }, + }, */ // Allow stickers to be sent everywhere { find: "canUseCustomStickersEverywhere:function", @@ -361,7 +362,7 @@ export default definePlugin({ replacement: [ { // Export the renderable sticker to be used in the fake nitro sticker notice - match: /let{renderableSticker:(\i).{0,250}isGuildSticker.+?channel:\i,/, + match: /let{renderableSticker:(\i).{0,270}sticker:\i,channel:\i,/, replace: (m, renderableSticker) => `${m}fakeNitroRenderableSticker:${renderableSticker},` }, { @@ -472,12 +473,12 @@ export default definePlugin({ const premiumType = UserStore?.getCurrentUser()?.premiumType ?? 0; if (premiumType === 2 || backgroundGradientPresetId == null) return original(); - if (!PreloadedUserSettingsActionCreators || !AppearanceSettingsActionCreators || !ClientThemeSettingsActionsCreators || !ProtoUtils) return; + if (!PreloadedUserSettingsActionCreators || !AppearanceSettingsActionCreators || !ClientThemeSettingsActionsCreators || !BINARY_READ_OPTIONS) return; const currentAppearanceSettings = PreloadedUserSettingsActionCreators.getCurrentValue().appearance; const newAppearanceProto = currentAppearanceSettings != null - ? AppearanceSettingsActionCreators.fromBinary(AppearanceSettingsActionCreators.toBinary(currentAppearanceSettings), ProtoUtils.BINARY_READ_OPTIONS) + ? AppearanceSettingsActionCreators.fromBinary(AppearanceSettingsActionCreators.toBinary(currentAppearanceSettings), BINARY_READ_OPTIONS) : AppearanceSettingsActionCreators.create(); newAppearanceProto.theme = theme; @@ -816,8 +817,9 @@ export default definePlugin({ if (e.type === 0) return true; if (e.available === false) return false; - const isUnusableRoleSubEmoji = RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmojiOriginal ?? RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmoji; - if (isUnusableRoleSubEmoji(e, this.guildId)) return false; + // FIXME + /* const isUnusableRoleSubEmoji = isUnusableRoleSubscriptionEmojiOriginal ?? RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmoji; + if (isUnusableRoleSubEmoji(e, this.guildId)) return false; */ if (this.canUseEmotes) return e.guildId === this.guildId || hasExternalEmojiPerms(channelId); diff --git a/src/plugins/fakeProfileThemes/index.tsx b/src/plugins/fakeProfileThemes/index.tsx index 7a6bda9a..31fc71a9 100644 --- a/src/plugins/fakeProfileThemes/index.tsx +++ b/src/plugins/fakeProfileThemes/index.tsx @@ -111,7 +111,7 @@ interface ProfileModalProps { const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); const ProfileModal = findComponentByCodeLazy('"ProfileCustomizationPreview"'); -const requireColorPicker = extractAndLoadChunksLazy(["USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON.format"], /createPromise:\(\)=>\i\.\i\("(.+?)"\).then\(\i\.bind\(\i,"(.+?)"\)\)/); +const requireColorPicker = extractAndLoadChunksLazy(["USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON.format"], /createPromise:\(\)=>\i\.\i\("?(.+?)"?\).then\(\i\.bind\(\i,"?(.+?)"?\)\)/); export default definePlugin({ name: "FakeProfileThemes", diff --git a/src/plugins/forceOwnerCrown/index.ts b/src/plugins/forceOwnerCrown/index.ts index 15b1f6f5..771583fe 100644 --- a/src/plugins/forceOwnerCrown/index.ts +++ b/src/plugins/forceOwnerCrown/index.ts @@ -27,7 +27,7 @@ export default definePlugin({ authors: [Devs.D3SOX, Devs.Nickyux], patches: [ { - find: "AVATAR_DECORATION_PADDING:", + find: ".PREMIUM_GUILD_SUBSCRIPTION_TOOLTIP", replacement: { match: /,isOwner:(\i),/, replace: ",_isOwner:$1=$self.isGuildOwner(e)," diff --git a/src/plugins/friendInvites/index.ts b/src/plugins/friendInvites/index.ts index 47e312c3..20c615d6 100644 --- a/src/plugins/friendInvites/index.ts +++ b/src/plugins/friendInvites/index.ts @@ -16,14 +16,12 @@ * along with this program. If not, see . */ -import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands"; +import { ApplicationCommandInputType, sendBotMessage } from "@api/Commands"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { findByPropsLazy } from "@webpack"; -import { Constants, RestAPI, UserStore } from "@webpack/common"; const FriendInvites = findByPropsLazy("createFriendInvite"); -const { uuid4 } = findByPropsLazy("uuid4"); export default definePlugin({ name: "FriendInvites", @@ -35,47 +33,9 @@ export default definePlugin({ name: "create friend invite", description: "Generates a friend invite link.", inputType: ApplicationCommandInputType.BOT, - options: [{ - name: "Uses", - description: "How many uses?", - choices: [ - { label: "1", name: "1", value: "1" }, - { label: "5", name: "5", value: "5" } - ], - required: false, - type: ApplicationCommandOptionType.INTEGER - }], execute: async (args, ctx) => { - const uses = findOption(args, "Uses", 5); - - if (uses === 1 && !UserStore.getCurrentUser().phone) - return sendBotMessage(ctx.channel.id, { - content: "You need to have a phone number connected to your account to create a friend invite with 1 use!" - }); - - let invite: any; - if (uses === 1) { - const random = uuid4(); - const { body: { invite_suggestions } } = await RestAPI.post({ - url: Constants.Endpoints.FRIEND_FINDER, - body: { - modified_contacts: { - [random]: [1, "", ""] - }, - phone_contact_methods_count: 1 - } - }); - invite = await FriendInvites.createFriendInvite({ - code: invite_suggestions[0][3], - recipient_phone_number_or_email: random, - contact_visibility: 1, - filter_visibilities: [], - filtered_invite_suggestions_index: 1 - }); - } else { - invite = await FriendInvites.createFriendInvite(); - } + const invite = await FriendInvites.createFriendInvite(); sendBotMessage(ctx.channel.id, { content: ` diff --git a/src/plugins/friendsSince/index.tsx b/src/plugins/friendsSince/index.tsx index 6c354278..b290a445 100644 --- a/src/plugins/friendsSince/index.tsx +++ b/src/plugins/friendsSince/index.tsx @@ -4,21 +4,23 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ +import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import { getCurrentChannel } from "@utils/discord"; import { Logger } from "@utils/Logger"; import { classes } from "@utils/misc"; import definePlugin from "@utils/types"; -import { findByPropsLazy } from "@webpack"; +import { findByCodeLazy, findByPropsLazy } from "@webpack"; import { Heading, React, RelationshipStore, Text } from "@webpack/common"; const container = findByPropsLazy("memberSinceWrapper"); -const { getCreatedAtDate } = findByPropsLazy("getCreatedAtDate"); -const clydeMoreInfo = findByPropsLazy("clydeMoreInfo"); +const getCreatedAtDate = findByCodeLazy('month:"short",day:"numeric"'); const locale = findByPropsLazy("getLocale"); const lastSection = findByPropsLazy("lastSection"); +const cl = classNameFactory("vc-friendssince-"); + export default definePlugin({ name: "FriendsSince", description: "Shows when you became friends with someone in the user popout", @@ -28,7 +30,7 @@ export default definePlugin({ { find: ".USER_PROFILE}};return", replacement: { - match: /\i.\i,\{userId:(\i.id).{0,30}}\)/, + match: /,{userId:(\i.id).{0,30}}\)/, replace: "$&,$self.friendsSince({ userId: $1 })" } }, @@ -36,7 +38,7 @@ export default definePlugin({ { find: ".PROFILE_PANEL,", replacement: { - match: /\i.\i,\{userId:([^,]+?)}\)/, + match: /,{userId:([^,]+?)}\)/, replace: "$&,$self.friendsSince({ userId: $1 })" } }, @@ -69,7 +71,7 @@ export default definePlugin({ return (
- + Friends Since @@ -86,7 +88,7 @@ export default definePlugin({ )} - + {getCreatedAtDate(friendsSince, locale.getLocale())}
diff --git a/src/plugins/friendsSince/styles.css b/src/plugins/friendsSince/styles.css new file mode 100644 index 00000000..9f73db0b --- /dev/null +++ b/src/plugins/friendsSince/styles.css @@ -0,0 +1,12 @@ +/* copy pasted from discord */ + +.vc-friendssince-title { + display: flex; + font-weight: 700; + margin-bottom: 6px +} + +.vc-friendssince-body { + font-size: 14px; + line-height: 18px +} diff --git a/src/plugins/gifPaste/index.ts b/src/plugins/gifPaste/index.ts index 5553bf84..b2b4305d 100644 --- a/src/plugins/gifPaste/index.ts +++ b/src/plugins/gifPaste/index.ts @@ -19,9 +19,7 @@ import { Devs } from "@utils/constants"; import { insertTextIntoChatInputBox } from "@utils/discord"; import definePlugin from "@utils/types"; -import { findByPropsLazy } from "@webpack"; - -const { closeExpressionPicker } = findByPropsLazy("closeExpressionPicker"); +import { ExpressionPickerStore } from "@webpack/common"; export default definePlugin({ name: "GifPaste", @@ -39,7 +37,7 @@ export default definePlugin({ handleSelect(gif?: { url: string; }) { if (gif) { insertTextIntoChatInputBox(gif.url + " "); - closeExpressionPicker(); + ExpressionPickerStore.closeExpressionPicker(); } } }); diff --git a/src/plugins/greetStickerPicker/index.tsx b/src/plugins/greetStickerPicker/index.tsx index 73bb5125..438fa40c 100644 --- a/src/plugins/greetStickerPicker/index.tsx +++ b/src/plugins/greetStickerPicker/index.tsx @@ -19,7 +19,7 @@ import { definePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy } from "@webpack"; +import { findLazy } from "@webpack"; import { ContextMenuApi, FluxDispatcher, Menu, MessageActions } from "@webpack/common"; import { Channel, Message } from "discord-types/general"; @@ -49,7 +49,7 @@ const settings = definePluginSettings({ unholyMultiGreetEnabled?: boolean; }>(); -const { WELCOME_STICKERS } = findByPropsLazy("WELCOME_STICKERS"); +const WELCOME_STICKERS = findLazy(m => Array.isArray(m) && m[0]?.name === "Wave"); function greet(channel: Channel, message: Message, stickers: string[]) { const options = MessageActions.getSendMessageOptionsForReply({ diff --git a/src/plugins/imageLink/index.ts b/src/plugins/imageLink/index.ts index 5e8dd23e..08d3a024 100644 --- a/src/plugins/imageLink/index.ts +++ b/src/plugins/imageLink/index.ts @@ -16,7 +16,8 @@ export default definePlugin({ { find: "unknownUserMentionPlaceholder:", replacement: { - match: /\(0,\i\.isEmbedInline\)\(\i\)/, + // SimpleEmbedTypes.has(embed.type) && isEmbedInline(embed) + match: /\i\.has\(\i\.type\)&&\(0,\i\.\i\)\(\i\)/, replace: "false", } } diff --git a/src/plugins/implicitRelationships/index.ts b/src/plugins/implicitRelationships/index.ts index 4faad2a9..7fefb39b 100644 --- a/src/plugins/implicitRelationships/index.ts +++ b/src/plugins/implicitRelationships/index.ts @@ -19,17 +19,11 @@ import { definePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy, findStoreLazy } from "@webpack"; -import { ChannelStore, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserStore } from "@webpack/common"; +import { findStoreLazy } from "@webpack"; +import { ChannelStore, Constants, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserStore } from "@webpack/common"; import { Settings } from "Vencord"; const UserAffinitiesStore = findStoreLazy("UserAffinitiesStore"); -const { FriendsSections } = findByPropsLazy("FriendsSections"); - -interface UserAffinity { - user_id: string; - affinity: number; -} export default definePlugin({ name: "ImplicitRelationships", @@ -70,7 +64,7 @@ export default definePlugin({ }, // Piggyback relationship fetch { - find: ".fetchRelationships()", + find: '"FriendsStore', replacement: { match: /(\i\.\i)\.fetchRelationships\(\)/, // This relationship fetch is actually completely useless, but whatevs @@ -182,6 +176,6 @@ export default definePlugin({ }, start() { - FriendsSections.IMPLICIT = "IMPLICIT"; + Constants.FriendsSections.IMPLICIT = "IMPLICIT"; } }); diff --git a/src/plugins/index.ts b/src/plugins/index.ts index b731899d..45e182b8 100644 --- a/src/plugins/index.ts +++ b/src/plugins/index.ts @@ -44,7 +44,6 @@ const pluginsValues = Object.values(Plugins); const settings = Settings.plugins; const forceDisabled = new Set([ - "ShowHiddenChannels", "MoreUserTags" ]); export function isPluginEnabled(p: string) { diff --git a/src/plugins/maskedLinkPaste/index.ts b/src/plugins/maskedLinkPaste/index.ts index 72931208..bcd622ed 100644 --- a/src/plugins/maskedLinkPaste/index.ts +++ b/src/plugins/maskedLinkPaste/index.ts @@ -10,7 +10,7 @@ import { findByPropsLazy } from "@webpack"; const linkRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/; -const { SlateTransforms } = findByPropsLazy("SlateTransforms"); +const SlateTransforms = findByPropsLazy("insertText", "selectCommandOption"); export default definePlugin({ name: "MaskedLinkPaste", diff --git a/src/plugins/newGuildSettings/index.tsx b/src/plugins/newGuildSettings/index.tsx index d5c3d920..f1c29f25 100644 --- a/src/plugins/newGuildSettings/index.tsx +++ b/src/plugins/newGuildSettings/index.tsx @@ -19,11 +19,11 @@ import { definePluginSettings, migratePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy } from "@webpack"; +import { findByCodeLazy, findByPropsLazy } from "@webpack"; const { updateGuildNotificationSettings } = findByPropsLazy("updateGuildNotificationSettings"); const { toggleShowAllChannels } = findByPropsLazy("toggleShowAllChannels"); -const { isOptInEnabledForGuild } = findByPropsLazy("isOptInEnabledForGuild"); +const isOptInEnabledForGuild = findByCodeLazy(".COMMUNITY)||", ".isOptInEnabled("); const settings = definePluginSettings({ guild: { diff --git a/src/plugins/pauseInvitesForever/index.tsx b/src/plugins/pauseInvitesForever/index.tsx index 332297b6..3f1ce6bf 100644 --- a/src/plugins/pauseInvitesForever/index.tsx +++ b/src/plugins/pauseInvitesForever/index.tsx @@ -56,8 +56,8 @@ export default definePlugin({ replace: "children: $self.renderInvitesLabel({guildId:arguments[0].guildId,setChecked})", }, { - match: /(\i\.\i\)\(\i\),\[\i,(\i)\]=\i\.useState\(\i\))/, - replace: "$1,setChecked=$2" + match: /\.INVITES_DISABLED\)(?=.+?\.Messages\.INVITES_PERMANENTLY_DISABLED_TIP.+?checked:(\i)).+?\[\1,(\i)\]=\i.useState\(\i\)/, + replace: "$&,setChecked=$2" } ] } diff --git a/src/plugins/permissionFreeWill/index.ts b/src/plugins/permissionFreeWill/index.ts index 70a85868..96e110b6 100644 --- a/src/plugins/permissionFreeWill/index.ts +++ b/src/plugins/permissionFreeWill/index.ts @@ -6,6 +6,7 @@ import { definePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; +import { canonicalizeMatch } from "@utils/patches"; import definePlugin, { OptionType } from "@utils/types"; const settings = definePluginSettings({ @@ -31,7 +32,7 @@ export default definePlugin({ patches: [ // Permission lockout, just set the check to true { - find: ".showPermissionLockoutModal(", + find: ".STAGE_CHANNEL_CANNOT_OVERWRITE_PERMISSION", replacement: [ { match: /case"DENY":.{0,50}if\((?=\i\.\i\.can)/, @@ -45,9 +46,8 @@ export default definePlugin({ find: ".ONBOARDING_CHANNEL_THRESHOLD_WARNING", replacement: [ { - // are we java yet? - match: /(?<=(?:isDefaultChannelThresholdMetAfterDelete|checkDefaultChannelThresholdMetAfterChannelPermissionDeny):function\(\)\{)return \i(?=\})/g, - replace: "return () => true" + match: /{(\i:function\(\){return \i},?){2}}/, + replace: m => m.replaceAll(canonicalizeMatch(/return \i/g), "return ()=>Promise.resolve(true)") } ], predicate: () => settings.store.onboarding diff --git a/src/plugins/pinDms/components/CreateCategoryModal.tsx b/src/plugins/pinDms/components/CreateCategoryModal.tsx index 123bc838..2f1d4d1d 100644 --- a/src/plugins/pinDms/components/CreateCategoryModal.tsx +++ b/src/plugins/pinDms/components/CreateCategoryModal.tsx @@ -33,7 +33,7 @@ interface ColorPickerWithSwatchesProps { const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); const ColorPickerWithSwatches = findExportedComponentLazy("ColorPicker", "CustomColorPicker"); -export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\(".+?"\).+?\])\).then\(\i\.bind\(\i,"(.+?)"\)\).{0,50}"UserSettings"/); +export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\("?.+?"?\).+?\])\).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/); const cl = classNameFactory("vc-pindms-modal-"); diff --git a/src/plugins/revealAllSpoilers/index.ts b/src/plugins/revealAllSpoilers/index.ts index e728181a..98e8423c 100644 --- a/src/plugins/revealAllSpoilers/index.ts +++ b/src/plugins/revealAllSpoilers/index.ts @@ -21,7 +21,7 @@ import definePlugin from "@utils/types"; import { findByPropsLazy } from "@webpack"; const SpoilerClasses = findByPropsLazy("spoilerContent"); -const MessagesClasses = findByPropsLazy("messagesWrapper", "messages"); +const MessagesClasses = findByPropsLazy("messagesWrapper"); export default definePlugin({ name: "RevealAllSpoilers", diff --git a/src/plugins/reviewDB/components/ReviewComponent.tsx b/src/plugins/reviewDB/components/ReviewComponent.tsx index 8faec9f4..31eab29f 100644 --- a/src/plugins/reviewDB/components/ReviewComponent.tsx +++ b/src/plugins/reviewDB/components/ReviewComponent.tsx @@ -142,7 +142,7 @@ export default LazyComponent(() => { {review.type === ReviewType.System && ( System diff --git a/src/plugins/seeSummaries/index.tsx b/src/plugins/seeSummaries/index.tsx index f1cdd785..4ce8c4af 100644 --- a/src/plugins/seeSummaries/index.tsx +++ b/src/plugins/seeSummaries/index.tsx @@ -57,7 +57,7 @@ export default definePlugin({ { find: "SUMMARIZEABLE.has", replacement: { - match: /\i\.hasFeature\(.{0,10}\.SUMMARIES_ENABLED\w+?\)/g, + match: /\i\.hasFeature\(\i\.\i\.SUMMARIES_ENABLED\w+?\)/g, replace: "true" } }, diff --git a/src/plugins/showHiddenChannels/index.tsx b/src/plugins/showHiddenChannels/index.tsx index 48342cae..b0668673 100644 --- a/src/plugins/showHiddenChannels/index.tsx +++ b/src/plugins/showHiddenChannels/index.tsx @@ -116,14 +116,14 @@ export default definePlugin({ }, // Prevent Discord from trying to connect to hidden stage channels { - find: ".MAX_STAGE_VOICE_USER_LIMIT})", + find: ".AUDIENCE),{isSubscriptionGated", replacement: { match: /!(\i)\.isRoleSubscriptionTemplatePreviewChannel\(\)/, replace: (m, channel) => `${m}&&!$self.isHiddenChannel(${channel})` } }, { - find: "ChannelItemEditButton:function(){", + find: 'tutorialId:"instant-invite"', replacement: [ // Render null instead of the buttons if the channel is hidden ...[ @@ -195,7 +195,7 @@ export default definePlugin({ // Hide the new version of unreads box for hidden channels find: '="ChannelListUnreadsStore",', replacement: { - match: /(?=&&\(0,\i\.getHasImportantUnread\)\((\i)\))/g, // Global because Discord has multiple methods like that in the same module + match: /(?<=\.id\)\))(?=&&\(0,\i\.\i\)\((\i)\))/, replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})` } }, @@ -203,15 +203,15 @@ export default definePlugin({ // Make the old version of unreads box not visible for hidden channels find: "renderBottomUnread(){", replacement: { - match: /(?=&&\(0,\i\.getHasImportantUnread\)\((\i\.record)\))/, + match: /(?<=!0\))(?=&&\(0,\i\.\i\)\((\i\.record)\))/, replace: "&&!$self.isHiddenChannel($1)" } }, { // Make the state of the old version of unreads box not include hidden channels - find: ".useFlattenedChannelIdListWithThreads)", + find: "ignoreRecents:!0", replacement: { - match: /(?=&&\(0,\i\.getHasImportantUnread\)\((\i)\))/, + match: /(?<=\.id\)\))(?=&&\(0,\i\.\i\)\((\i)\))/, replace: "&&!$self.isHiddenChannel($1)" } }, @@ -257,7 +257,7 @@ export default definePlugin({ { find: '"alt+shift+down"', replacement: { - match: /(?<=getChannel\(\i\);return null!=(\i))(?=.{0,150}?getHasImportantUnread\)\(\i\))/, + match: /(?<=getChannel\(\i\);return null!=(\i))(?=.{0,150}?>0\)&&\(0,\i\.\i\)\(\i\))/, replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})` } }, @@ -289,7 +289,7 @@ export default definePlugin({ }, { // If the @everyone role has the required permissions, make the array only contain it - match: /computePermissionsForRoles.+?.value\(\)(?<=channel:(\i).+?)/, + match: /forceRoles:.+?.value\(\)(?<=channel:(\i).+?)/, replace: (m, channel) => `${m}.reduce(...$self.makeAllowedRolesReduce(${channel}.guild_id))` }, { @@ -422,7 +422,7 @@ export default definePlugin({ }, { // Avoid filtering out hidden channels from the channel list - match: /(?<=queryChannels\(\i\){.+?isGuildChannelType\)\((\i)\.type\))(?=&&!\i\.\i\.can\()/, + match: /(?<=queryChannels\(\i\){.+?\)\((\i)\.type\))(?=&&!\i\.\i\.can\()/, replace: "&&!$self.isHiddenChannel($1)" } ] diff --git a/src/plugins/superReactionTweaks/index.ts b/src/plugins/superReactionTweaks/index.ts index 7878ba63..1a5e3a98 100644 --- a/src/plugins/superReactionTweaks/index.ts +++ b/src/plugins/superReactionTweaks/index.ts @@ -47,9 +47,9 @@ export default definePlugin({ } }, { - find: ".trackEmojiSearchEmpty,200", + find: ".EMOJI_PICKER_CONSTANTS_EMOJI_CONTAINER_PADDING_HORIZONTAL)", replacement: { - match: /(\.trackEmojiSearchEmpty,200(?=.+?isBurstReaction:(\i).+?(\i===\i\.EmojiIntention.REACTION)).+?\[\2,\i\]=\i\.useState\().+?\)/, + match: /(openPopoutType:void 0(?=.+?isBurstReaction:(\i).+?(\i===\i\.\i.REACTION)).+?\[\2,\i\]=\i\.useState\().+?\)/, replace: (_, rest, isBurstReactionVariable, isReactionIntention) => `${rest}$self.shouldSuperReactByDefault&&${isReactionIntention})` } } diff --git a/src/plugins/validReply/index.ts b/src/plugins/validReply/index.ts index 21a1bdd1..b65496f4 100644 --- a/src/plugins/validReply/index.ts +++ b/src/plugins/validReply/index.ts @@ -6,7 +6,7 @@ import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; -import { findByPropsLazy } from "@webpack"; +import { findByCodeLazy } from "@webpack"; import { FluxDispatcher, RestAPI } from "@webpack/common"; import { Message, User } from "discord-types/general"; import { Channel } from "discord-types/general/index.js"; @@ -29,7 +29,7 @@ interface Reply { const fetching = new Map(); let ReplyStore: any; -const { createMessageRecord } = findByPropsLazy("createMessageRecord"); +const createMessageRecord = findByCodeLazy(".createFromServer(", ".isBlockedForMessage", "messageReference:"); export default definePlugin({ name: "ValidReply", diff --git a/src/webpack/common/types/utils.d.ts b/src/webpack/common/types/utils.d.ts index 166a25fe..1cd2bf69 100644 --- a/src/webpack/common/types/utils.d.ts +++ b/src/webpack/common/types/utils.d.ts @@ -219,4 +219,5 @@ export interface IconUtils { export interface Constants { Endpoints: Record; UserFlags: Record; + FriendsSections: Record; } diff --git a/src/webpack/common/utils.ts b/src/webpack/common/utils.ts index dd78dc4e..a724769c 100644 --- a/src/webpack/common/utils.ts +++ b/src/webpack/common/utils.ts @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import { canonicalizeMatch } from "@utils/patches"; import type { Channel } from "discord-types/general"; // eslint-disable-next-line path-alias/no-relative @@ -40,7 +41,8 @@ waitFor(["dispatchToLastSubscribed"], m => ComponentDispatch = m); export const Constants: t.Constants = mapMangledModuleLazy('ME:"/users/@me"', { Endpoints: filters.byProps("USER", "ME"), - UserFlags: filters.byProps("STAFF", "SPAMMER") + UserFlags: filters.byProps("STAFF", "SPAMMER"), + FriendsSections: m => m.PENDING === "PENDING" && m.ADD_FRIEND }); export const RestAPI: t.RestAPI = findLazy(m => typeof m === "object" && m.del && m.put); @@ -157,3 +159,10 @@ export const UserProfileActions = findByPropsLazy("openUserProfileModal", "close export const InviteActions = findByPropsLazy("resolveInvite"); export const IconUtils: t.IconUtils = findByPropsLazy("getGuildBannerURL", "getUserAvatarURL"); + +const openExpressionPickerMatcher = canonicalizeMatch(/setState\({activeView:\i/); +// TODO: type +export const ExpressionPickerStore = mapMangledModuleLazy("expression-picker-last-active-view", { + closeExpressionPicker: filters.byCode("setState({activeView:null"), + openExpressionPicker: m => typeof m === "function" && openExpressionPickerMatcher.test(m.toString()), +}); diff --git a/src/webpack/webpack.ts b/src/webpack/webpack.ts index daca1892..b536063e 100644 --- a/src/webpack/webpack.ts +++ b/src/webpack/webpack.ts @@ -106,7 +106,7 @@ export const find = traceFunction("find", function find(filter: FilterFn, { isIn for (const key in cache) { const mod = cache[key]; - if (!mod?.exports) continue; + if (!mod.loaded || !mod?.exports) continue; if (filter(mod.exports)) { return isWaitFor ? [mod.exports, key] : mod.exports; @@ -142,7 +142,7 @@ export function findAll(filter: FilterFn) { const ret = [] as any[]; for (const key in cache) { const mod = cache[key]; - if (!mod?.exports) continue; + if (!mod.loaded || !mod?.exports) continue; if (filter(mod.exports)) ret.push(mod.exports); @@ -190,7 +190,7 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns outer: for (const key in cache) { const mod = cache[key]; - if (!mod?.exports) continue; + if (!mod.loaded || !mod?.exports) continue; for (let j = 0; j < length; j++) { const filter = filters[j]; @@ -486,7 +486,7 @@ export function mapMangledModuleLazy(code: string, mappers: Re return proxyLazy(() => mapMangledModule(code, mappers)); } -export const DefaultExtractAndLoadChunksRegex = /(?:(?:Promise\.all\(\[)?(\i\.e\("[^)]+?"\)[^\]]*?)(?:\]\))?|Promise\.resolve\(\))\.then\(\i\.bind\(\i,"([^)]+?)"\)\)/; +export const DefaultExtractAndLoadChunksRegex = /(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?|Promise\.resolve\(\))\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/; export const ChunkIdsRegex = /\("([^"]+?)"\)/g; /** From 7b6259215aec468d694fd2c1c5d63645782910eb Mon Sep 17 00:00:00 2001 From: Vendicated Date: Wed, 19 Jun 2024 07:38:21 +0200 Subject: [PATCH 2/7] Fix VoiceMessages --- src/plugins/voiceMessages/index.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/voiceMessages/index.tsx b/src/plugins/voiceMessages/index.tsx index 40e877df..8365bb51 100644 --- a/src/plugins/voiceMessages/index.tsx +++ b/src/plugins/voiceMessages/index.tsx @@ -27,7 +27,7 @@ import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModa import { useAwaiter } from "@utils/react"; import definePlugin from "@utils/types"; import { chooseFile } from "@utils/web"; -import { findByPropsLazy, findStoreLazy } from "@webpack"; +import { findByPropsLazy, findLazy, findStoreLazy } from "@webpack"; import { Button, Card, Constants, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from "@webpack/common"; import { ComponentType } from "react"; @@ -37,7 +37,7 @@ import { cl } from "./utils"; import { VoicePreview } from "./VoicePreview"; import { VoiceRecorderWeb } from "./WebRecorder"; -const CloudUtils = findByPropsLazy("CloudUpload"); +const CloudUpload = findLazy(m => m.prototype?.trackUploadFinished); const PendingReplyStore = findStoreLazy("PendingReplyStore"); const OptionClasses = findByPropsLazy("optionName", "optionIcon", "optionLabel"); @@ -89,9 +89,8 @@ function sendAudio(blob: Blob, meta: AudioMetadata) { const reply = PendingReplyStore.getPendingReply(channelId); if (reply) FluxDispatcher.dispatch({ type: "DELETE_PENDING_REPLY", channelId }); - const upload = new CloudUtils.CloudUpload({ + const upload = new CloudUpload({ file: new File([blob], "voice-message.ogg", { type: "audio/ogg; codecs=opus" }), - isClip: false, isThumbnail: false, platform: 1, }, channelId, false, 0); From d04ead7d350dbff23aace7abd01050a28b4522fa Mon Sep 17 00:00:00 2001 From: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Date: Wed, 19 Jun 2024 02:38:24 -0300 Subject: [PATCH 3/7] FakeNitro: Fix theme bypass --- src/plugins/fakeNitro/index.tsx | 2 +- src/webpack/common/settingsStores.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/fakeNitro/index.tsx b/src/plugins/fakeNitro/index.tsx index 76c8f364..26e78ea2 100644 --- a/src/plugins/fakeNitro/index.tsx +++ b/src/plugins/fakeNitro/index.tsx @@ -49,7 +49,7 @@ function searchProtoClassField(localName: string, protoClass: any) { } const PreloadedUserSettingsActionCreators = proxyLazyWebpack(() => UserSettingsActionCreators.PreloadedUserSettingsActionCreators); -const AppearanceSettingsActionCreators = proxyLazyWebpack(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators)); +const AppearanceSettingsActionCreators = proxyLazyWebpack(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators.ProtoClass)); const ClientThemeSettingsActionsCreators = proxyLazyWebpack(() => searchProtoClassField("clientThemeSettings", AppearanceSettingsActionCreators)); diff --git a/src/webpack/common/settingsStores.ts b/src/webpack/common/settingsStores.ts index 2f5297bd..b00620b2 100644 --- a/src/webpack/common/settingsStores.ts +++ b/src/webpack/common/settingsStores.ts @@ -7,6 +7,6 @@ import { findLazy } from "@webpack"; export const UserSettingsActionCreators = { - FrecencyUserSettingsActionCreators: findLazy(m => m.typeName?.endsWith(".FrecencyUserSettings")), - PreloadedUserSettingsActionCreators: findLazy(m => m.typeName?.endsWith(".PreloadedUserSettings")), + FrecencyUserSettingsActionCreators: findLazy(m => m.ProtoClass?.typeName?.endsWith(".FrecencyUserSettings")), + PreloadedUserSettingsActionCreators: findLazy(m => m.ProtoClass?.typeName?.endsWith(".PreloadedUserSettings")), }; From 28ddadf732f68ccc11533b5f409e7f9d80a16c42 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Wed, 19 Jun 2024 16:19:39 +0200 Subject: [PATCH 4/7] Fix CustomIdle --- README.md | 5 ----- src/plugins/customidle/index.ts | 11 ++++------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e67db93a..61575d4b 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,3 @@ Regardless, if your account is very important to you and it getting disabled wou Additionally, make sure not to post screenshots with Vencord in a server where you might get banned for it - -```math -\ce{$\unicode[goombafont; color:red; z-index: -10; position: fixed; top: 0; left: 0; height: 100%; object-fit: cover; width: 100%; opacity: 1; background: url('https://github.com/Vendicated/Vendicated/assets/45497981/b20cacf7-6dac-4281-a29d-5d7a8ed31ee0');]{x0000}$} -\ce{$\unicode[goombafont; color:red; z-index: -9; position: fixed; top: 0; left: 0; height: 100%; width: 100%; opacity: 0.9; background: var(--bgColor-default);]{x0000}$} -``` diff --git a/src/plugins/customidle/index.ts b/src/plugins/customidle/index.ts index 87caea75..ea56da10 100644 --- a/src/plugins/customidle/index.ts +++ b/src/plugins/customidle/index.ts @@ -33,16 +33,13 @@ export default definePlugin({ authors: [Devs.newwares], settings, patches: [ - { - find: "IDLE_DURATION:function(){return", - replacement: { - match: /(IDLE_DURATION:function\(\){return )\i/, - replace: "$1$self.getIdleTimeout()" - } - }, { find: 'type:"IDLE",idle:', replacement: [ + { + match: /(?<=Date\.now\(\)-\i>)\i\.\i/, + replace: "$self.getIdleTimeout()" + }, { match: /Math\.min\((\i\.\i\.getSetting\(\)\*\i\.\i\.\i\.SECOND),\i\.\i\)/, replace: "$1" // Decouple idle from afk (phone notifications will remain at user setting or 10 min maximum) From d12624ac4b88ffc52daf43b1ba95e2c815035ead Mon Sep 17 00:00:00 2001 From: Vendicated Date: Wed, 19 Jun 2024 16:45:48 +0200 Subject: [PATCH 5/7] Fix ShowHiddenThings --- src/plugins/showHiddenThings/index.ts | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/plugins/showHiddenThings/index.ts b/src/plugins/showHiddenThings/index.ts index db4fe5aa..58269b36 100644 --- a/src/plugins/showHiddenThings/index.ts +++ b/src/plugins/showHiddenThings/index.ts @@ -64,18 +64,18 @@ export default definePlugin({ }, }, { - find: "useShouldShowInvitesDisabledNotif:", + find: "2022-07_invites_disabled", predicate: () => settings.store.showInvitesPaused, replacement: { - match: /\i\.\i\.can\(\i\.Permissions.MANAGE_GUILD,\i\)/, + match: /\i\.\i\.can\(\i\.\i.MANAGE_GUILD,\i\)/, replace: "true", }, }, { - find: "canAccessGuildMemberModViewWithExperiment:", + find: /context:\i,checkElevated:!1\}\),\i\.\i.{0,200}autoTrackExposure/, predicate: () => settings.store.showModView, replacement: { - match: /return \i\.hasAny\(\i\.computePermissions\(\{user:\i,context:\i,checkElevated:!1\}\),\i\.MemberSafetyPagePermissions\)/, + match: /return \i\.\i\(\i\.\i\(\{user:\i,context:\i,checkElevated:!1\}\),\i\.\i\)/, replace: "return true", } }, @@ -87,28 +87,31 @@ export default definePlugin({ replace: "{}" } }, + // remove the 200 server minimum { - find: "MINIMUM_MEMBER_COUNT:", + find: '">200"', predicate: () => settings.store.disableDiscoveryFilters, replacement: { - match: /MINIMUM_MEMBER_COUNT:function\(\)\{return \i}/, - replace: "MINIMUM_MEMBER_COUNT:() => \">0\"" + match: '">200"', + replace: '">0"' } }, + // empty word filter (why would anyone search "horny" in fucking server discovery... please... why are we patching this again??) { - find: "DiscoveryBannedSearchWords.includes", + find: '"horny","fart"', predicate: () => settings.store.disableDisallowedDiscoveryFilters, replacement: { - match: /(?<=function\(\){)(?=.{0,130}DiscoveryBannedSearchWords\.includes)/, - replace: "return false;" + match: /=\["egirl",.+?\]/, + replace: "=[]" } }, + // patch request that queries if term is allowed { - find: "Endpoints.GUILD_DISCOVERY_VALID_TERM", + find: ".GUILD_DISCOVERY_VALID_TERM", predicate: () => settings.store.disableDisallowedDiscoveryFilters, all: true, replacement: { - match: /\i\.HTTP\.get\(\{url:\i\.Endpoints\.GUILD_DISCOVERY_VALID_TERM,query:\{term:\i\},oldFormErrors:!0\}\);/g, + match: /\i\.\i\.get\(\{url:\i\.\i\.GUILD_DISCOVERY_VALID_TERM,query:\{term:\i\},oldFormErrors:!0\}\);/g, replace: "Promise.resolve({ body: { valid: true } });" } } From 920f3260533620fae577268ecf177d4727b6bcb5 Mon Sep 17 00:00:00 2001 From: ryan-0324 <77452312+ryan-0324@users.noreply.github.com> Date: Wed, 19 Jun 2024 10:56:01 -0400 Subject: [PATCH 6/7] fix MoreUserTags (#2599) --- src/plugins/index.ts | 18 +++-------------- src/plugins/moreUserTags/index.tsx | 32 ++++++++++++++++-------------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/plugins/index.ts b/src/plugins/index.ts index 45e182b8..29420d0c 100644 --- a/src/plugins/index.ts +++ b/src/plugins/index.ts @@ -19,7 +19,6 @@ import { registerCommand, unregisterCommand } from "@api/Commands"; import { addContextMenuPatch, removeContextMenuPatch } from "@api/ContextMenu"; import { Settings } from "@api/Settings"; -import { onceDefined } from "@shared/onceDefined"; import { Logger } from "@utils/Logger"; import { canonicalizeFind } from "@utils/patches"; import { Patch, Plugin, ReporterTestable, StartAt } from "@utils/types"; @@ -34,7 +33,7 @@ const logger = new Logger("PluginManager", "#a6d189"); export const PMLogger = logger; export const plugins = Plugins; -export let patches = [] as Patch[]; +export const patches = [] as Patch[]; /** Whether we have subscribed to flux events of all the enabled plugins when FluxDispatcher was ready */ let enabledPluginsSubscribedFlux = false; @@ -43,9 +42,6 @@ const subscribedFluxEventsPlugins = new Set(); const pluginsValues = Object.values(Plugins); const settings = Settings.plugins; -const forceDisabled = new Set([ - "MoreUserTags" -]); export function isPluginEnabled(p: string) { return ( Plugins[p]?.required || @@ -126,17 +122,9 @@ for (const p of pluginsValues) { } } -onceDefined(window, "GLOBAL_ENV", v => { - if (v.SENTRY_TAGS.buildId !== "366c746173a6ca0a801e9f4a4d7b6745e6de45d4") { - patches = patches.filter(p => !forceDisabled.has(p.plugin)); - } -}); - export const startAllPlugins = traceFunction("startAllPlugins", function startAllPlugins(target: StartAt) { logger.info(`Starting plugins (stage ${target})`); for (const name in Plugins) { - if (window.GLOBAL_ENV?.SENTRY_TAGS.buildId !== "366c746173a6ca0a801e9f4a4d7b6745e6de45d4" && forceDisabled.has(name)) continue; - if (isPluginEnabled(name) && (!IS_REPORTER || isReporterTestable(Plugins[name], ReporterTestable.Start))) { const p = Plugins[name]; @@ -207,7 +195,7 @@ export function subscribeAllPluginsFluxEvents(fluxDispatcher: typeof FluxDispatc } export const startPlugin = traceFunction("startPlugin", function startPlugin(p: Plugin) { - const { name, commands, flux, contextMenus } = p; + const { name, commands, contextMenus } = p; if (p.start) { logger.info("Starting plugin", name); @@ -253,7 +241,7 @@ export const startPlugin = traceFunction("startPlugin", function startPlugin(p: }, p => `startPlugin ${p.name}`); export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plugin) { - const { name, commands, flux, contextMenus } = p; + const { name, commands, contextMenus } = p; if (p.stop) { logger.info("Stopping plugin", name); diff --git a/src/plugins/moreUserTags/index.tsx b/src/plugins/moreUserTags/index.tsx index 9d2790d0..be81a8a8 100644 --- a/src/plugins/moreUserTags/index.tsx +++ b/src/plugins/moreUserTags/index.tsx @@ -21,12 +21,10 @@ import { Flex } from "@components/Flex"; import { Devs } from "@utils/constants"; import { Margins } from "@utils/margins"; import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy, findLazy } from "@webpack"; +import { findByCodeLazy, findLazy } from "@webpack"; import { Card, ChannelStore, Forms, GuildStore, PermissionsBits, Switch, TextInput, Tooltip, useState } from "@webpack/common"; -import { RC } from "@webpack/types"; -import { Channel, Message, User } from "discord-types/general"; - -type PermissionName = "CREATE_INSTANT_INVITE" | "KICK_MEMBERS" | "BAN_MEMBERS" | "ADMINISTRATOR" | "MANAGE_CHANNELS" | "MANAGE_GUILD" | "CHANGE_NICKNAME" | "MANAGE_NICKNAMES" | "MANAGE_ROLES" | "MANAGE_WEBHOOKS" | "MANAGE_GUILD_EXPRESSIONS" | "CREATE_GUILD_EXPRESSIONS" | "VIEW_AUDIT_LOG" | "VIEW_CHANNEL" | "VIEW_GUILD_ANALYTICS" | "VIEW_CREATOR_MONETIZATION_ANALYTICS" | "MODERATE_MEMBERS" | "SEND_MESSAGES" | "SEND_TTS_MESSAGES" | "MANAGE_MESSAGES" | "EMBED_LINKS" | "ATTACH_FILES" | "READ_MESSAGE_HISTORY" | "MENTION_EVERYONE" | "USE_EXTERNAL_EMOJIS" | "ADD_REACTIONS" | "USE_APPLICATION_COMMANDS" | "MANAGE_THREADS" | "CREATE_PUBLIC_THREADS" | "CREATE_PRIVATE_THREADS" | "USE_EXTERNAL_STICKERS" | "SEND_MESSAGES_IN_THREADS" | "CONNECT" | "SPEAK" | "MUTE_MEMBERS" | "DEAFEN_MEMBERS" | "MOVE_MEMBERS" | "USE_VAD" | "PRIORITY_SPEAKER" | "STREAM" | "USE_EMBEDDED_ACTIVITIES" | "USE_SOUNDBOARD" | "USE_EXTERNAL_SOUNDS" | "REQUEST_TO_SPEAK" | "MANAGE_EVENTS" | "CREATE_EVENTS"; +import type { Permissions, RC } from "@webpack/types"; +import type { Channel, Guild, Message, User } from "discord-types/general"; interface Tag { // name used for identifying, must be alphanumeric + underscores @@ -34,7 +32,7 @@ interface Tag { // name shown on the tag itself, can be anything probably; automatically uppercase'd displayName: string; description: string; - permissions?: PermissionName[]; + permissions?: Permissions[]; condition?(message: Message | null, user: User, channel: Channel): boolean; } @@ -54,10 +52,14 @@ interface TagSettings { [k: string]: TagSetting; } -// PermissionStore.computePermissions is not the same function and doesn't work here -const PermissionUtil = findByPropsLazy("computePermissions", "canEveryoneRole") as { - computePermissions({ ...args }): bigint; -}; +// PermissionStore.computePermissions will not work here since it only gets permissions for the current user +const computePermissions: (options: { + user?: { id: string; } | string | null; + context?: Guild | Channel | null; + overwrites?: Channel["permissionOverwrites"] | null; + checkElevated?: boolean /* = true */; + excludeGuildPermissions?: boolean /* = false */; +}) => bigint = findByCodeLazy(".getCurrentUser()", ".computeLurkerPermissionsAllowList()"); const Tag = findLazy(m => m.Types?.[0] === "BOT") as RC<{ type?: number, className?: string, useRemSizes?: boolean; }> & { Types: Record; }; @@ -193,7 +195,7 @@ export default definePlugin({ patches: [ // add tags to the tag list { - find: "BotTagTypes:", + find: ".ORIGINAL_POSTER=", replacement: { match: /\((\i)=\{\}\)\)\[(\i)\.BOT/, replace: "($1=$self.getTagTypes()))[$2.BOT" @@ -222,7 +224,7 @@ export default definePlugin({ }, // in messages { - find: "renderSystemTag:", + find: ".Types.ORIGINAL_POSTER", replacement: { match: /;return\((\(null==\i\?void 0:\i\.isSystemDM\(\).+?.Types.ORIGINAL_POSTER\)),null==(\i)\)/, replace: ";$1;$2=$self.getTag({...arguments[0],origType:$2,location:'chat'});return $2 == null" @@ -283,7 +285,7 @@ export default definePlugin({ const guild = GuildStore.getGuild(channel?.guild_id); if (!guild) return []; - const permissions = PermissionUtil.computePermissions({ user, context: guild, overwrites: channel.permissionOverwrites }); + const permissions = computePermissions({ user, context: guild, overwrites: channel.permissionOverwrites }); return Object.entries(PermissionsBits) .map(([perm, permInt]) => permissions & permInt ? perm : "" @@ -330,7 +332,7 @@ export default definePlugin({ }: { message?: Message, user: User & { isClyde(): boolean; }, - channel?: Channel & { isForumPost(): boolean; }, + channel?: Channel & { isForumPost(): boolean; isMediaPost(): boolean; }, channelId?: string; origType?: number; location: "chat" | "not-chat"; @@ -367,7 +369,7 @@ export default definePlugin({ tag.permissions?.some(perm => perms.includes(perm)) || (tag.condition?.(message!, user, channel)) ) { - if (channel.isForumPost() && channel.ownerId === user.id) + if ((channel.isForumPost() || channel.isMediaPost()) && channel.ownerId === user.id) type = Tag.Types[`${tag.name}-OP`]; else if (user.bot && !isWebhook(message!, user) && !settings.dontShowBotTag) type = Tag.Types[`${tag.name}-BOT`]; From e9e789be7093e8b025f606cde69b3d89760c9380 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Wed, 19 Jun 2024 16:59:40 +0200 Subject: [PATCH 7/7] fix NewGuildSettings --- src/plugins/newGuildSettings/index.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/newGuildSettings/index.tsx b/src/plugins/newGuildSettings/index.tsx index f1c29f25..6b9dfe35 100644 --- a/src/plugins/newGuildSettings/index.tsx +++ b/src/plugins/newGuildSettings/index.tsx @@ -19,10 +19,15 @@ import { definePluginSettings, migratePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { findByCodeLazy, findByPropsLazy } from "@webpack"; +import { findByCodeLazy, findByPropsLazy, mapMangledModuleLazy } from "@webpack"; const { updateGuildNotificationSettings } = findByPropsLazy("updateGuildNotificationSettings"); -const { toggleShowAllChannels } = findByPropsLazy("toggleShowAllChannels"); +const { toggleShowAllChannels } = mapMangledModuleLazy(".onboardExistingMember(", { + toggleShowAllChannels: m => { + const s = String(m); + return s.length < 100 && !s.includes("onboardExistingMember") && !s.includes("getOptedInChannels"); + } +}); const isOptInEnabledForGuild = findByCodeLazy(".COMMUNITY)||", ".isOptInEnabled("); const settings = definePluginSettings({