diff options
-rw-r--r-- | src/plugins/apiNotices.ts | 7 | ||||
-rw-r--r-- | src/plugins/crashHandler.ts | 4 | ||||
-rw-r--r-- | src/plugins/disableDMCallIdle.ts | 10 | ||||
-rw-r--r-- | src/plugins/experiments.tsx | 90 | ||||
-rw-r--r-- | src/plugins/fakeNitro.ts | 22 | ||||
-rw-r--r-- | src/plugins/ignoreActivities.tsx | 65 | ||||
-rw-r--r-- | src/plugins/moyai.ts | 53 | ||||
-rw-r--r-- | src/plugins/noScreensharePreview.ts | 8 | ||||
-rw-r--r-- | src/plugins/pronoundb/index.ts | 10 | ||||
-rw-r--r-- | src/plugins/revealAllSpoilers.ts | 4 | ||||
-rw-r--r-- | src/plugins/showHiddenChannels/index.tsx | 191 | ||||
-rw-r--r-- | src/plugins/spotifyCrack.ts | 78 | ||||
-rw-r--r-- | src/plugins/typingIndicator.tsx | 4 | ||||
-rw-r--r-- | src/plugins/volumeBooster.ts | 56 | ||||
-rw-r--r-- | src/plugins/whoReacted.tsx | 4 |
15 files changed, 324 insertions, 282 deletions
diff --git a/src/plugins/apiNotices.ts b/src/plugins/apiNotices.ts index 8922ace..af7cb15 100644 --- a/src/plugins/apiNotices.ts +++ b/src/plugins/apiNotices.ts @@ -29,13 +29,12 @@ export default definePlugin({ find: 'displayName="NoticeStore"', replacement: [ { - match: /;.{1,2}=null;.{0,70}getPremiumSubscription/g, - replace: - ";if(Vencord.Api.Notices.currentNotice)return false$&" + match: /(?=;\i=null;.{0,70}getPremiumSubscription)/g, + replace: ";if(Vencord.Api.Notices.currentNotice)return false" }, { match: /(?<=,NOTICE_DISMISS:function\(\i\){)(?=if\(null==(\i)\))/, - replace: 'if($1?.id=="VencordNotice")return($1=null,Vencord.Api.Notices.nextNotice(),true);' + replace: (_, notice) => `if(${notice}.id=="VencordNotice")return(${notice}=null,Vencord.Api.Notices.nextNotice(),true);` } ] } diff --git a/src/plugins/crashHandler.ts b/src/plugins/crashHandler.ts index 79db782..e35dfed 100644 --- a/src/plugins/crashHandler.ts +++ b/src/plugins/crashHandler.ts @@ -64,8 +64,8 @@ export default definePlugin({ { find: 'dispatch({type:"MODAL_POP_ALL"})', replacement: { - match: /(?<=(?<popAll>\i)=function\(\){\(0,\i\.\i\)\(\);\i\.\i\.dispatch\({type:"MODAL_POP_ALL"}\).+};)/, - replace: "$self.popAllModals=$<popAll>;" + match: /"MODAL_POP_ALL".+?};(?<=(\i)=function.+?)/, + replace: (m, popAll) => `${m}$self.popAllModals=${popAll};` } } ], diff --git a/src/plugins/disableDMCallIdle.ts b/src/plugins/disableDMCallIdle.ts index c620f54..2ba861c 100644 --- a/src/plugins/disableDMCallIdle.ts +++ b/src/plugins/disableDMCallIdle.ts @@ -27,9 +27,9 @@ export default definePlugin({ { find: ".Messages.BOT_CALL_IDLE_DISCONNECT", replacement: { - match: /function (?<functionName>.{1,3})\(\){.{1,100}\.Messages\.BOT_CALL_IDLE_DISCONNECT.+?}}/, - replace: "function $<functionName>(){}", - }, - }, - ], + match: /(?<=function \i\(\){)(?=.{1,100}\.Messages\.BOT_CALL_IDLE_DISCONNECT)/, + replace: "return;" + } + } + ] }); diff --git a/src/plugins/experiments.tsx b/src/plugins/experiments.tsx index a3125ae..686b822 100644 --- a/src/plugins/experiments.tsx +++ b/src/plugins/experiments.tsx @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { Settings } from "@api/settings"; +import { definePluginSettings } from "@api/settings"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { findByPropsLazy } from "@webpack"; @@ -24,49 +24,71 @@ import { Forms, React } from "@webpack/common"; const KbdStyles = findByPropsLazy("key", "removeBuildOverride"); +const settings = definePluginSettings({ + enableIsStaff: { + description: "Enable isStaff", + type: OptionType.BOOLEAN, + default: false, + restartNeeded: true + }, + forceStagingBanner: { + description: "Whether to force Staging banner under user area.", + type: OptionType.BOOLEAN, + default: false, + restartNeeded: true + } +}); + export default definePlugin({ name: "Experiments", + description: "Enable Access to Experiments in Discord!", authors: [ Devs.Megu, Devs.Ven, Devs.Nickyux, - Devs.BanTheNons + Devs.BanTheNons, + Devs.Nuckyz ], - description: "Enable Access to Experiments in Discord!", - patches: [{ - find: "Object.defineProperties(this,{isDeveloper", - replacement: { - match: /(?<={isDeveloper:\{[^}]+,get:function\(\)\{return )\w/, - replace: "true" + settings, + + patches: [ + { + find: "Object.defineProperties(this,{isDeveloper", + replacement: { + match: /(?<={isDeveloper:\{[^}]+?,get:function\(\)\{return )\w/, + replace: "true" + } + }, + { + find: 'type:"user",revision', + replacement: { + match: /!(\i)&&"CONNECTION_OPEN".+?;/g, + replace: "$1=!0;" + } }, - }, { - find: 'type:"user",revision', - replacement: { - match: /!(\w{1,3})&&"CONNECTION_OPEN".+?;/g, - replace: "$1=!0;" + { + find: ".isStaff=function(){", + predicate: () => settings.store.enableIsStaff, + replacement: [ + { + match: /return\s*?(\i)\.hasFlag\((\i\.\i)\.STAFF\)}/, + replace: (_, user, flags) => `return Vencord.Webpack.Common.UserStore.getCurrentUser().id===${user}.id||${user}.hasFlag(${flags}.STAFF)}` + }, + { + match: /hasFreePremium=function\(\){return this.isStaff\(\)\s*?\|\|/, + replace: "hasFreePremium=function(){return ", + } + ] }, - }, { - find: ".isStaff=function(){", - predicate: () => Settings.plugins.Experiments.enableIsStaff === true, - replacement: [ - { - match: /return\s*(\w+)\.hasFlag\((.+?)\.STAFF\)}/, - replace: "return Vencord.Webpack.Common.UserStore.getCurrentUser().id===$1.id||$1.hasFlag($2.STAFF)}" - }, - { - match: /hasFreePremium=function\(\){return this.isStaff\(\)\s*\|\|/, - replace: "hasFreePremium=function(){return ", - }, - ], - }], - options: { - enableIsStaff: { - description: "Enable isStaff (requires restart)", - type: OptionType.BOOLEAN, - default: false, - restartNeeded: true, + { + find: ".Messages.DEV_NOTICE_STAGING", + predicate: () => settings.store.forceStagingBanner, + replacement: { + match: /"staging"===window\.GLOBAL_ENV\.RELEASE_CHANNEL/, + replace: "true" + } } - }, + ], settingsAboutComponent: () => { const isMacOS = navigator.platform.includes("Mac"); diff --git a/src/plugins/fakeNitro.ts b/src/plugins/fakeNitro.ts index a09a95a..e9b19ca 100644 --- a/src/plugins/fakeNitro.ts +++ b/src/plugins/fakeNitro.ts @@ -72,7 +72,7 @@ migratePluginSettings("FakeNitro", "NitroBypass"); export default definePlugin({ name: "FakeNitro", - authors: [Devs.Arjix, Devs.D3SOX, Devs.Ven, Devs.obscurity, Devs.captain], + authors: [Devs.Arjix, Devs.D3SOX, Devs.Ven, Devs.obscurity, Devs.captain, Devs.Nuckyz], description: "Allows you to stream in nitro quality, send fake emojis/stickers and use client themes.", dependencies: ["MessageEventsAPI"], @@ -82,16 +82,16 @@ export default definePlugin({ predicate: () => Settings.plugins.FakeNitro.enableEmojiBypass === true, replacement: [ { - match: /(?<=(?<intention>\i)=\i\.intention)/, - replace: ",fakeNitroIntention=$<intention>" + match: /(?<=(\i)=\i\.intention)/, + replace: (_, intention) => `,fakeNitroIntention=${intention}` }, { match: /(?<=\.(?:canUseEmojisEverywhere|canUseAnimatedEmojis)\(\i)(?=\))/g, replace: ',typeof fakeNitroIntention!=="undefined"?fakeNitroIntention:void 0' }, { - match: /(?<=&&!\i&&)!(?<canUseExternal>\i)(?=\)return \i\.\i\.DISALLOW_EXTERNAL;)/, - replace: `(!$<canUseExternal>&&(typeof fakeNitroIntention==="undefined"||![${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)))` + match: /(?<=&&!\i&&)!(\i)(?=\)return \i\.\i\.DISALLOW_EXTERNAL;)/, + replace: (_, canUseExternal) => `(!${canUseExternal}&&(typeof fakeNitroIntention==="undefined"||![${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)))` } ] }, @@ -99,16 +99,16 @@ export default definePlugin({ find: "canUseAnimatedEmojis:function", predicate: () => Settings.plugins.FakeNitro.enableEmojiBypass === true, replacement: { - match: /(?<=(?:canUseEmojisEverywhere|canUseAnimatedEmojis):function\((?<user>\i))\){(?<premiumCheck>.+?\))/g, - replace: `,fakeNitroIntention){$<premiumCheck>||fakeNitroIntention==null||[${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)` + match: /(?<=(?:canUseEmojisEverywhere|canUseAnimatedEmojis):function\(\i)\){(.+?\))/g, + replace: (_, premiumCheck) => `,fakeNitroIntention){${premiumCheck}||fakeNitroIntention==null||[${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)` } }, { find: "canUseStickersEverywhere:function", predicate: () => Settings.plugins.FakeNitro.enableStickerBypass === true, replacement: { - match: /canUseStickersEverywhere:function\(.+?\{/, - replace: "$&return true;" + match: /(?<=canUseStickersEverywhere:function\(\i\){)/, + replace: "return true;" }, }, { @@ -128,8 +128,8 @@ export default definePlugin({ "canStreamMidQuality" ].map(func => { return { - match: new RegExp(`${func}:function\\(.+?\\{`), - replace: "$&return true;" + match: new RegExp(`(?<=${func}:function\\(\\i\\){)`), + replace: "return true;" }; }) }, diff --git a/src/plugins/ignoreActivities.tsx b/src/plugins/ignoreActivities.tsx index 3d53bbc..07b458f 100644 --- a/src/plugins/ignoreActivities.tsx +++ b/src/plugins/ignoreActivities.tsx @@ -21,7 +21,7 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import { useForceUpdater } from "@utils/misc"; import definePlugin from "@utils/types"; -import { findByPropsLazy } from "@webpack"; +import { findByPropsLazy, findStoreLazy } from "@webpack"; import { Tooltip } from "webpack/common"; enum ActivitiesTypes { @@ -37,7 +37,7 @@ interface IgnoredActivity { const RegisteredGamesClasses = findByPropsLazy("overlayToggleIconOff", "overlayToggleIconOn"); const TryItOutClasses = findByPropsLazy("tryItOutBadge", "tryItOutBadgeIcon"); const BaseShapeRoundClasses = findByPropsLazy("baseShapeRound", "baseShapeRoundLeft", "baseShapeRoundRight"); -const RunningGameStore = findByPropsLazy("getRunningGames", "getGamesSeen"); +const RunningGameStore = findStoreLazy("RunningGameStore"); function ToggleIconOff() { return ( @@ -71,7 +71,7 @@ function ToggleIconOff() { ); } -function ToggleIconOn() { +function ToggleIconOn({ forceWhite }: { forceWhite?: boolean; }) { return ( <svg className={RegisteredGamesClasses.overlayToggleIconOn} @@ -80,14 +80,15 @@ function ToggleIconOn() { viewBox="0 0 32 26" > <path - className={RegisteredGamesClasses.fill} + className={forceWhite ? "" : RegisteredGamesClasses.fill} + fill={forceWhite ? "var(--white-500)" : ""} d="M 16 8 C 7.664063 8 1.25 15.34375 1.25 15.34375 L 0.65625 16 L 1.25 16.65625 C 1.25 16.65625 7.097656 23.324219 14.875 23.9375 C 15.246094 23.984375 15.617188 24 16 24 C 16.382813 24 16.753906 23.984375 17.125 23.9375 C 24.902344 23.324219 30.75 16.65625 30.75 16.65625 L 31.34375 16 L 30.75 15.34375 C 30.75 15.34375 24.335938 8 16 8 Z M 16 10 C 18.203125 10 20.234375 10.601563 22 11.40625 C 22.636719 12.460938 23 13.675781 23 15 C 23 18.613281 20.289063 21.582031 16.78125 21.96875 C 16.761719 21.972656 16.738281 21.964844 16.71875 21.96875 C 16.480469 21.980469 16.242188 22 16 22 C 15.734375 22 15.476563 21.984375 15.21875 21.96875 C 11.710938 21.582031 9 18.613281 9 15 C 9 13.695313 9.351563 12.480469 9.96875 11.4375 L 9.9375 11.4375 C 11.71875 10.617188 13.773438 10 16 10 Z M 16 12 C 14.34375 12 13 13.34375 13 15 C 13 16.65625 14.34375 18 16 18 C 17.65625 18 19 16.65625 19 15 C 19 13.34375 17.65625 12 16 12 Z M 7.25 12.9375 C 7.09375 13.609375 7 14.285156 7 15 C 7 16.753906 7.5 18.394531 8.375 19.78125 C 5.855469 18.324219 4.105469 16.585938 3.53125 16 C 4.011719 15.507813 5.351563 14.203125 7.25 12.9375 Z M 24.75 12.9375 C 26.648438 14.203125 27.988281 15.507813 28.46875 16 C 27.894531 16.585938 26.144531 18.324219 23.625 19.78125 C 24.5 18.394531 25 16.753906 25 15 C 25 14.285156 24.90625 13.601563 24.75 12.9375 Z" /> </svg> ); } -function ToggleActivityComponent({ activity }: { activity: IgnoredActivity; }) { +function ToggleActivityComponent({ activity, forceWhite }: { activity: IgnoredActivity; forceWhite?: boolean; }) { const forceUpdate = useForceUpdater(); return ( @@ -105,7 +106,7 @@ function ToggleActivityComponent({ activity }: { activity: IgnoredActivity; }) { { ignoredActivitiesCache.has(activity.id) ? <ToggleIconOff /> - : <ToggleIconOn /> + : <ToggleIconOn forceWhite={forceWhite} /> } </div> )} @@ -117,9 +118,9 @@ function ToggleActivityComponentWithBackground({ activity }: { activity: Ignored return ( <div className={`${TryItOutClasses.tryItOutBadge} ${BaseShapeRoundClasses.baseShapeRound}`} - style={{ padding: "0 2px" }} + style={{ padding: "0px 2px" }} > - <ToggleActivityComponent activity={activity} /> + <ToggleActivityComponent activity={activity} forceWhite={true} /> </div> ); } @@ -142,28 +143,32 @@ export default definePlugin({ name: "IgnoreActivities", authors: [Devs.Nuckyz], description: "Ignore certain activities (like games and actual activities) from showing up on your status. You can configure which ones are ignored from the Registered Games and Activities tabs.", - patches: [{ - find: ".Messages.SETTINGS_GAMES_TOGGLE_OVERLAY", - replacement: { - match: /!(\i)\|\|(null==\i\)return null;var \i=(\i)\.overlay.+?children:)(\[.{0,70}overlayStatusText.+?\])(?=}\)}\(\))/, - replace: (_, platformCheck, restWithoutPlatformCheck, props, children) => "" - + `${restWithoutPlatformCheck}` - + `(${platformCheck}?${children}:[])` - + `.concat(Vencord.Plugins.plugins.IgnoreActivities.renderToggleGameActivityButton(${props}))` - } - }, { - find: ".overlayBadge", - replacement: { - match: /.badgeContainer.+?.\?\(0,.\.jsx\)\(.{1,2},{name:(?<props>.)\.name}\):null/, - replace: "$&,$self.renderToggleActivityButton($<props>)" - } - }, { - find: '.displayName="LocalActivityStore"', - replacement: { - match: /(?<activities>.)\.push\(.\({type:.\..{1,3}\.LISTENING.+?\)\)/, - replace: "$&;$<activities>=$<activities>.filter($self.isActivityNotIgnored);" + patches: [ + { + find: ".Messages.SETTINGS_GAMES_TOGGLE_OVERLAY", + replacement: { + match: /!(\i)\|\|(null==\i\)return null;var \i=(\i)\.overlay.+?children:)(\[.{0,70}overlayStatusText.+?\])(?=}\)}\(\))/, + replace: (_, platformCheck, restWithoutPlatformCheck, props, children) => "" + + `${restWithoutPlatformCheck}` + + `(${platformCheck}?${children}:[])` + + `.concat(Vencord.Plugins.plugins.IgnoreActivities.renderToggleGameActivityButton(${props}))` + } + }, + { + find: ".overlayBadge", + replacement: { + match: /(?<=\(\)\.badgeContainer.+?(\i)\.name}\):null)/, + replace: (_, props) => `,$self.renderToggleActivityButton(${props})` + } + }, + { + find: '.displayName="LocalActivityStore"', + replacement: { + match: /LISTENING.+?\)\);(?<=(\i)\.push.+?)/, + replace: (m, activities) => `${m}${activities}=${activities}.filter($self.isActivityNotIgnored);` + } } - }], + ], async start() { const ignoredActivitiesData = await DataStore.get<string[] | Map<IgnoredActivity["id"], IgnoredActivity>>("IgnoreActivities_ignoredActivities") ?? new Map<IgnoredActivity["id"], IgnoredActivity>(); @@ -217,5 +222,5 @@ export default definePlugin({ } } return true; - }, + } }); diff --git a/src/plugins/moyai.ts b/src/plugins/moyai.ts index fabc97f..146ac3f 100644 --- a/src/plugins/moyai.ts +++ b/src/plugins/moyai.ts @@ -16,7 +16,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { Settings } from "@api/settings"; +import { definePluginSettings } from "@api/settings"; import { makeRange } from "@components/PluginSettings/components/SettingSliderComponent"; import { Devs } from "@utils/constants"; import { sleep } from "@utils/misc"; @@ -54,15 +54,36 @@ const MOYAI = "🗿"; const MOYAI_URL = "https://raw.githubusercontent.com/MeguminSama/VencordPlugins/main/plugins/moyai/moyai.mp3"; +const settings = definePluginSettings({ + volume: { + description: "Volume of the 🗿🗿🗿", + type: OptionType.SLIDER, + markers: makeRange(0, 1, 0.1), + default: 0.5, + stickToMarkers: false + }, + triggerWhenUnfocused: { + description: "Trigger the 🗿 even when the window is unfocused", + type: OptionType.BOOLEAN, + default: true + }, + ignoreBots: { + description: "Ignore bots", + type: OptionType.BOOLEAN, + default: true + } +}); + export default definePlugin({ name: "Moyai", authors: [Devs.Megu, Devs.Nuckyz], description: "🗿🗿🗿🗿🗿🗿🗿🗿", + settings, async onMessage(e: IMessageCreate) { if (e.optimistic || e.type !== "MESSAGE_CREATE") return; if (e.message.state === "SENDING") return; - if (Settings.plugins.Moyai.ignoreBots && e.message.author?.bot) return; + if (settings.store.ignoreBots && e.message.author?.bot) return; if (!e.message.content) return; if (e.channelId !== SelectedChannelStore.getChannelId()) return; @@ -76,7 +97,7 @@ export default definePlugin({ onReaction(e: IReactionAdd) { if (e.optimistic || e.type !== "MESSAGE_REACTION_ADD") return; - if (Settings.plugins.Moyai.ignoreBots && UserStore.getUser(e.userId)?.bot) return; + if (settings.store.ignoreBots && UserStore.getUser(e.userId)?.bot) return; if (e.channelId !== SelectedChannelStore.getChannelId()) return; const name = e.emoji.name.toLowerCase(); @@ -103,28 +124,6 @@ export default definePlugin({ FluxDispatcher.unsubscribe("MESSAGE_CREATE", this.onMessage); FluxDispatcher.unsubscribe("MESSAGE_REACTION_ADD", this.onReaction); FluxDispatcher.unsubscribe("VOICE_CHANNEL_EFFECT_SEND", this.onVoiceChannelEffect); - }, - - options: { - volume: { - description: "Volume of the 🗿🗿🗿", - type: OptionType.SLIDER, - markers: makeRange(0, 1, 0.1), - default: 0.5, - stickToMarkers: false, - }, - triggerWhenUnfocused: { - description: "Trigger the 🗿 even when the window is unfocused", - type: OptionType.BOOLEAN, - default: true, - restartNeeded: false, - }, - ignoreBots: { - description: "Ignore bots", - type: OptionType.BOOLEAN, - default: true, - restartNeeded: false, - } } }); @@ -158,9 +157,9 @@ function getMoyaiCount(message: string) { } function boom() { - if (!Settings.plugins.Moyai.triggerWhenUnfocused && !document.hasFocus()) return; + if (!settings.store.triggerWhenUnfocused && !document.hasFocus()) return; const audioElement = document.createElement("audio"); audioElement.src = MOYAI_URL; - audioElement.volume = Settings.plugins.Moyai.volume; + audioElement.volume = settings.store.volume; audioElement.play(); } diff --git a/src/plugins/noScreensharePreview.ts b/src/plugins/noScreensharePreview.ts index b09f206..50b2a96 100644 --- a/src/plugins/noScreensharePreview.ts +++ b/src/plugins/noScreensharePreview.ts @@ -30,9 +30,9 @@ export default definePlugin({ "\\i\\.default\\.makeChunkedRequest\\(", "\\i\\.\\i\\.post\\({url:" ].map(match => ({ - match: new RegExp(`return\\[(?<code>\\d),${match}\\i\\.\\i\\.STREAM_PREVIEW.+?}\\)\\];`), - replace: 'return[$<code>,Promise.resolve({body:"",status:204})];' + match: new RegExp(`(?=return\\[(\\d),${match}\\i\\.\\i\\.STREAM_PREVIEW.+?}\\)\\];)`), + replace: (_, code) => `return[${code},Promise.resolve({body:"",status:204})];` })) - }, - ], + } + ] }); diff --git a/src/plugins/pronoundb/index.ts b/src/plugins/pronoundb/index.ts index 7ebe919..820b66e 100644 --- a/src/plugins/pronoundb/index.ts +++ b/src/plugins/pronoundb/index.ts @@ -41,7 +41,7 @@ export default definePlugin({ replace: "[$1, $self.PronounsChatComponent(e)]" } }, - // Hijack the discord pronouns section (hidden without experiment) and add a wrapper around the text section + // Hijack the discord pronouns section and add a wrapper around the text section { find: ".Messages.BOT_PROFILE_SLASH_COMMANDS", replacement: { @@ -49,12 +49,12 @@ export default definePlugin({ replace: "$<fullProps>&&$self.PronounsProfileWrapper($<PronounComponent>,$<pronounProps>,$<fullProps>)" } }, - // Make pronouns experiment be enabled by default + // Force enable pronouns component ignoring the experiment value { - find: "2022-01_pronouns", + find: ".Messages.USER_POPOUT_PRONOUNS", replacement: { - match: "!1", // false - replace: "!0" + match: /\i\.\i\.useExperiment\({}\)\.showPronouns/, + replace: "true" } } ], diff --git a/src/plugins/revealAllSpoilers.ts b/src/plugins/revealAllSpoilers.ts index ead169f..9cb7b6b 100644 --- a/src/plugins/revealAllSpoilers.ts +++ b/src/plugins/revealAllSpoilers.ts @@ -32,8 +32,8 @@ export default definePlugin({ { find: ".removeObscurity=function", replacement: { - match: /\.removeObscurity=function\((\i)\){/, - replace: ".removeObscurity=function($1){$self.reveal($1);" + match: /(?<=\.removeObscurity=function\((\i)\){)/, + replace: (_, event) => `$self.reveal(${event});` } } ], diff --git a/src/plugins/showHiddenChannels/index.tsx b/src/plugins/showHiddenChannels/index.tsx index 60e0c51..70c5045 100644 --- a/src/plugins/showHiddenChannels/index.tsx +++ b/src/plugins/showHiddenChannels/index.tsx @@ -64,29 +64,29 @@ export default definePlugin({ patches: [ { // RenderLevel defines if a channel is hidden, collapsed in category, visible, etc - find: ".CannotShow", + find: ".CannotShow=", // These replacements only change the necessary CannotShow's replacement: [ { - match: /(?<=isChannelGatedAndVisible\(this\.record\.guild_id,this\.record\.id\).+?renderLevel:)(?<RenderLevels>\i)\..+?(?=,)/, - replace: "this.category.isCollapsed?$<RenderLevels>.WouldShowIfUncollapsed:$<RenderLevels>.Show" + match: /(?<=isChannelGatedAndVisible\(this\.record\.guild_id,this\.record\.id\).+?renderLevel:)(\i)\..+?(?=,)/, + replace: (_, RenderLevels) => `this.category.isCollapsed?${RenderLevels}.WouldShowIfUncollapsed:${RenderLevels}.Show` }, // Move isChannelGatedAndVisible renderLevel logic to the bottom to not show hidden channels in case they are muted { - match: /(?<=(?<permissionCheck>if\(!\i\.\i\.can\(\i\.\i\.VIEW_CHANNEL.+?{)if\(this\.id===\i\).+?};)(?<isChannelGatedAndVisibleCondition>if\(!\i\.\i\.isChannelGatedAndVisible\(.+?})(?<restOfFunction>.+?)(?=return{renderLevel:\i\.Show.{1,40}return \i)/, - replace: "$<restOfFunction>$<permissionCheck>$<isChannelGatedAndVisibleCondition>}" + match: /(?<=(if\(!\i\.\i\.can\(\i\.\i\.VIEW_CHANNEL.+?{)if\(this\.id===\i\).+?};)(if\(!\i\.\i\.isChannelGatedAndVisible\(.+?})(.+?)(?=return{renderLevel:\i\.Show.{0,40}?return \i)/, + replace: (_, permissionCheck, isChannelGatedAndVisibleCondition, rest) => `${rest}${permissionCheck}${isChannelGatedAndVisibleCondition}}` }, { - match: /(?<=renderLevel:(?<renderLevelExpression>\i\(this,\i\)\?\i\.Show:\i\.WouldShowIfUncollapsed).+?renderLevel:).+?(?=,)/, - replace: "$<renderLevelExpression>" + match: /(?<=renderLevel:(\i\(this,\i\)\?\i\.Show:\i\.WouldShowIfUncollapsed).+?renderLevel:).+?(?=,)/, + replace: (_, renderLevelExpression) => renderLevelExpression }, { - match: /(?<=activeJoinedRelevantThreads.+?renderLevel:.+?,threadIds:\i\(this.record.+?renderLevel:)(?<RenderLevels>\i)\..+?(?=,)/, - replace: "$<RenderLevels>.Show" + match: /(?<=activeJoinedRelevantThreads.+?renderLevel:.+?,threadIds:\i\(this.record.+?renderLevel:)(\i)\..+?(?=,)/, + replace: (_, RenderLevels) => `${RenderLevels}.Show` }, { - match: /(?<=getRenderLevel=function.+?return ).+?\?(?<renderLevelExpressionWithoutPermCheck>.+?):\i\.CannotShow(?=})/, - replace: "$<renderLevelExpressionWithoutPermCheck>" + match: /(?<=getRenderLevel=function.+?return ).+?\?(.+?):\i\.CannotShow(?=})/, + replace: (_, renderLevelExpressionWithoutPermCheck) => renderLevelExpressionWithoutPermCheck } ] }, @@ -95,18 +95,18 @@ export default definePlugin({ replacement: [ { // Do not show confirmation to join a voice channel when already connected to another if clicking on a hidden voice channel - match: /(?<=getCurrentClientVoiceChannelId\(\i\.guild_id\);if\()(?=.+?\((?<channel>\i)\))/, - replace: "!$self.isHiddenChannel($<channel>)&&" + match: /(?<=getCurrentClientVoiceChannelId\((\i)\.guild_id\);if\()/, + replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&` }, { // Make Discord think we are connected to a voice channel so it shows us inside it - match: /(?=\|\|\i\.default\.selectVoiceChannel\((?<channel>\i)\.id\))/, - replace: "||$self.isHiddenChannel($<channel>)" + match: /(?=\|\|\i\.default\.selectVoiceChannel\((\i)\.id\))/, + replace: (_, channel) => `||$self.isHiddenChannel(${channel})` }, { // Make Discord think we are connected to a voice channel so it shows us inside it - match: /(?<=\|\|\i\.default\.selectVoiceChannel\((?<channel>\i)\.id\);!__OVERLAY__&&\()/, - replace: "$self.isHiddenChannel($<channel>)||" + match: /(?<=\|\|\i\.default\.selectVoiceChannel\((\i)\.id\);!__OVERLAY__&&\()/, + replace: (_, channel) => `$self.isHiddenChannel(${channel})||` } ] }, @@ -119,7 +119,7 @@ export default definePlugin({ "renderInviteButton", "renderOpenChatButton" ].map(func => ({ - match: new RegExp(`(?<=\\i\\.${func}=function\\(\\){)`, "g"), // Global because Discord has multiple declarations of the same functions + match: new RegExp(`(?<=${func}=function\\(\\){)`, "g"), // Global because Discord has multiple declarations of the same functions replace: "if($self.isHiddenChannel(this.props.channel))return null;" })) ] @@ -129,17 +129,8 @@ export default definePlugin({ predicate: () => settings.store.showMode === ShowMode.LockIcon, replacement: { // Lock Icon - match: /(?=switch\((?<channel>\i)\.type\).{1,30}\.GUILD_ANNOUNCEMENT.{1,30}\(0,\i\.\i\))/, - replace: "if($self.isHiddenChannel($<channel>))return $self.LockIcon;" - } - }, - { - find: ".UNREAD_HIGHLIGHT", - predicate: () => settings.store.hideUnreads === true, - replacement: { - // Hide unreads - match: /(?<=\i\.connected,\i=)(?=(?<props>\i)\.unread)/, - replace: "$self.isHiddenChannel($<props>.channel)?false:" + match: /(?=switch\((\i)\.type\).{0,30}\.GUILD_ANNOUNCEMENT.{0,30}\(0,\i\.\i\))/, + replace: (_, channel) => `if($self.isHiddenChannel(${channel}))return $self.LockIcon;` } }, { @@ -148,36 +139,44 @@ export default definePlugin({ replacement: [ // Make the channel appear as muted if it's hidden { - match: /(?<=\i\.name,\i=)(?=(?<props>\i)\.muted)/, - replace: "$self.isHiddenChannel($<props>.channel)?true:" + match: /(?<=\i\.name,\i=)(?=(\i)\.muted)/, + replace: (_, props) => `$self.isHiddenChannel(${props}.channel)?true:` }, // Add the hidden eye icon if the channel is hidden { - match: /(?<=(?<channel>\i)=\i\.channel,.+?\(\)\.children.+?:null)/, - replace: ",$self.isHiddenChannel($<channel>)?$self.HiddenChannelIcon():null" + match: /\(\).children.+?:null(?<=(\i)=\i\.channel,.+?)/, + replace: (m, channel) => `${m},$self.isHiddenChannel(${channel})?$self.HiddenChannelIcon():null` }, // Make voice channels also appear as muted if they are muted { - match: /(?<=\i\(\)\.wrapper:\i\(\)\.notInteractive,)(?<otherClasses>.+?)(?<mutedClassExpression>(?<isMuted>\i)\?\i\.MUTED)/, - replace: "$<mutedClassExpression>:\"\",$<otherClasses>$<isMuted>?\"\"" + match: /(?<=\.wrapper:\i\(\)\.notInteractive,)(.+?)((\i)\?\i\.MUTED)/, + replace: (_, otherClasses, mutedClassExpression, isMuted) => `${mutedClassExpression}:"",${otherClasses}${isMuted}?""` } ] }, - // Make muted channels also appear as unread if hide unreads is false, using the HiddenIconWithMutedStyle and the channel is hidden { find: ".UNREAD_HIGHLIGHT", - predicate: () => settings.store.hideUnreads === false && settings.store.showMode === ShowMode.HiddenIconWithMutedStyle, - replacement: { - match: /(?<=(?<channel>\i)=\i\.channel,.+?\.LOCKED:\i)/, - replace: "&&!($self.settings.store.hideUnreads===false&&$self.isHiddenChannel($<channel>))" - } + replacement: [ + { + // Make muted channels also appear as unread if hide unreads is false, using the HiddenIconWithMutedStyle and the channel is hidden + predicate: () => settings.store.hideUnreads === false && settings.store.showMode === ShowMode.HiddenIconWithMutedStyle, + match: /\.LOCKED:\i(?<=(\i)=\i\.channel,.+?)/, + replace: (m, channel) => `${m}&&!$self.isHiddenChannel(${channel})` + }, + { + // Hide unreads + predicate: () => settings.store.hideUnreads === true, + match: /(?<=\i\.connected,\i=)(?=(\i)\.unread)/, + replace: (_, props) => `$self.isHiddenChannel(${props}.channel)?false:` + } + ] }, { // Hide New unreads box for hidden channels find: '.displayName="ChannelListUnreadsStore"', replacement: { - match: /(?<=return null!=(?<channel>\i))(?=.{1,130}hasRelevantUnread\(\i\))/g, // Global because Discord has multiple methods like that in the same module - replace: "&&!$self.isHiddenChannel($<channel>)" + match: /(?<=return null!=(\i))(?=.{0,130}?hasRelevantUnread\(\i\))/g, // Global because Discord has multiple methods like that in the same module + replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})` } }, // Only render the channel header and buttons that work when transitioning to a hidden channel @@ -185,20 +184,20 @@ export default definePlugin({ find: "Missing channel in Channel.renderHeaderToolbar", replacement: [ { - match: /(?<=renderHeaderToolbar=function.+?case \i\.\i\.GUILD_TEXT:)(?=.+?;(?<pushNotificationButtonExpression>.+?{channel:(?<channel>\i)},"notifications"\)\);))/, - replace: "if($self.isHiddenChannel($<channel>)){$<pushNotificationButtonExpression>break;}" + match: /(?<=renderHeaderToolbar=function.+?case \i\.\i\.GUILD_TEXT:)(?=.+?;(.+?{channel:(\i)},"notifications"\)\);))/, + replace: (_, pushNotificationButtonExpression, channel) => `if($self.isHiddenChannel(${channel})){${pushNotificationButtonExpression}break;}` }, { - match: /(?<=renderHeaderToolbar=function.+?case \i\.\i\.GUILD_FORUM:if\(!\i\){)(?=.+?;(?<pushNotificationButtonExpression>.+?{channel:(?<channel>\i)},"notifications"\)\)))/, - replace: "if($self.isHiddenChannel($<channel>)){$<pushNotificationButtonExpression>;break;}" + match: /(?<=renderHeaderToolbar=function.+?case \i\.\i\.GUILD_FORUM:if\(!\i\){)(?=.+?;(.+?{channel:(\i)},"notifications"\)\)))/, + replace: (_, pushNotificationButtonExpression, channel) => `if($self.isHiddenChannel(${channel})){${pushNotificationButtonExpression};break;}` }, { - match: /(?<=(?<this>\i)\.renderMobileToolbar=function.+?case \i\.\i\.GUILD_FORUM:)/, - replace: "if($self.isHiddenChannel($<this>.props.channel))break;" + match: /renderMobileToolbar=function.+?case \i\.\i\.GUILD_FORUM:(?<=(\i)\.renderMobileToolbar.+?)/, + replace: (m, that) => `${m}if($self.isHiddenChannel(${that}.props.channel))break;` }, { - match: /(?<=renderHeaderBar=function.+?hideSearch:(?<channel>\i)\.isDirectory\(\))/, - replace: "||$self.isHiddenChannel($<channel>)" + match: /(?<=renderHeaderBar=function.+?hideSearch:(\i)\.isDirectory\(\))/, + replace: (_, channel) => `||$self.isHiddenChannel(${channel})` }, { match: /(?<=renderSidebar=function\(\){)/, @@ -213,25 +212,23 @@ export default definePlugin({ // Avoid trying to fetch messages from hidden channels { find: '"MessageManager"', - replacement: [ - { - match: /(?<=if\(null!=(?<channelId>\i)\).{1,100}"Skipping fetch because channelId is a static route".{1,10}else{)/, - replace: "if($self.isHiddenChannel({channelId:$<channelId>}))return;" - }, - ] + replacement: { + match: /"Skipping fetch because channelId is a static route"\);else{(?=.+?getChannel\((\i)\))/, + replace: (m, channelId) => `${m}if($self.isHiddenChannel({channelId:${channelId}}))return;` + } }, // Patch keybind handlers so you can't accidentally jump to hidden channels { find: '"alt+shift+down"', replacement: { - match: /(?<=getChannel\(\i\);return null!=(?<channel>\i))(?=.{1,130}hasRelevantUnread\(\i\))/, - replace: "&&!$self.isHiddenChannel($<channel>)" + match: /(?<=getChannel\(\i\);return null!=(\i))(?=.{0,130}?hasRelevantUnread\(\i\))/, + replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})` } }, { find: '"alt+down"', replacement: { - match: /(?<=getState\(\)\.channelId.{1,30}\(0,\i\.\i\)\(\i\))(?=\.map\()/, + match: /(?<=getState\(\)\.channelId.{0,30}?\(0,\i\.\i\)\(\i\))(?=\.map\()/, replace: ".filter(ch=>!$self.isHiddenChannel(ch))" } }, @@ -239,8 +236,8 @@ export default definePlugin({ { find: 'jumboable?"jumbo":"default"', replacement: { - match: /(?<=(?<component>\i)=function.{1,20}node,\i=\i.isInteracting.+?}}\)},)/, - replace: "shcEmojiComponentExport=($self.setEmojiComponent($<component>),void 0)," + match: /jumboable\?"jumbo":"default",emojiId.+?}}\)},(?<=(\i)=function\(\i\){var \i=\i\.node.+?)/, + replace: (m, component) => `${m}shcEmojiComponentExport=($self.setEmojiComponent(${component}),void 0),` } }, { @@ -248,13 +245,13 @@ export default definePlugin({ replacement: [ { // Export the channel beggining header - match: /(?<=function (?<component>\i)\(.{1,600}computePermissionsForRoles.+?}\)})(?=var)/, - replace: "$self.setChannelBeginHeaderComponent($<component>);" + match: /computePermissionsForRoles.+?}\)}(?<=function (\i)\(.+?)(?=var)/, + replace: (m, component) => `${m}$self.setChannelBeginHeaderComponent(${component});` }, { // Patch the header to only return allowed users and roles if it's a hidden channel (Like when it's used on the HiddenChannelLockScreen) - match: /(?<=MANAGE_ROLES.{1,60}return)(?=\(.+?(?<component>\(0,\i\.jsxs\)\("div",{className:\i\(\)\.members.+?guildId:(?<channel>\i)\.guild_id.+?roleColor.+?]}\)))/, - replace: " $self.isHiddenChannel($<channel>)?$<component>:" + match: /MANAGE_ROLES.{0,60}?return(?=\(.+?(\(0,\i\.jsxs\)\("div",{className:\i\(\)\.members.+?guildId:(\i)\.guild_id.+?roleColor.+?]}\)))/, + replace: (m, component, channel) => `${m} $self.isHiddenChannel(${channel})?${component}:` } ] }, @@ -263,23 +260,23 @@ export default definePlugin({ replacement: [ { // Remove the divider and the open chat button for the HiddenChannelLockScreen - match: /(?<=function \i\((?<props>\i)\).{1,2000}"more-options-popout"\)\);if\()/, - replace: "(!$self.isHiddenChannel($<props>.channel)||$<props>.inCall)&&" + match: /"more-options-popout"\)\);if\((?<=function \i\((\i)\).+?)/, + replace: (m, props) => `${m}(!$self.isHiddenChannel(${props}.channel)||${props}.inCall)&&` }, { // Render our HiddenChannelLockScreen component instead of the main voice channel component - match: /(?<=renderContent=function.{1,1700}children:)/, - replace: "!this.props.inCall&&$self.isHiddenChannel(this.props.channel)?$self.HiddenChannelLockScreen(this.props.channel):" + match: /this\.renderVoiceChannelEffects.+?children:(?<=renderContent=function.+?)/, + replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel)?$self.HiddenChannelLockScreen(this.props.channel):" }, { // Disable gradients for the HiddenChannelLockScreen of voice channels - match: /(?<=renderContent=function.{1,1600}disableGradients:)/, - replace: "!this.props.inCall&&$self.isHiddenChannel(this.props.channel)||" + match: /this\.renderVoiceChannelEffects.+?disableGradients:(?<=renderContent=function.+?)/, + replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel)||" }, { // Disable useless components for the HiddenChannelLockScreen of voice channels - match: /(?<=renderContent=function.{1,800}render(?!Header).{0,30}:)(?!void)/g, - replace: "!this.props.inCall&&$self.isHiddenChannel(this.props.channel)?null:" + match: /(?:{|,)render(?!Header|ExternalHeader).{0,30}?:(?<=renderContent=function.+?)(?!void)/g, + replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel)?null:" } ] }, @@ -288,40 +285,58 @@ export default definePlugin({ replacement: [ { // Render our HiddenChannelLockScreen component instead of the main stage channel component - match: /(?<=(?<channel>\i)\.getGuildId\(\).{1,30}Guild voice channel without guild id\..{1,1400}children:)(?=.{1,20}}\)}function)/, - replace: "$self.isHiddenChannel($<channel>)?$self.HiddenChannelLockScreen($<channel>):" + match: /Guild voice channel without guild id.+?children:(?<=(\i)\.getGuildId\(\).+?)(?=.{0,20}?}\)}function)/, + replace: (m, channel) => `${m}$self.isHiddenChannel(${channel})?$self.HiddenChannelLockScreen(${channel}):` }, { // Disable useless components for the HiddenChannelLockScreen of stage channels - match: /(?<=(?<channel>\i)\.getGuildId\(\).{1,30}Guild voice channel without guild id\..{1,1000}render(?!Header).{0,30}:)/g, - replace: "$self.isHiddenChannel($<channel>)?null:" + match: /render(?!Header).{0,30}?:(?<=(\i)\.getGuildId\(\).+?Guild voice channel without guild id.+?)/g, + replace: (m, channel) => `${m}$self.isHiddenChannel(${channel})?null:` }, // Prevent Discord from replacing our route if we aren't connected to the stage channel { - match: /(?<=if\()(?=!\i&&!\i&&!\i.{1,80}(?<channel>\i)\.getGuildId\(\).{1,50}Guild voice channel without guild id\.)/, - replace: "!$self.isHiddenChannel($<channel>)&&" + match: /(?=!\i&&!\i&&!\i.{0,80}?(\i)\.getGuildId\(\).{0,50}?Guild voice channel without guild id)(?<=if\()/, + replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&` }, { // Disable gradients for the HiddenChannelLockScreen of stage channels - match: /(?<=(?<channel>\i)\.getGuildId\(\).{1,30}Guild voice channel without guild id\..{1,600}disableGradients:)/, - replace: "$self.isHiddenChannel($<channel>)||" + match: /Guild voice channel without guild id.+?disableGradients:(?<=(\i)\.getGuildId\(\).+?)/, + replace: (m, channel) => `${m}$self.isHiddenChannel(${channel})||` }, { // Disable strange styles applied to the header for the HiddenChannelLockScreen of stage channels - match: /(?<=(?<channel>\i)\.getGuildId\(\).{1,30}Guild voice channel without guild id\..{1,600}style:)/, - replace: "$self.isHiddenChannel($<channel>)?undefined:" + match: /Guild voice channel without guild id.+?style:(?<=(\i)\.getGuildId\(\).+?)/, + replace: (m, channel) => `${m}$self.isHiddenChannel(${channel})?undefined:` }, { // Remove the divider and amount of users in stage channel components for the HiddenChannelLockScreen - match: /\(0,\i\.jsx\)\(\i\.\i\.Divider.+?}\)]}\)(?=.+?:(?<channel>\i)\.guild_id)/, - replace: "$self.isHiddenChannel($<channel>)?null:($&)" + match: /\(0,\i\.jsx\)\(\i\.\i\.Divider.+?}\)]}\)(?=.+?:(\i)\.guild_id)/, + replace: (m, channel) => `$self.isHiddenChannel(${channel})?null:(${m})` }, { // Remove the open chat button for the HiddenChannelLockScreen - match: /(?<=null,)(?=.{1,120}channelId:(?<channel>\i)\.id,.+?toggleRequestToSpeakSidebar:\i,iconClassName:\i\(\)\.buttonIcon)/, - replace: "!$self.isHiddenChannel($<channel>)&&" + match: /"recents".+?null,(?=.{0,120}?channelId:(\i)\.id)/, + replace: (m, channel) => `${m}!$self.isHiddenChannel(${channel})&&` } ], + }, + { + // The module wasn't being found, so lets just escape everything + // eslint-disable-next-line no-useless-escape + find: "\^https\:\/\/\(\?\:canary\.\|ptb\.\)\?discord.com\/channels\/\(\\\\\d\+\|", + replacement: { + // Make mentions of hidden channels work + match: /\i\.\i\.can\(\i\.\i\.VIEW_CHANNEL,\i\)/, + replace: "true" + }, + }, + { + find: ".shouldCloseDefaultModals", + replacement: { + // Show inside voice channel instead of trying to join them when clicking on a channel mention + match: /(?<=getChannel\((\i)\)\)(?=.{0,100}?selectVoiceChannel))/, + replace: (_, channelId) => `&&!$self.isHiddenChannel({channelId:${channelId}})` + } } ], diff --git a/src/plugins/spotifyCrack.ts b/src/plugins/spotifyCrack.ts index c64154a..2682ccb 100644 --- a/src/plugins/spotifyCrack.ts +++ b/src/plugins/spotifyCrack.ts @@ -16,53 +16,55 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { migratePluginSettings, Settings } from "@api/settings"; +import { definePluginSettings, migratePluginSettings } from "@api/settings"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; +const settings = definePluginSettings({ + noSpotifyAutoPause: { + description: "Disable Spotify auto-pause", + type: OptionType.BOOLEAN, + default: true, + restartNeeded: true + }, + keepSpotifyActivityOnIdle: { + description: "Keep Spotify activity playing when idling", + type: OptionType.BOOLEAN, + default: false, + restartNeeded: true + } +}); + migratePluginSettings("SpotifyCrack", "Ify"); export default definePlugin({ name: "SpotifyCrack", description: "Free listen along, no auto-pausing in voice chat, and allows activity to continue playing when idling", - authors: [ - Devs.Cyn, - Devs.Nuckyz - ], + authors: [Devs.Cyn, Devs.Nuckyz], + settings, - patches: [{ - find: 'dispatch({type:"SPOTIFY_PROFILE_UPDATE"', - replacement: [{ - match: /(function\((.{1,2})\){)(.{1,6}dispatch\({type:"SPOTIFY_PROFILE_UPDATE")/, - replace: (_, functionStart, data, functionBody) => `${functionStart}${data}.body.product="premium";${functionBody}` - }], - }, { - find: '.displayName="SpotifyStore"', - predicate: () => Settings.plugins.SpotifyCrack.noSpotifyAutoPause, - replacement: { - match: /function (.{1,2})\(\).{0,200}SPOTIFY_AUTO_PAUSED\);.{0,}}}}/, - replace: "function $1(){}" - } - }, { - find: '.displayName="SpotifyStore"', - predicate: () => Settings.plugins.SpotifyCrack.keepSpotifyActivityOnIdle, - replacement: { - match: /(shouldShowActivity=function\(\){.{1,50})&&!.{1,6}\.isIdle\(\)(.{0,}?})/, - replace: (_, functionDeclarationAndExpression, restOfFunction) => `${functionDeclarationAndExpression}${restOfFunction}` - } - }], + patches: [ + { - options: { - noSpotifyAutoPause: { - description: "Disable Spotify auto-pause", - type: OptionType.BOOLEAN, - default: true, - restartNeeded: true, + find: 'dispatch({type:"SPOTIFY_PROFILE_UPDATE"', + replacement: { + match: /SPOTIFY_PROFILE_UPDATE.+?isPremium:(?="premium"===(\i)\.body\.product)/, + replace: (m, req) => `${m}(${req}.body.product="premium")&&` + }, }, - keepSpotifyActivityOnIdle: { - description: "Keep Spotify activity playing when idling", - type: OptionType.BOOLEAN, - default: false, - restartNeeded: true, + { + find: '.displayName="SpotifyStore"', + replacement: [ + { + predicate: () => settings.store.noSpotifyAutoPause, + match: /(?<=function \i\(\){)(?=.{0,200}SPOTIFY_AUTO_PAUSED\))/, + replace: "return;" + }, + { + predicate: () => settings.store.keepSpotifyActivityOnIdle, + match: /(?<=shouldShowActivity=function\(\){.{0,50})&&!\i\.\i\.isIdle\(\)/, + replace: "" + } + ] } - } + ] }); diff --git a/src/plugins/typingIndicator.tsx b/src/plugins/typingIndicator.tsx index 27c143b..9af09bc 100644 --- a/src/plugins/typingIndicator.tsx +++ b/src/plugins/typingIndicator.tsx @@ -121,8 +121,8 @@ export default definePlugin({ { find: ".UNREAD_HIGHLIGHT", replacement: { - match: /(?<=(?<channel>\i)=\i\.channel,.+?\(\)\.children.+?:null)/, - replace: ",$self.TypingIndicator($<channel>.id)" + match: /\(\).children.+?:null(?<=(\i)=\i\.channel,.+?)/, + replace: (m, channel) => `${m},$self.TypingIndicator(${channel}.id)` } } ], diff --git a/src/plugins/volumeBooster.ts b/src/plugins/volumeBooster.ts index 6553a5c..7d81449 100644 --- a/src/plugins/volumeBooster.ts +++ b/src/plugins/volumeBooster.ts @@ -16,14 +16,26 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { makeRange } from "@components/PluginSettings/components/SettingSliderComponent"; +import { definePluginSettings } from "@api/settings"; +import { makeRange } from "@components/PluginSettings/components"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; +const settings = definePluginSettings({ + multiplier: { + description: "Volume Multiplier", + type: OptionType.SLIDER, + markers: makeRange(1, 5, 1), + default: 2, + stickToMarkers: true, + } +}); + export default definePlugin({ name: "VolumeBooster", authors: [Devs.Nuckyz], description: "Allows you to set the user and stream volume above the default maximum.", + settings, patches: [ // Change the max volume for sliders to allow for values above 200 @@ -33,11 +45,10 @@ export default definePlugin({ ].map(find => ({ find, replacement: { - match: /maxValue:(?<defaultMaxVolumePredicate>\i\.\i)\?(?<higherMaxVolume>\d+?):(?<minorMaxVolume>\d+?),/, - replace: "" - + "maxValue:$<defaultMaxVolumePredicate>" - + "?$<higherMaxVolume>*Vencord.Settings.plugins.VolumeBooster.multiplier" - + ":$<minorMaxVolume>*Vencord.Settings.plugins.VolumeBooster.multiplier," + match: /(?<=maxValue:\i\.\i)\?(\d+?):(\d+?)(?=,)/, + replace: (_, higherMaxVolume, minorMaxVolume) => "" + + `?${higherMaxVolume}*$self.settings.store.multiplier` + + `:${minorMaxVolume}*$self.settings.store.multiplier` } })), // Prevent Audio Context Settings sync from trying to sync with values above 200, changing them to 200 before we send to Discord @@ -45,16 +56,16 @@ export default definePlugin({ find: "AudioContextSettingsMigrated", replacement: [ { - match: /(?<restOfFunction>updateAsync\("audioContextSettings".{1,50})(?<volumeChangeExpression>return (?<volumeOptions>\i)\.volume=(?<newVolume>\i))/, - replace: "$<restOfFunction>if($<newVolume>>200)return $<volumeOptions>.volume=200;$<volumeChangeExpression>" + match: /(?<=updateAsync\("audioContextSettings".{0,50})(?=return (\i)\.volume=(\i))/, + replace: (_, volumeOptions, newVolume) => `if(${newVolume}>200)return ${volumeOptions}.volume=200;` }, { - match: /(?<restOfFunction>Object\.entries\(\i\.localMutes\).+?)volume:(?<volumeExpression>.+?),/, - replace: "$<restOfFunction>volume:$<volumeExpression>>200?200:$<volumeExpression>," + match: /(?<=Object\.entries\(\i\.localMutes\).+?volume:).+?(?=,)/, + replace: "$&>200?200:$&" }, { - match: /(?<restOfFunction>Object\.entries\(\i\.localVolumes\).+?)volume:(?<volumeExpression>.+?)}\)/, - replace: "$<restOfFunction>volume:$<volumeExpression>>200?200:$<volumeExpression>})" + match: /(?<=Object\.entries\(\i\.localVolumes\).+?volume:).+?(?=})/, + replace: "$&>200?200:$&" } ] }, @@ -63,24 +74,13 @@ export default definePlugin({ find: '.displayName="MediaEngineStore"', replacement: [ { - match: /(?<restOfFunction>\.settings\.audioContextSettings.+?)(?<localVolume>\i\[\i\])=(?<syncVolume>\i\.volume)(?<secondRestOfFunction>.+?)setLocalVolume\((?<id>.+?),.+?\)/, - replace: "" - + "$<restOfFunction>" - + "($<localVolume>>200?undefined:$<localVolume>=$<syncVolume>)" - + "$<secondRestOfFunction>" - + "setLocalVolume($<id>,$<localVolume>??$<syncVolume>)" + match: /(?<=\.settings\.audioContextSettings.+?)(\i\[\i\])=(\i\.volume)(.+?setLocalVolume\(\i,).+?\)/, + replace: (_, localVolume, syncVolume, rest) => "" + + `(${localVolume}>200?void 0:${localVolume}=${syncVolume})` + + rest + + `${localVolume}??${syncVolume})` } ] } ], - - options: { - multiplier: { - description: "Volume Multiplier", - type: OptionType.SLIDER, - markers: makeRange(1, 5, 1), - default: 2, - stickToMarkers: true, - } - } }); diff --git a/src/plugins/whoReacted.tsx b/src/plugins/whoReacted.tsx index 8ab1c5f..4b1c828 100644 --- a/src/plugins/whoReacted.tsx +++ b/src/plugins/whoReacted.tsx @@ -93,8 +93,8 @@ export default definePlugin({ patches: [{ find: ",reactionRef:", replacement: { - match: /((.)=(.{1,3})\.hideCount)(,.+?reactionCount.+?\}\))/, - replace: "$1,whoReactedProps=$3$4,$2?null:$self.renderUsers(whoReactedProps)" + match: /(?<=(\i)=(\i)\.hideCount,)(.+?reactionCount.+?\}\))/, + replace: (_, hideCount, props, rest) => `whoReactedProps=${props},${rest},${hideCount}?null:$self.renderUsers(whoReactedProps)` } }], |