diff --git a/docs/1_INSTALLING.md b/docs/1_INSTALLING.md index d57e64e5..edeed4eb 100644 --- a/docs/1_INSTALLING.md +++ b/docs/1_INSTALLING.md @@ -1,6 +1,6 @@ -> [!WARNING] -> These instructions are only for advanced users. If you're not a Developer, you should use our [graphical installer](https://github.com/Vendicated/VencordInstaller#usage) instead. -> No support will be provided for installing in this fashion. If you cannot figure it out, you should just stick to a regular install. +> [!WARNING] +> These instructions are only for advanced users. If you're not a Developer, you should use our [graphical installer](https://github.com/Vendicated/VencordInstaller#usage) instead. +> No support will be provided for installing in this fashion. If you cannot figure it out, you should just stick to a regular install. # Installation Guide @@ -95,5 +95,3 @@ Simply run: ```shell pnpm uninject ``` - -If you need more help, ask in the support channel in our [Discord Server](https://discord.gg/D9uwnFnqmd). diff --git a/package.json b/package.json index 025fa13d..78370f09 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.7.3", + "version": "1.7.4", "description": "The cutest Discord client mod", "homepage": "https://github.com/Vendicated/Vencord#readme", "bugs": { diff --git a/scripts/generateReport.ts b/scripts/generateReport.ts index 33b099ef..41e38429 100644 --- a/scripts/generateReport.ts +++ b/scripts/generateReport.ts @@ -67,7 +67,8 @@ const IGNORED_DISCORD_ERRORS = [ "Unable to process domain list delta: Client revision number is null", "Downloading the full bad domains file", /\[GatewaySocket\].{0,110}Cannot access '/, - "search for 'name' in undefined" + "search for 'name' in undefined", + "Attempting to set fast connect zstd when unsupported" ] as Array; function toCodeBlock(s: string) { diff --git a/src/plugins/_api/chatButtons.ts b/src/plugins/_api/chatButtons.ts index ca85964c..1ec2fa25 100644 --- a/src/plugins/_api/chatButtons.ts +++ b/src/plugins/_api/chatButtons.ts @@ -13,10 +13,10 @@ export default definePlugin({ authors: [Devs.Ven], patches: [{ - find: 'location:"ChannelTextAreaButtons"', + find: '"sticker")', replacement: { - match: /if\(!\i\.isMobile\)\{(?=.+?&&(\i)\.push\(.{0,50}"gift")/, - replace: "$&Vencord.Api.ChatButtons._injectButtons($1,arguments[0]);" + match: /!\i\.isMobile(?=.+?(\i)\.push\(.{0,50}"gift")/, + replace: "$& &&(Vencord.Api.ChatButtons._injectButtons($1,arguments[0]),true)" } }] }); diff --git a/src/plugins/_api/memberListDecorators.ts b/src/plugins/_api/memberListDecorators.ts index 1251c357..5e3e5ed1 100644 --- a/src/plugins/_api/memberListDecorators.ts +++ b/src/plugins/_api/memberListDecorators.ts @@ -31,7 +31,7 @@ export default definePlugin({ match: /let\{[^}]*lostPermissionTooltipText:\i[^}]*\}=(\i),/, replace: "$&vencordProps=$1," }, { - match: /decorators:.{0,100}?children:\[/, + match: /\.Messages\.GUILD_OWNER(?=.+?decorators:(\i)\(\)).+?\1=?\(\)=>.+?children:\[/, replace: "$&...(typeof vencordProps=='undefined'?[]:Vencord.Api.MemberListDecorators.__getDecorators(vencordProps))," } ] diff --git a/src/plugins/_api/messageEvents.ts b/src/plugins/_api/messageEvents.ts index 1b4a2d15..48ae062c 100644 --- a/src/plugins/_api/messageEvents.ts +++ b/src/plugins/_api/messageEvents.ts @@ -35,7 +35,7 @@ export default definePlugin({ } }, { - find: ".handleSendMessage=", + find: ".handleSendMessage", 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) diff --git a/src/plugins/_api/notices.ts b/src/plugins/_api/notices.ts index 0648afa0..90ae6ded 100644 --- a/src/plugins/_api/notices.ts +++ b/src/plugins/_api/notices.ts @@ -26,7 +26,7 @@ export default definePlugin({ required: true, patches: [ { - find: 'displayName="NoticeStore"', + find: '"NoticeStore"', replacement: [ { match: /\i=null;(?=.{0,80}getPremiumSubscription\(\))/g, diff --git a/src/plugins/alwaysTrust/index.ts b/src/plugins/alwaysTrust/index.ts index 5113935f..b195e8eb 100644 --- a/src/plugins/alwaysTrust/index.ts +++ b/src/plugins/alwaysTrust/index.ts @@ -41,7 +41,7 @@ export default definePlugin({ authors: [Devs.zt, Devs.Trwy], patches: [ { - find: ".displayName=\"MaskedLinkStore\"", + find: '="MaskedLinkStore",', replacement: { match: /(?<=isTrustedDomain\(\i\){)return \i\(\i\)/, replace: "return true" diff --git a/src/plugins/betterGifAltText/index.ts b/src/plugins/betterGifAltText/index.ts index 8b411631..f0090343 100644 --- a/src/plugins/betterGifAltText/index.ts +++ b/src/plugins/betterGifAltText/index.ts @@ -26,7 +26,7 @@ export default definePlugin({ "Change GIF alt text from simply being 'GIF' to containing the gif tags / filename", patches: [ { - find: "onCloseImage=", + find: '"onCloseImage",', replacement: { match: /(return.{0,10}\.jsx.{0,50}isWindowFocused)/, replace: diff --git a/src/plugins/betterGifPicker/index.ts b/src/plugins/betterGifPicker/index.ts index 09bb570d..f1608f28 100644 --- a/src/plugins/betterGifPicker/index.ts +++ b/src/plugins/betterGifPicker/index.ts @@ -15,8 +15,8 @@ export default definePlugin({ { find: ".GIFPickerResultTypes.SEARCH", replacement: [{ - match: "this.state={resultType:null}", - replace: 'this.state={resultType:"Favorites"}' + match: /(?<="state",{resultType:)null/, + replace: '"Favorites"' }] } ] diff --git a/src/plugins/betterNotes/index.tsx b/src/plugins/betterNotes/index.tsx index da41b973..2183d98e 100644 --- a/src/plugins/betterNotes/index.tsx +++ b/src/plugins/betterNotes/index.tsx @@ -18,6 +18,7 @@ import { Settings } from "@api/Settings"; import { Devs } from "@utils/constants"; +import { canonicalizeMatch } from "@utils/patches"; import definePlugin, { OptionType } from "@utils/types"; import { findByPropsLazy } from "@webpack"; @@ -39,8 +40,12 @@ export default definePlugin({ match: /hideNote:.+?(?=([,}].*?\)))/g, replace: (m, rest) => { const destructuringMatch = rest.match(/}=.+/); - if (destructuringMatch == null) return "hideNote:!0"; - return m; + if (destructuringMatch) { + const defaultValueMatch = m.match(canonicalizeMatch(/hideNote:(\i)=!?\d/)); + return defaultValueMatch ? `hideNote:${defaultValueMatch[1]}=!0` : m; + } + + return "hideNote:!0"; } } }, @@ -52,10 +57,10 @@ export default definePlugin({ } }, { - find: ".Messages.NOTE}", + find: ".popularApplicationCommandIds,", replacement: { - match: /(?<=return \i\?)null(?=:\(0,\i\.jsxs)/, - replace: "$self.patchPadding(arguments[0])" + match: /lastSection:(!?\i)}\),/, + replace: "$&$self.patchPadding($1)," } } ], @@ -75,8 +80,8 @@ export default definePlugin({ } }, - patchPadding(e: any) { - if (!e.lastSection) return; + patchPadding(lastSection: any) { + if (!lastSection) return; return (
); diff --git a/src/plugins/betterSettings/index.tsx b/src/plugins/betterSettings/index.tsx index 6d3c8798..7d81c6f5 100644 --- a/src/plugins/betterSettings/index.tsx +++ b/src/plugins/betterSettings/index.tsx @@ -82,7 +82,7 @@ export default definePlugin({ find: "this.renderArtisanalHack()", replacement: [ { // Fade in on layer - match: /(?<=(\i)\.contextType=\i\.AccessibilityPreferencesContext;)/, + match: /(?<=\((\i),"contextType",\i\.AccessibilityPreferencesContext\);)/, replace: "$1=$self.Layer;", predicate: () => settings.store.disableFade }, @@ -107,11 +107,11 @@ export default definePlugin({ ], predicate: () => settings.store.disableFade }, - { // Load menu stuff on hover, not on click + { // Load menu TOC eagerly find: "Messages.USER_SETTINGS_WITH_BUILD_OVERRIDE.format", replacement: { - match: /(?<=handleOpenSettingsContextMenu.{0,250}?\i\.el\(("[^"]+")\)\.then\([^;]*?("\d+").*?Messages\.USER_SETTINGS,)(?=onClick:)/, - replace: "onMouseEnter(){Vencord.Webpack.wreq.el($1).then(()=>Vencord.Webpack.wreq($2));}," + match: /(?<=(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?openContextMenuLazy.{0,100}?(await Promise\.all[^};]*?\)\)).*?,)(?=\1\(this)/, + replace: "(async ()=>$2)()," }, predicate: () => settings.store.eagerLoad }, diff --git a/src/plugins/decor/index.tsx b/src/plugins/decor/index.tsx index 7b9b4e3b..d4f420c7 100644 --- a/src/plugins/decor/index.tsx +++ b/src/plugins/decor/index.tsx @@ -61,8 +61,8 @@ export default definePlugin({ }, // Remove NEW label from decor avatar decorations { - match: /(?<=\.Section\.PREMIUM_PURCHASE&&\i;if\()(?<=avatarDecoration:(\i).+?)/, - replace: "$1.skuId===$self.SKU_ID||" + match: /(?<=\.Section\.PREMIUM_PURCHASE&&\i)(?<=avatarDecoration:(\i).+?)/, + replace: "||$1.skuId===$self.SKU_ID" } ] }, diff --git a/src/plugins/disableCallIdle/index.ts b/src/plugins/disableCallIdle/index.ts index 904d53b0..d26f7281 100644 --- a/src/plugins/disableCallIdle/index.ts +++ b/src/plugins/disableCallIdle/index.ts @@ -29,7 +29,7 @@ export default definePlugin({ { find: ".Messages.BOT_CALL_IDLE_DISCONNECT", replacement: { - match: /,?(?=this\.idleTimeout=new \i\.Timeout)/, + match: /,?(?=\i\(this,"idleTimeout",new \i\.Timeout\))/, replace: ";return;" } }, diff --git a/src/plugins/experiments/index.tsx b/src/plugins/experiments/index.tsx index f8ea4b04..34463882 100644 --- a/src/plugins/experiments/index.tsx +++ b/src/plugins/experiments/index.tsx @@ -64,7 +64,7 @@ export default definePlugin({ } }, { - find: ".isStaff=()", + find: '"isStaff",', predicate: () => settings.store.enableIsStaff, replacement: [ { diff --git a/src/plugins/fakeNitro/index.tsx b/src/plugins/fakeNitro/index.tsx index 30744276..eb993195 100644 --- a/src/plugins/fakeNitro/index.tsx +++ b/src/plugins/fakeNitro/index.tsx @@ -277,7 +277,7 @@ export default definePlugin({ } }, { - find: '.displayName="UserSettingsProtoStore"', + find: '"UserSettingsProtoStore"', replacement: [ { // Overwrite incoming connection settings proto with our local settings @@ -388,6 +388,14 @@ export default definePlugin({ match: /\i\.\i\.isPremium\(\i\.\i\.getCurrentUser\(\)\)/, replace: "true" } + }, + // Make all Soundboard sounds available + { + find: 'type:"GUILD_SOUNDBOARD_SOUND_CREATE"', + replacement: { + match: /(?<=type:"(?:SOUNDBOARD_SOUNDS_RECEIVED|GUILD_SOUNDBOARD_SOUND_CREATE|GUILD_SOUNDBOARD_SOUND_UPDATE|GUILD_SOUNDBOARD_SOUNDS_UPDATE)".+?available:)\i\.available/g, + replace: "true" + } } ], diff --git a/src/plugins/gifPaste/index.ts b/src/plugins/gifPaste/index.ts index 3e864b31..5553bf84 100644 --- a/src/plugins/gifPaste/index.ts +++ b/src/plugins/gifPaste/index.ts @@ -29,10 +29,10 @@ export default definePlugin({ authors: [Devs.Ven], patches: [{ - find: ".handleSelectGIF=", + find: '"handleSelectGIF",', replacement: { - match: /\.handleSelectGIF=(\i)=>\{/, - replace: ".handleSelectGIF=$1=>{if (!this.props.className) return $self.handleSelect($1);" + match: /"handleSelectGIF",(\i)=>\{/, + replace: '"handleSelectGIF",$1=>{if (!this.props.className) return $self.handleSelect($1);' } }], diff --git a/src/plugins/ignoreActivities/index.tsx b/src/plugins/ignoreActivities/index.tsx index c04ce1c5..e2262129 100644 --- a/src/plugins/ignoreActivities/index.tsx +++ b/src/plugins/ignoreActivities/index.tsx @@ -210,10 +210,10 @@ export default definePlugin({ patches: [ { - find: '.displayName="LocalActivityStore"', + find: '="LocalActivityStore",', replacement: [ { - match: /HANG_STATUS.+?(?=!\i\(\i,\i\)&&)(?<=(\i)\.push.+?)/, + match: /HANG_STATUS.+?(?=!\i\(\)\(\i,\i\)&&)(?<=(\i)\.push.+?)/, replace: (m, activities) => `${m}${activities}=${activities}.filter($self.isActivityNotIgnored);` } ] diff --git a/src/plugins/imageZoom/index.tsx b/src/plugins/imageZoom/index.tsx index cbaa07d2..3f0e3294 100644 --- a/src/plugins/imageZoom/index.tsx +++ b/src/plugins/imageZoom/index.tsx @@ -23,7 +23,7 @@ import { makeRange } from "@components/PluginSettings/components"; import { debounce } from "@shared/debounce"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { Menu, React, ReactDOM } from "@webpack/common"; +import { Menu, ReactDOM } from "@webpack/common"; import type { Root } from "react-dom/client"; import { Magnifier, MagnifierProps } from "./components/Magnifier"; @@ -168,7 +168,7 @@ export default definePlugin({ }, { - find: "handleImageLoad=", + find: ".handleImageLoad)", replacement: [ { match: /placeholderVersion:\i,/, diff --git a/src/plugins/loadingQuotes/index.ts b/src/plugins/loadingQuotes/index.ts index eed5b3ec..97178979 100644 --- a/src/plugins/loadingQuotes/index.ts +++ b/src/plugins/loadingQuotes/index.ts @@ -81,11 +81,11 @@ export default definePlugin({ find: ".LOADING_DID_YOU_KNOW}", replacement: [ { - match: /\._loadingText=function\(\)\{/, + match: /"_loadingText",function\(\)\{/, replace: "$&return $self.quote;", }, { - match: /\._eventLoadingText=function\(\)\{/, + match: /"_eventLoadingText",function\(\)\{/, replace: "$&return $self.quote;", predicate: () => settings.store.replaceEvents } diff --git a/src/plugins/messageLogger/index.tsx b/src/plugins/messageLogger/index.tsx index 26409b89..8a1e2391 100644 --- a/src/plugins/messageLogger/index.tsx +++ b/src/plugins/messageLogger/index.tsx @@ -225,7 +225,7 @@ export default definePlugin({ { // MessageStore // Module 171447 - find: "displayName=\"MessageStore\"", + find: '"MessageStore"', replacement: [ { // Add deleted=true to all target messages in the MESSAGE_DELETE event @@ -380,7 +380,7 @@ export default definePlugin({ { // ReferencedMessageStore // Module 778667 - find: "displayName=\"ReferencedMessageStore\"", + find: '"ReferencedMessageStore"', replacement: [ { match: /MESSAGE_DELETE:function\((\i)\).+?},/, diff --git a/src/plugins/noBlockedMessages/index.ts b/src/plugins/noBlockedMessages/index.ts index f9de3e13..427f725c 100644 --- a/src/plugins/noBlockedMessages/index.ts +++ b/src/plugins/noBlockedMessages/index.ts @@ -38,8 +38,8 @@ export default definePlugin({ ] }, ...[ - 'displayName="MessageStore"', - 'displayName="ReadStateStore"' + '="MessageStore",', + '"displayName","ReadStateStore")' ].map(find => ({ find, predicate: () => Settings.plugins.NoBlockedMessages.ignoreBlockedMessages === true, diff --git a/src/plugins/noRPC.discordDesktop/index.ts b/src/plugins/noRPC.discordDesktop/index.ts index ebbbd5e8..4c6319e5 100644 --- a/src/plugins/noRPC.discordDesktop/index.ts +++ b/src/plugins/noRPC.discordDesktop/index.ts @@ -27,7 +27,7 @@ export default definePlugin({ { find: '.ensureModule("discord_rpc")', replacement: { - match: /\.ensureModule\("discord_rpc"\)\.then\(\(.+?\)\)}/, + match: /\.ensureModule\("discord_rpc"\)\.then\(\(.+?\)}\)}/, replace: '.ensureModule("discord_rpc")}', }, }, diff --git a/src/plugins/pinDms/components/CreateCategoryModal.tsx b/src/plugins/pinDms/components/CreateCategoryModal.tsx index f38cc88c..309ca69f 100644 --- a/src/plugins/pinDms/components/CreateCategoryModal.tsx +++ b/src/plugins/pinDms/components/CreateCategoryModal.tsx @@ -31,9 +31,9 @@ interface ColorPickerWithSwatchesProps { } const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); -const ColorPickerWithSwatches = findComponentByCodeLazy(".presets,", "customColor:"); +const ColorPickerWithSwatches = findComponentByCodeLazy("presets,", "customColor:"); -export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}el\("(.+?)"\).{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/pinDms/index.tsx b/src/plugins/pinDms/index.tsx index ee726bfa..8951f094 100644 --- a/src/plugins/pinDms/index.tsx +++ b/src/plugins/pinDms/index.tsx @@ -79,11 +79,11 @@ export default definePlugin({ // Rendering { - match: /this\.renderDM=\(.+?(\i\.default),{channel.+?this.renderRow=(\i)=>{/, - replace: "$&if($self.isChannelIndex($2.section, $2.row))return $self.renderChannel($2.section,$2.row,$1);" + match: /"renderRow",(\i)=>{(?<="renderDM",.+?(\i\.default),\{channel:.+?)/, + replace: "$&if($self.isChannelIndex($1.section, $1.row))return $self.renderChannel($1.section,$1.row,$2);" }, { - match: /this\.renderSection=(\i)=>{/, + match: /"renderSection",(\i)=>{/, replace: "$&if($self.isCategoryIndex($1.section))return $self.renderCategory($1);" }, { @@ -93,11 +93,11 @@ export default definePlugin({ // Fix Row Height { - match: /(?<=this\.getRowHeight=.{1,100}return 1===)\i/, + match: /(?<="getRowHeight",.{1,100}return 1===)\i/, replace: "($&-$self.categoryLen())" }, { - match: /this.getRowHeight=\((\i),(\i)\)=>{/, + match: /"getRowHeight",\((\i),(\i)\)=>{/, replace: "$&if($self.isChannelHidden($1,$2))return 0;" }, diff --git a/src/plugins/readAllNotificationsButton/index.tsx b/src/plugins/readAllNotificationsButton/index.tsx index 0e08edb6..ae66e11a 100644 --- a/src/plugins/readAllNotificationsButton/index.tsx +++ b/src/plugins/readAllNotificationsButton/index.tsx @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +import "./style.css"; + import { addServerListElement, removeServerListElement, ServerListRenderPosition } from "@api/ServerList"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; @@ -49,9 +51,11 @@ const ReadAllButton = () => ( + color={Button.Colors.CUSTOM} + className="vc-ranb-button" + > + Read All + ); export default definePlugin({ diff --git a/src/plugins/readAllNotificationsButton/style.css b/src/plugins/readAllNotificationsButton/style.css new file mode 100644 index 00000000..3d10b2bd --- /dev/null +++ b/src/plugins/readAllNotificationsButton/style.css @@ -0,0 +1,11 @@ +.vc-ranb-button { + color: var(--interactive-normal); + padding: 0 0.5em; + margin-bottom: 0.5em; + width: 100%; + box-sizing: border-box; +} + +.vc-ranb-button:hover { + color: var(--interactive-active); +} diff --git a/src/plugins/resurrectHome/index.tsx b/src/plugins/resurrectHome/index.tsx index 6b0069a7..f48debc7 100644 --- a/src/plugins/resurrectHome/index.tsx +++ b/src/plugins/resurrectHome/index.tsx @@ -59,7 +59,7 @@ export default definePlugin({ find: "GuildHomeFeedbackExperiment.definition.id", replacement: [ { - match: /return{showFeedback:\i,setOnDismissedFeedback:(\i)}/, + match: /return{showFeedback:.+?,setOnDismissedFeedback:(\i)}/, replace: "return{showFeedback:false,setOnDismissedFeedback:$1}" } ] diff --git a/src/plugins/revealAllSpoilers/index.ts b/src/plugins/revealAllSpoilers/index.ts index 746973b4..e728181a 100644 --- a/src/plugins/revealAllSpoilers/index.ts +++ b/src/plugins/revealAllSpoilers/index.ts @@ -30,9 +30,9 @@ export default definePlugin({ patches: [ { - find: ".removeObscurity=", + find: ".removeObscurity,", replacement: { - match: /(?<=\.removeObscurity=(\i)=>{)/, + match: /(?<="removeObscurity",(\i)=>{)/, replace: (_, event) => `$self.reveal(${event});` } } diff --git a/src/plugins/secretRingTone/index.ts b/src/plugins/secretRingTone/index.ts index 9d6d6a15..8f0176f8 100644 --- a/src/plugins/secretRingTone/index.ts +++ b/src/plugins/secretRingTone/index.ts @@ -16,7 +16,7 @@ export default definePlugin({ { find: "call_ringing_beat\"", replacement: { - match: /500===\i\.random\(1,1e3\)/, + match: /500===\i\(\)\.random\(1,1e3\)/, replace: "true" } }, diff --git a/src/plugins/showHiddenChannels/index.tsx b/src/plugins/showHiddenChannels/index.tsx index 2d091c24..31dc93ad 100644 --- a/src/plugins/showHiddenChannels/index.tsx +++ b/src/plugins/showHiddenChannels/index.tsx @@ -138,7 +138,7 @@ export default definePlugin({ all: true, // Render null instead of the buttons if the channel is hidden replacement: { - match: /(?<=renderOpenChatButton=\(\)=>{)/, + match: /(?<="renderOpenChatButton",\(\)=>{)/, replace: "if($self.isHiddenChannel(this.props.channel))return null;" } }, @@ -191,10 +191,10 @@ export default definePlugin({ }, { // Hide the new version of unreads box for hidden channels - find: '.displayName="ChannelListUnreadsStore"', + find: '="ChannelListUnreadsStore",', replacement: { - match: /(?<=if\(null==(\i))(?=.{0,160}?getHasImportantUnread\)\(\i\))/g, // Global because Discord has multiple methods like that in the same module - replace: (_, channel) => `||$self.isHiddenChannel(${channel})` + match: /(?=&&\(0,\i\.getHasImportantUnread\)\((\i)\))/g, // Global because Discord has multiple methods like that in the same module + replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})` } }, { @@ -218,19 +218,19 @@ export default definePlugin({ find: "Missing channel in Channel.renderHeaderToolbar", replacement: [ { - match: /(?<=renderHeaderToolbar=\(\)=>{.+?case \i\.\i\.GUILD_TEXT:)(?=.+?(\i\.push.{0,50}channel:(\i)},"notifications"\)\)))(?<=isLurking:(\i).+?)/, + match: /(?<="renderHeaderToolbar",\(\)=>{.+?case \i\.\i\.GUILD_TEXT:)(?=.+?(\i\.push.{0,50}channel:(\i)},"notifications"\)\)))(?<=isLurking:(\i).+?)/, replace: (_, pushNotificationButtonExpression, channel, isLurking) => `if(!${isLurking}&&$self.isHiddenChannel(${channel})){${pushNotificationButtonExpression};break;}` }, { - match: /(?<=renderHeaderToolbar=\(\)=>{.+?case \i\.\i\.GUILD_MEDIA:)(?=.+?(\i\.push.{0,40}channel:(\i)},"notifications"\)\)))(?<=isLurking:(\i).+?)/, + match: /(?<="renderHeaderToolbar",\(\)=>{.+?case \i\.\i\.GUILD_MEDIA:)(?=.+?(\i\.push.{0,40}channel:(\i)},"notifications"\)\)))(?<=isLurking:(\i).+?)/, replace: (_, pushNotificationButtonExpression, channel, isLurking) => `if(!${isLurking}&&$self.isHiddenChannel(${channel})){${pushNotificationButtonExpression};break;}` }, { - match: /renderMobileToolbar=\(\)=>{.+?case \i\.\i\.GUILD_DIRECTORY:(?<=let{channel:(\i).+?)/, + match: /"renderMobileToolbar",\(\)=>{.+?case \i\.\i\.GUILD_DIRECTORY:(?<=let{channel:(\i).+?)/, replace: (m, channel) => `${m}if($self.isHiddenChannel(${channel}))break;` }, { - match: /(?<=renderHeaderBar=\(\)=>{.+?hideSearch:(\i)\.isDirectory\(\))/, + match: /(?<="renderHeaderBar",\(\)=>{.+?hideSearch:(\i)\.isDirectory\(\))/, replace: (_, channel) => `||$self.isHiddenChannel(${channel})` }, { @@ -442,7 +442,7 @@ export default definePlugin({ } }, { - find: '.displayName="GuildChannelStore"', + find: '="GuildChannelStore",', replacement: [ { // Make GuildChannelStore contain hidden channels @@ -465,7 +465,7 @@ export default definePlugin({ } }, { - find: '.displayName="NowPlayingViewStore"', + find: '="NowPlayingViewStore",', replacement: { // Make active now voice states on hidden channels match: /(getVoiceStateForUser.{0,150}?)&&\i\.\i\.canWithPartialContext.{0,20}VIEW_CHANNEL.+?}\)(?=\?)/, diff --git a/src/plugins/spotifyCrack/index.ts b/src/plugins/spotifyCrack/index.ts index 5d890349..1beccad6 100644 --- a/src/plugins/spotifyCrack/index.ts +++ b/src/plugins/spotifyCrack/index.ts @@ -51,7 +51,7 @@ export default definePlugin({ }, }, { - find: '.displayName="SpotifyStore"', + find: '"displayName","SpotifyStore")', replacement: [ { predicate: () => settings.store.noSpotifyAutoPause, diff --git a/src/plugins/userVoiceShow/index.tsx b/src/plugins/userVoiceShow/index.tsx index 935ff1c5..200cfe89 100644 --- a/src/plugins/userVoiceShow/index.tsx +++ b/src/plugins/userVoiceShow/index.tsx @@ -98,8 +98,8 @@ export default definePlugin({ { find: ".popularApplicationCommandIds,", replacement: { - match: /\(0,\i\.jsx\)\(\i\.\i,{user:\i,setNote/, - replace: "$self.patchPopout(arguments[0]),$&", + match: /applicationId:\i\.id}\),(?=.{0,50}setNote:\i)/, + replace: "$&$self.patchPopout(arguments[0]),", } }, // below username diff --git a/src/plugins/volumeBooster.discordDesktop/index.ts b/src/plugins/volumeBooster.discordDesktop/index.ts index 4aca79fc..b455c97e 100644 --- a/src/plugins/volumeBooster.discordDesktop/index.ts +++ b/src/plugins/volumeBooster.discordDesktop/index.ts @@ -71,7 +71,7 @@ export default definePlugin({ }, // Prevent the MediaEngineStore from overwriting our LocalVolumes above 200 with the ones the Discord Audio Context Settings sync sends { - find: '.displayName="MediaEngineStore"', + find: '="MediaEngineStore",', replacement: [ { match: /(\.settings\.audioContextSettings.+?)(\i\[\i\])=(\i\.volume)(.+?setLocalVolume\(\i,).+?\)/, diff --git a/src/plugins/webContextMenus.web/index.ts b/src/plugins/webContextMenus.web/index.ts index faa24078..ac468903 100644 --- a/src/plugins/webContextMenus.web/index.ts +++ b/src/plugins/webContextMenus.web/index.ts @@ -195,7 +195,7 @@ export default definePlugin({ // Add back "Show My Camera" context menu { - find: '.default("MediaEngineWebRTC");', + find: '"MediaEngineWebRTC");', replacement: { match: /supports\(\i\)\{switch\(\i\)\{case (\i).Features/, replace: "$&.DISABLE_VIDEO:return true;case $1.Features" diff --git a/src/plugins/whoReacted/index.tsx b/src/plugins/whoReacted/index.tsx index b6036690..b3728c21 100644 --- a/src/plugins/whoReacted/index.tsx +++ b/src/plugins/whoReacted/index.tsx @@ -93,28 +93,30 @@ export default definePlugin({ description: "Renders the avatars of users who reacted to a message", authors: [Devs.Ven, Devs.KannaDev, Devs.newwares], - patches: [{ - find: ",reactionRef:", - replacement: { - match: /(\i)\?null:\(0,\i\.jsx\)\(\i\.\i,{className:\i\.reactionCount,.*?}\),/, - replace: "$&$1?null:$self.renderUsers(this.props)," - } - }, { - find: '.displayName="MessageReactionsStore";', - replacement: { - match: /(?<=CONNECTION_OPEN:function\(\){)(\i)={}/, - replace: "$&;$self.reactions=$1" - } - }, - { + patches: [ + { + find: ",reactionRef:", + replacement: { + match: /(\i)\?null:\(0,\i\.jsx\)\(\i\.\i,{className:\i\.reactionCount,.*?}\),/, + replace: "$&$1?null:$self.renderUsers(this.props)," + } + }, { + find: '"MessageReactionsStore"', + replacement: { + match: /(?<=CONNECTION_OPEN:function\(\){)(\i)={}/, + replace: "$&;$self.reactions=$1" + } + }, + { - find: "cleanAutomaticAnchor(){", - replacement: { - match: /this\.automaticAnchor=null,this\.messageFetchAnchor=null,/, - replace: "$&$self.setScrollObj(this)," + find: "cleanAutomaticAnchor(){", + replacement: { + match: /constructor\(\i\)\{(?=.{0,100}automaticAnchor)/, + replace: "$&$self.setScrollObj(this);" + } } - } ], + setScrollObj(scroll: any) { Scroll = scroll; }, diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index f3a18d7b..2f9786bc 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -44,7 +44,6 @@ export let PermissionStore: GenericStore; export let GuildChannelStore: GenericStore; export let ReadStateStore: GenericStore; export let PresenceStore: GenericStore; -export let PoggerModeSettingsStore: GenericStore; export let GuildStore: t.GuildStore; export let UserStore: Stores.UserStore & t.FluxStore; diff --git a/src/webpack/webpack.ts b/src/webpack/webpack.ts index 992bf38f..0790e8bf 100644 --- a/src/webpack/webpack.ts +++ b/src/webpack/webpack.ts @@ -110,13 +110,13 @@ 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?.exports || mod.exports === window) continue; if (filter(mod.exports)) { return isWaitFor ? [mod.exports, key] : mod.exports; } - if (mod.exports.default && filter(mod.exports.default)) { + if (mod.exports.default && mod.exports.default !== window && filter(mod.exports.default)) { const found = mod.exports.default; return isWaitFor ? [found, key] : found; } @@ -408,10 +408,11 @@ export function findExportedComponentLazy(...props: stri /** * Extract and load chunks using their entry point - * @param code An array of all the code the module factory containing the entry point (as of using it to load chunks) must include - * @param matcher A RegExp that returns the entry point id as the first capture group. Defaults to a matcher that captures the first entry point found in the module factory + * @param code An array of all the code the module factory containing the lazy chunk loading must include + * @param matcher A RegExp that returns the chunk ids array as the first capture group and the entry point id as the second. Defaults to a matcher that captures the lazy chunk loading found in the module factory + * @returns A promise that resolves when the chunks were loaded */ -export async function extractAndLoadChunks(code: string[], matcher: RegExp = /\.el\("(.+?)"\)(?<=(\i)\.el.+?)\.then\(\2\.bind\(\2,"\1"\)\)/) { +export async function extractAndLoadChunks(code: string[], matcher: RegExp = /Promise\.all\((\[\i\.\i\(".+?"\).+?\])\).then\(\i\.bind\(\i,"(.+?)"\)\)/) { const module = findModuleFactory(...code); if (!module) { const err = new Error("extractAndLoadChunks: Couldn't find module factory"); @@ -432,9 +433,9 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = /\. return; } - const [, id] = match; - if (!id || !Number(id)) { - const err = new Error("extractAndLoadChunks: Matcher didn't return a capturing group with the entry point, or the entry point returned wasn't a number"); + const [, rawChunkIds, entryPointId] = match; + if (!rawChunkIds || Number.isNaN(entryPointId)) { + const err = new Error("extractAndLoadChunks: Matcher didn't return a capturing group with the chunk ids array, or the entry point id returned as the second group wasn't a number"); logger.warn(err, "Code:", code, "Matcher:", matcher); // Strict behaviour in DevBuilds to fail early and make sure the issue is found @@ -444,19 +445,21 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = /\. return; } - await (wreq as any).el(id); - return wreq(id as any); + const chunkIds = Array.from(rawChunkIds.matchAll(/\("(.+?)"\)/g)).map((m: any) => m[1]); + + await Promise.all(chunkIds.map(id => wreq.e(id))); + wreq(entryPointId); } /** * This is just a wrapper around {@link extractAndLoadChunks} to make our reporter test for your webpack finds. * * Extract and load chunks using their entry point - * @param code An array of all the code the module factory containing the entry point (as of using it to load chunks) must include - * @param matcher A RegExp that returns the entry point id as the first capture group. Defaults to a matcher that captures the first entry point found in the module factory - * @returns A function that loads the chunks on first call + * @param code An array of all the code the module factory containing the lazy chunk loading must include + * @param matcher A RegExp that returns the chunk ids array as the first capture group and the entry point id as the second. Defaults to a matcher that captures the lazy chunk loading found in the module factory + * @returns A function that returns a promise that resolves when the chunks were loaded, on first call */ -export function extractAndLoadChunksLazy(code: string[], matcher: RegExp = /\.el\("(.+?)"\)(?<=(\i)\.el.+?)\.then\(\2\.bind\(\2,"\1"\)\)/) { +export function extractAndLoadChunksLazy(code: string[], matcher: RegExp = /Promise\.all\((\[\i\.\i\(".+?"\).+?\])\).then\(\i\.bind\(\i,"(.+?)"\)\)/) { if (IS_DEV) lazyWebpackSearchHistory.push(["extractAndLoadChunks", [code, matcher]]); return () => extractAndLoadChunks(code, matcher);