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>
This commit is contained in:
vee 2024-06-19 07:16:29 +02:00 committed by GitHub
parent d19b0aeb5b
commit 3505adad6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 126 additions and 151 deletions

View file

@ -1,7 +1,7 @@
{ {
"name": "vencord", "name": "vencord",
"private": "true", "private": "true",
"version": "1.8.9", "version": "1.9.0",
"description": "The cutest Discord client mod", "description": "The cutest Discord client mod",
"homepage": "https://github.com/Vendicated/Vencord#readme", "homepage": "https://github.com/Vendicated/Vencord#readme",
"bugs": { "bugs": {

View file

@ -25,7 +25,7 @@ export async function loadLazyChunks() {
// True if resolved, false otherwise // True if resolved, false otherwise
const chunksSearchPromises = [] as Array<() => boolean>; 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) { async function searchAndLoadLazyChunks(factoryCode: string) {
const lazyChunks = factoryCode.matchAll(LazyChunkRegex); const lazyChunks = factoryCode.matchAll(LazyChunkRegex);

View file

@ -35,11 +35,11 @@ export default definePlugin({
} }
}, },
{ {
find: ".handleSendMessage", find: ".handleSendMessage,onResize",
replacement: { replacement: {
// props.chatInputType...then((function(isMessageValid)... var parsedMessage = b.c.parse(channel,... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); // 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) // 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 }; // 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) => "" + replace: (_, rest1, rest2, parsedMessage, channel, replyOptions, extra) => "" +
`${rest1}async ${rest2}` + `${rest1}async ${rest2}` +

View file

@ -84,13 +84,6 @@ export default definePlugin({
replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}` 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", find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL",
replacement: { replacement: {

View file

@ -49,7 +49,7 @@ export default definePlugin({
predicate: () => settings.store.domain predicate: () => settings.store.domain
}, },
{ {
find: "isSuspiciousDownload:", find: "bitbucket.org",
replacement: { replacement: {
match: /function \i\(\i\){(?=.{0,60}\.parse\(\i\))/, match: /function \i\(\i\){(?=.{0,60}\.parse\(\i\))/,
replace: "$&return null;" replace: "$&return null;"

View file

@ -27,7 +27,7 @@ export default definePlugin({
{ {
find: "BAN_CONFIRM_TITLE.", find: "BAN_CONFIRM_TITLE.",
replacement: { replacement: {
match: /src:\i\(\d+\)/g, match: /src:\i\("?\d+"?\)/g,
replace: "src: Vencord.Settings.plugins.BANger.source" replace: "src: Vencord.Settings.plugins.BANger.source"
} }
} }

View file

@ -144,8 +144,8 @@ export default definePlugin({
replacement: [ replacement: [
{ {
// Modify the expanded state to instead return the list of expanded folders // Modify the expanded state to instead return the list of expanded folders
match: /(\i\).{0,20}=>)(\i\.\i)\.isFolderExpanded\(\i\)/, match: /(\],\(\)=>)(\i\.\i)\.isFolderExpanded\(\i\)\)/,
replace: (_, rest, ExpandedGuildFolderStore) => `${rest}${ExpandedGuildFolderStore}.getExpandedFolders()`, 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 // 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

View file

@ -88,7 +88,7 @@ export default definePlugin({
predicate: () => settings.store.disableFade predicate: () => settings.store.disableFade
}, },
{ // Lazy-load contents { // Lazy-load contents
match: /createPromise:\(\)=>([^:}]*?),webpackId:\d+,name:(?!="CollectiblesShop")"[^"]+"/g, match: /createPromise:\(\)=>([^:}]*?),webpackId:"?\d+"?,name:(?!="CollectiblesShop")"[^"]+"/g,
replace: "$&,_:$1", replace: "$&,_:$1",
predicate: () => settings.store.eagerLoad predicate: () => settings.store.eagerLoad
} }
@ -111,7 +111,7 @@ export default definePlugin({
{ // Load menu TOC eagerly { // Load menu TOC eagerly
find: "Messages.USER_SETTINGS_WITH_BUILD_OVERRIDE.format", find: "Messages.USER_SETTINGS_WITH_BUILD_OVERRIDE.format",
replacement: { 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)()," replace: "$&(async ()=>$2)(),"
}, },
predicate: () => settings.store.eagerLoad predicate: () => settings.store.eagerLoad
@ -119,8 +119,8 @@ export default definePlugin({
{ // Settings cog context menu { // Settings cog context menu
find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL", find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL",
replacement: { replacement: {
match: /\(0,\i.\i\)\(\)(?=\.filter\(\i=>\{let\{section:\i\}=)/, match: /(EXPERIMENTS:.+?)(\(0,\i.\i\)\(\))(?=\.filter\(\i=>\{let\{section:\i\}=)/,
replace: "$self.wrapMenu($&)" replace: "$1$self.wrapMenu($2)"
} }
} }
], ],

View file

@ -11,7 +11,7 @@ import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { classes } from "@utils/misc"; import { classes } from "@utils/misc";
import definePlugin, { OptionType, StartAt } from "@utils/types"; 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"; import { Button, Forms, useStateFromStores } from "@webpack/common";
const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
@ -30,7 +30,7 @@ function onPickColor(color: number) {
updateColorVars(hexColor); updateColorVars(hexColor);
} }
const { saveClientTheme } = findByPropsLazy("saveClientTheme"); const saveClientTheme = findByCodeLazy('type:"UNSYNCED_USER_SETTINGS_UPDATE",settings:{useSystemTheme:"system"===');
function setTheme(theme: string) { function setTheme(theme: string) {
saveClientTheme({ theme }); saveClientTheme({ theme });

View file

@ -24,20 +24,19 @@ import { closeAllModals } from "@utils/modal";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { maybePromptToUpdate } from "@utils/updater"; import { maybePromptToUpdate } from "@utils/updater";
import { filters, findBulk, proxyLazyWebpack } from "@webpack"; 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 CrashHandlerLogger = new Logger("CrashHandler");
const { ModalStack, DraftManager, closeExpressionPicker } = proxyLazyWebpack(() => { const { ModalStack, DraftManager } = proxyLazyWebpack(() => {
const [ModalStack, DraftManager, ExpressionManager] = findBulk( const [ModalStack, DraftManager] = findBulk(
filters.byProps("pushLazy", "popAll"), filters.byProps("pushLazy", "popAll"),
filters.byProps("clearDraft", "saveDraft"), filters.byProps("clearDraft", "saveDraft"),
filters.byProps("closeExpressionPicker", "openExpressionPicker"),); );
return { return {
ModalStack, ModalStack,
DraftManager, DraftManager
closeExpressionPicker: ExpressionManager?.closeExpressionPicker,
}; };
}); });
@ -144,7 +143,7 @@ export default definePlugin({
CrashHandlerLogger.debug("Failed to clear drafts.", err); CrashHandlerLogger.debug("Failed to clear drafts.", err);
} }
try { try {
closeExpressionPicker(); ExpressionPickerStore.closeExpressionPicker();
} }
catch (err) { catch (err) {
CrashHandlerLogger.debug("Failed to close expression picker.", err); CrashHandlerLogger.debug("Failed to close expression picker.", err);

View file

@ -10,5 +10,5 @@ import { extractAndLoadChunksLazy, findByPropsLazy } from "@webpack";
export const cl = classNameFactory("vc-decor-"); export const cl = classNameFactory("vc-decor-");
export const DecorationModalStyles = findByPropsLazy("modalFooterShopButton"); export const DecorationModalStyles = findByPropsLazy("modalFooterShopButton");
export const requireAvatarDecorationModal = extractAndLoadChunksLazy(["openAvatarDecorationModal:"]); export const requireAvatarDecorationModal = extractAndLoadChunksLazy([".COLLECTIBLES_SHOP_FULLSCREEN&&"]);
export const requireCreateStickerModal = extractAndLoadChunksLazy(["stickerInspected]:"]); export const requireCreateStickerModal = extractAndLoadChunksLazy(["stickerInspected]:"]);

View file

@ -9,7 +9,7 @@ import { Link } from "@components/Link";
import { openInviteModal } from "@utils/discord"; import { openInviteModal } from "@utils/discord";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; 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 { 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"; import { GUILD_ID, INVITE_KEY, RAW_SKU_ID } from "../../lib/constants";
@ -19,7 +19,10 @@ import { AvatarDecorationModalPreview } from "../components";
const FileUpload = findComponentByCodeLazy("fileUploadInput,"); 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) { function useObjectURL(object: Blob | MediaSource | null) {
const [url, setUrl] = useState<string | null>(null); const [url, setUrl] = useState<string | null>(null);

View file

@ -23,12 +23,12 @@ import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal"; import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
import definePlugin from "@utils/types"; 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 { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
import { Promisable } from "type-fest"; import { Promisable } from "type-fest";
const StickersStore = findStoreLazy("StickersStore"); const StickersStore = findStoreLazy("StickersStore");
const EmojiManager = findByPropsLazy("fetchEmoji", "uploadEmoji", "deleteEmoji"); const uploadEmoji = findByCodeLazy(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START");
interface Sticker { interface Sticker {
t: "Sticker"; t: "Sticker";
@ -106,7 +106,7 @@ async function cloneEmoji(guildId: string, emoji: Emoji) {
reader.readAsDataURL(data); reader.readAsDataURL(data);
}); });
return EmojiManager.uploadEmoji({ return uploadEmoji({
guildId, guildId,
name: emoji.name.split("~")[0], name: emoji.name.split("~")[0],
image: dataUrl image: dataUrl

View file

@ -28,7 +28,7 @@ import { Forms, React } from "@webpack/common";
import hideBugReport from "./hideBugReport.css?managed"; import hideBugReport from "./hideBugReport.css?managed";
const KbdStyles = findByPropsLazy("key", "removeBuildOverride"); const KbdStyles = findByPropsLazy("key", "combo");
const settings = definePluginSettings({ const settings = definePluginSettings({
toolbarDevMenu: { toolbarDevMenu: {
@ -106,9 +106,11 @@ export default definePlugin({
<Forms.FormTitle tag="h3">More Information</Forms.FormTitle> <Forms.FormTitle tag="h3">More Information</Forms.FormTitle>
<Forms.FormText variant="text-md/normal"> <Forms.FormText variant="text-md/normal">
You can open Discord's DevTools via {" "} You can open Discord's DevTools via {" "}
<div className={KbdStyles.combo} style={{ display: "inline-flex" }}>
<kbd className={KbdStyles.key}>{modKey}</kbd> +{" "} <kbd className={KbdStyles.key}>{modKey}</kbd> +{" "}
<kbd className={KbdStyles.key}>{altKey}</kbd> +{" "} <kbd className={KbdStyles.key}>{altKey}</kbd> +{" "}
<kbd className={KbdStyles.key}>O</kbd>{" "} <kbd className={KbdStyles.key}>O</kbd>{" "}
</div>
</Forms.FormText> </Forms.FormText>
</React.Fragment> </React.Fragment>
); );

View file

@ -37,8 +37,8 @@ const StickerStore = findStoreLazy("StickersStore") as {
}; };
const UserSettingsProtoStore = findStoreLazy("UserSettingsProtoStore"); 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) { function searchProtoClassField(localName: string, protoClass: any) {
const field = protoClass?.fields?.find((field: any) => field.localName === localName); 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 PreloadedUserSettingsActionCreators = proxyLazyWebpack(() => UserSettingsActionCreators.PreloadedUserSettingsActionCreators);
const AppearanceSettingsActionCreators = proxyLazyWebpack(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators.ProtoClass)); const AppearanceSettingsActionCreators = proxyLazyWebpack(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators));
const ClientThemeSettingsActionsCreators = proxyLazyWebpack(() => searchProtoClassField("clientThemeSettings", AppearanceSettingsActionCreators)); const ClientThemeSettingsActionsCreators = proxyLazyWebpack(() => searchProtoClassField("clientThemeSettings", AppearanceSettingsActionCreators));
@ -234,15 +234,16 @@ export default definePlugin({
} }
] ]
}, },
// FIXME
// Allows the usage of subscription-locked emojis // Allows the usage of subscription-locked emojis
{ /* {
find: "isUnusableRoleSubscriptionEmoji:function", find: ".getUserIsAdmin(",
replacement: { 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 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 // Allow stickers to be sent everywhere
{ {
find: "canUseCustomStickersEverywhere:function", find: "canUseCustomStickersEverywhere:function",
@ -361,7 +362,7 @@ export default definePlugin({
replacement: [ replacement: [
{ {
// Export the renderable sticker to be used in the fake nitro sticker notice // 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},` replace: (m, renderableSticker) => `${m}fakeNitroRenderableSticker:${renderableSticker},`
}, },
{ {
@ -472,12 +473,12 @@ export default definePlugin({
const premiumType = UserStore?.getCurrentUser()?.premiumType ?? 0; const premiumType = UserStore?.getCurrentUser()?.premiumType ?? 0;
if (premiumType === 2 || backgroundGradientPresetId == null) return original(); 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 currentAppearanceSettings = PreloadedUserSettingsActionCreators.getCurrentValue().appearance;
const newAppearanceProto = currentAppearanceSettings != null const newAppearanceProto = currentAppearanceSettings != null
? AppearanceSettingsActionCreators.fromBinary(AppearanceSettingsActionCreators.toBinary(currentAppearanceSettings), ProtoUtils.BINARY_READ_OPTIONS) ? AppearanceSettingsActionCreators.fromBinary(AppearanceSettingsActionCreators.toBinary(currentAppearanceSettings), BINARY_READ_OPTIONS)
: AppearanceSettingsActionCreators.create(); : AppearanceSettingsActionCreators.create();
newAppearanceProto.theme = theme; newAppearanceProto.theme = theme;
@ -816,8 +817,9 @@ export default definePlugin({
if (e.type === 0) return true; if (e.type === 0) return true;
if (e.available === false) return false; if (e.available === false) return false;
const isUnusableRoleSubEmoji = RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmojiOriginal ?? RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmoji; // FIXME
if (isUnusableRoleSubEmoji(e, this.guildId)) return false; /* const isUnusableRoleSubEmoji = isUnusableRoleSubscriptionEmojiOriginal ?? RoleSubscriptionEmojiUtils.isUnusableRoleSubscriptionEmoji;
if (isUnusableRoleSubEmoji(e, this.guildId)) return false; */
if (this.canUseEmotes) if (this.canUseEmotes)
return e.guildId === this.guildId || hasExternalEmojiPerms(channelId); return e.guildId === this.guildId || hasExternalEmojiPerms(channelId);

View file

@ -111,7 +111,7 @@ interface ProfileModalProps {
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
const ProfileModal = findComponentByCodeLazy<ProfileModalProps>('"ProfileCustomizationPreview"'); const ProfileModal = findComponentByCodeLazy<ProfileModalProps>('"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({ export default definePlugin({
name: "FakeProfileThemes", name: "FakeProfileThemes",

View file

@ -27,7 +27,7 @@ export default definePlugin({
authors: [Devs.D3SOX, Devs.Nickyux], authors: [Devs.D3SOX, Devs.Nickyux],
patches: [ patches: [
{ {
find: "AVATAR_DECORATION_PADDING:", find: ".PREMIUM_GUILD_SUBSCRIPTION_TOOLTIP",
replacement: { replacement: {
match: /,isOwner:(\i),/, match: /,isOwner:(\i),/,
replace: ",_isOwner:$1=$self.isGuildOwner(e)," replace: ",_isOwner:$1=$self.isGuildOwner(e),"

View file

@ -16,14 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands"; import { ApplicationCommandInputType, sendBotMessage } from "@api/Commands";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin from "@utils/types"; import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { findByPropsLazy } from "@webpack";
import { Constants, RestAPI, UserStore } from "@webpack/common";
const FriendInvites = findByPropsLazy("createFriendInvite"); const FriendInvites = findByPropsLazy("createFriendInvite");
const { uuid4 } = findByPropsLazy("uuid4");
export default definePlugin({ export default definePlugin({
name: "FriendInvites", name: "FriendInvites",
@ -35,47 +33,9 @@ export default definePlugin({
name: "create friend invite", name: "create friend invite",
description: "Generates a friend invite link.", description: "Generates a friend invite link.",
inputType: ApplicationCommandInputType.BOT, 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) => { execute: async (args, ctx) => {
const uses = findOption<number>(args, "Uses", 5); const invite = await FriendInvites.createFriendInvite();
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();
}
sendBotMessage(ctx.channel.id, { sendBotMessage(ctx.channel.id, {
content: ` content: `

View file

@ -4,21 +4,23 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { getCurrentChannel } from "@utils/discord"; import { getCurrentChannel } from "@utils/discord";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import { classes } from "@utils/misc"; import { classes } from "@utils/misc";
import definePlugin from "@utils/types"; import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { findByCodeLazy, findByPropsLazy } from "@webpack";
import { Heading, React, RelationshipStore, Text } from "@webpack/common"; import { Heading, React, RelationshipStore, Text } from "@webpack/common";
const container = findByPropsLazy("memberSinceWrapper"); const container = findByPropsLazy("memberSinceWrapper");
const { getCreatedAtDate } = findByPropsLazy("getCreatedAtDate"); const getCreatedAtDate = findByCodeLazy('month:"short",day:"numeric"');
const clydeMoreInfo = findByPropsLazy("clydeMoreInfo");
const locale = findByPropsLazy("getLocale"); const locale = findByPropsLazy("getLocale");
const lastSection = findByPropsLazy("lastSection"); const lastSection = findByPropsLazy("lastSection");
const cl = classNameFactory("vc-friendssince-");
export default definePlugin({ export default definePlugin({
name: "FriendsSince", name: "FriendsSince",
description: "Shows when you became friends with someone in the user popout", description: "Shows when you became friends with someone in the user popout",
@ -28,7 +30,7 @@ export default definePlugin({
{ {
find: ".USER_PROFILE}};return", find: ".USER_PROFILE}};return",
replacement: { replacement: {
match: /\i.\i,\{userId:(\i.id).{0,30}}\)/, match: /,{userId:(\i.id).{0,30}}\)/,
replace: "$&,$self.friendsSince({ userId: $1 })" replace: "$&,$self.friendsSince({ userId: $1 })"
} }
}, },
@ -36,7 +38,7 @@ export default definePlugin({
{ {
find: ".PROFILE_PANEL,", find: ".PROFILE_PANEL,",
replacement: { replacement: {
match: /\i.\i,\{userId:([^,]+?)}\)/, match: /,{userId:([^,]+?)}\)/,
replace: "$&,$self.friendsSince({ userId: $1 })" replace: "$&,$self.friendsSince({ userId: $1 })"
} }
}, },
@ -69,7 +71,7 @@ export default definePlugin({
return ( return (
<div className={lastSection.section}> <div className={lastSection.section}>
<Heading variant="eyebrow" className={clydeMoreInfo.title}> <Heading variant="eyebrow" className={cl("title")}>
Friends Since Friends Since
</Heading> </Heading>
@ -86,7 +88,7 @@ export default definePlugin({
<path d="M3 5v-.75C3 3.56 3.56 3 4.25 3s1.24.56 1.33 1.25C6.12 8.65 9.46 12 13 12h1a8 8 0 0 1 8 8 2 2 0 0 1-2 2 .21.21 0 0 1-.2-.15 7.65 7.65 0 0 0-1.32-2.3c-.15-.2-.42-.06-.39.17l.25 2c.02.15-.1.28-.25.28H9a2 2 0 0 1-2-2v-2.22c0-1.57-.67-3.05-1.53-4.37A15.85 15.85 0 0 1 3 5Z" /> <path d="M3 5v-.75C3 3.56 3.56 3 4.25 3s1.24.56 1.33 1.25C6.12 8.65 9.46 12 13 12h1a8 8 0 0 1 8 8 2 2 0 0 1-2 2 .21.21 0 0 1-.2-.15 7.65 7.65 0 0 0-1.32-2.3c-.15-.2-.42-.06-.39.17l.25 2c.02.15-.1.28-.25.28H9a2 2 0 0 1-2-2v-2.22c0-1.57-.67-3.05-1.53-4.37A15.85 15.85 0 0 1 3 5Z" />
</svg> </svg>
)} )}
<Text variant="text-sm/normal" className={classes(clydeMoreInfo.body, textClassName)}> <Text variant="text-sm/normal" className={classes(cl("body"), textClassName)}>
{getCreatedAtDate(friendsSince, locale.getLocale())} {getCreatedAtDate(friendsSince, locale.getLocale())}
</Text> </Text>
</div> </div>

View file

@ -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
}

View file

@ -19,9 +19,7 @@
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { insertTextIntoChatInputBox } from "@utils/discord"; import { insertTextIntoChatInputBox } from "@utils/discord";
import definePlugin from "@utils/types"; import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { ExpressionPickerStore } from "@webpack/common";
const { closeExpressionPicker } = findByPropsLazy("closeExpressionPicker");
export default definePlugin({ export default definePlugin({
name: "GifPaste", name: "GifPaste",
@ -39,7 +37,7 @@ export default definePlugin({
handleSelect(gif?: { url: string; }) { handleSelect(gif?: { url: string; }) {
if (gif) { if (gif) {
insertTextIntoChatInputBox(gif.url + " "); insertTextIntoChatInputBox(gif.url + " ");
closeExpressionPicker(); ExpressionPickerStore.closeExpressionPicker();
} }
} }
}); });

View file

@ -19,7 +19,7 @@
import { definePluginSettings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { findLazy } from "@webpack";
import { ContextMenuApi, FluxDispatcher, Menu, MessageActions } from "@webpack/common"; import { ContextMenuApi, FluxDispatcher, Menu, MessageActions } from "@webpack/common";
import { Channel, Message } from "discord-types/general"; import { Channel, Message } from "discord-types/general";
@ -49,7 +49,7 @@ const settings = definePluginSettings({
unholyMultiGreetEnabled?: boolean; 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[]) { function greet(channel: Channel, message: Message, stickers: string[]) {
const options = MessageActions.getSendMessageOptionsForReply({ const options = MessageActions.getSendMessageOptionsForReply({

View file

@ -16,7 +16,8 @@ export default definePlugin({
{ {
find: "unknownUserMentionPlaceholder:", find: "unknownUserMentionPlaceholder:",
replacement: { replacement: {
match: /\(0,\i\.isEmbedInline\)\(\i\)/, // SimpleEmbedTypes.has(embed.type) && isEmbedInline(embed)
match: /\i\.has\(\i\.type\)&&\(0,\i\.\i\)\(\i\)/,
replace: "false", replace: "false",
} }
} }

View file

@ -19,17 +19,11 @@
import { definePluginSettings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findStoreLazy } from "@webpack"; import { findStoreLazy } from "@webpack";
import { ChannelStore, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserStore } from "@webpack/common"; import { ChannelStore, Constants, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserStore } from "@webpack/common";
import { Settings } from "Vencord"; import { Settings } from "Vencord";
const UserAffinitiesStore = findStoreLazy("UserAffinitiesStore"); const UserAffinitiesStore = findStoreLazy("UserAffinitiesStore");
const { FriendsSections } = findByPropsLazy("FriendsSections");
interface UserAffinity {
user_id: string;
affinity: number;
}
export default definePlugin({ export default definePlugin({
name: "ImplicitRelationships", name: "ImplicitRelationships",
@ -70,7 +64,7 @@ export default definePlugin({
}, },
// Piggyback relationship fetch // Piggyback relationship fetch
{ {
find: ".fetchRelationships()", find: '"FriendsStore',
replacement: { replacement: {
match: /(\i\.\i)\.fetchRelationships\(\)/, match: /(\i\.\i)\.fetchRelationships\(\)/,
// This relationship fetch is actually completely useless, but whatevs // This relationship fetch is actually completely useless, but whatevs
@ -182,6 +176,6 @@ export default definePlugin({
}, },
start() { start() {
FriendsSections.IMPLICIT = "IMPLICIT"; Constants.FriendsSections.IMPLICIT = "IMPLICIT";
} }
}); });

View file

@ -44,7 +44,6 @@ const pluginsValues = Object.values(Plugins);
const settings = Settings.plugins; const settings = Settings.plugins;
const forceDisabled = new Set([ const forceDisabled = new Set([
"ShowHiddenChannels",
"MoreUserTags" "MoreUserTags"
]); ]);
export function isPluginEnabled(p: string) { export function isPluginEnabled(p: string) {

View file

@ -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 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({ export default definePlugin({
name: "MaskedLinkPaste", name: "MaskedLinkPaste",

View file

@ -19,11 +19,11 @@
import { definePluginSettings, migratePluginSettings } from "@api/Settings"; import { definePluginSettings, migratePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { findByCodeLazy, findByPropsLazy } from "@webpack";
const { updateGuildNotificationSettings } = findByPropsLazy("updateGuildNotificationSettings"); const { updateGuildNotificationSettings } = findByPropsLazy("updateGuildNotificationSettings");
const { toggleShowAllChannels } = findByPropsLazy("toggleShowAllChannels"); const { toggleShowAllChannels } = findByPropsLazy("toggleShowAllChannels");
const { isOptInEnabledForGuild } = findByPropsLazy("isOptInEnabledForGuild"); const isOptInEnabledForGuild = findByCodeLazy(".COMMUNITY)||", ".isOptInEnabled(");
const settings = definePluginSettings({ const settings = definePluginSettings({
guild: { guild: {

View file

@ -56,8 +56,8 @@ export default definePlugin({
replace: "children: $self.renderInvitesLabel({guildId:arguments[0].guildId,setChecked})", replace: "children: $self.renderInvitesLabel({guildId:arguments[0].guildId,setChecked})",
}, },
{ {
match: /(\i\.\i\)\(\i\),\[\i,(\i)\]=\i\.useState\(\i\))/, match: /\.INVITES_DISABLED\)(?=.+?\.Messages\.INVITES_PERMANENTLY_DISABLED_TIP.+?checked:(\i)).+?\[\1,(\i)\]=\i.useState\(\i\)/,
replace: "$1,setChecked=$2" replace: "$&,setChecked=$2"
} }
] ]
} }

View file

@ -6,6 +6,7 @@
import { definePluginSettings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { canonicalizeMatch } from "@utils/patches";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
const settings = definePluginSettings({ const settings = definePluginSettings({
@ -31,7 +32,7 @@ export default definePlugin({
patches: [ patches: [
// Permission lockout, just set the check to true // Permission lockout, just set the check to true
{ {
find: ".showPermissionLockoutModal(", find: ".STAGE_CHANNEL_CANNOT_OVERWRITE_PERMISSION",
replacement: [ replacement: [
{ {
match: /case"DENY":.{0,50}if\((?=\i\.\i\.can)/, match: /case"DENY":.{0,50}if\((?=\i\.\i\.can)/,
@ -45,9 +46,8 @@ export default definePlugin({
find: ".ONBOARDING_CHANNEL_THRESHOLD_WARNING", find: ".ONBOARDING_CHANNEL_THRESHOLD_WARNING",
replacement: [ replacement: [
{ {
// are we java yet? match: /{(\i:function\(\){return \i},?){2}}/,
match: /(?<=(?:isDefaultChannelThresholdMetAfterDelete|checkDefaultChannelThresholdMetAfterChannelPermissionDeny):function\(\)\{)return \i(?=\})/g, replace: m => m.replaceAll(canonicalizeMatch(/return \i/g), "return ()=>Promise.resolve(true)")
replace: "return () => true"
} }
], ],
predicate: () => settings.store.onboarding predicate: () => settings.store.onboarding

View file

@ -33,7 +33,7 @@ interface ColorPickerWithSwatchesProps {
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
const ColorPickerWithSwatches = findExportedComponentLazy<ColorPickerWithSwatchesProps>("ColorPicker", "CustomColorPicker"); const ColorPickerWithSwatches = findExportedComponentLazy<ColorPickerWithSwatchesProps>("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-"); const cl = classNameFactory("vc-pindms-modal-");

View file

@ -21,7 +21,7 @@ import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { findByPropsLazy } from "@webpack";
const SpoilerClasses = findByPropsLazy("spoilerContent"); const SpoilerClasses = findByPropsLazy("spoilerContent");
const MessagesClasses = findByPropsLazy("messagesWrapper", "messages"); const MessagesClasses = findByPropsLazy("messagesWrapper");
export default definePlugin({ export default definePlugin({
name: "RevealAllSpoilers", name: "RevealAllSpoilers",

View file

@ -142,7 +142,7 @@ export default LazyComponent(() => {
{review.type === ReviewType.System && ( {review.type === ReviewType.System && (
<span <span
className={classes(botTag.botTagVerified, botTag.botTagRegular, botTag.botTag, botTag.px, botTag.rem)} className={classes(botTag.botTagVerified, botTag.botTagRegular, botTag.px, botTag.rem)}
style={{ marginLeft: "4px" }}> style={{ marginLeft: "4px" }}>
<span className={botTag.botText}> <span className={botTag.botText}>
System System

View file

@ -57,7 +57,7 @@ export default definePlugin({
{ {
find: "SUMMARIZEABLE.has", find: "SUMMARIZEABLE.has",
replacement: { replacement: {
match: /\i\.hasFeature\(.{0,10}\.SUMMARIES_ENABLED\w+?\)/g, match: /\i\.hasFeature\(\i\.\i\.SUMMARIES_ENABLED\w+?\)/g,
replace: "true" replace: "true"
} }
}, },

View file

@ -116,14 +116,14 @@ export default definePlugin({
}, },
// Prevent Discord from trying to connect to hidden stage channels // Prevent Discord from trying to connect to hidden stage channels
{ {
find: ".MAX_STAGE_VOICE_USER_LIMIT})", find: ".AUDIENCE),{isSubscriptionGated",
replacement: { replacement: {
match: /!(\i)\.isRoleSubscriptionTemplatePreviewChannel\(\)/, match: /!(\i)\.isRoleSubscriptionTemplatePreviewChannel\(\)/,
replace: (m, channel) => `${m}&&!$self.isHiddenChannel(${channel})` replace: (m, channel) => `${m}&&!$self.isHiddenChannel(${channel})`
} }
}, },
{ {
find: "ChannelItemEditButton:function(){", find: 'tutorialId:"instant-invite"',
replacement: [ replacement: [
// Render null instead of the buttons if the channel is hidden // 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 // Hide the new version of unreads box for hidden channels
find: '="ChannelListUnreadsStore",', find: '="ChannelListUnreadsStore",',
replacement: { 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})` replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})`
} }
}, },
@ -203,15 +203,15 @@ export default definePlugin({
// Make the old version of unreads box not visible for hidden channels // Make the old version of unreads box not visible for hidden channels
find: "renderBottomUnread(){", find: "renderBottomUnread(){",
replacement: { replacement: {
match: /(?=&&\(0,\i\.getHasImportantUnread\)\((\i\.record)\))/, match: /(?<=!0\))(?=&&\(0,\i\.\i\)\((\i\.record)\))/,
replace: "&&!$self.isHiddenChannel($1)" replace: "&&!$self.isHiddenChannel($1)"
} }
}, },
{ {
// Make the state of the old version of unreads box not include hidden channels // Make the state of the old version of unreads box not include hidden channels
find: ".useFlattenedChannelIdListWithThreads)", find: "ignoreRecents:!0",
replacement: { replacement: {
match: /(?=&&\(0,\i\.getHasImportantUnread\)\((\i)\))/, match: /(?<=\.id\)\))(?=&&\(0,\i\.\i\)\((\i)\))/,
replace: "&&!$self.isHiddenChannel($1)" replace: "&&!$self.isHiddenChannel($1)"
} }
}, },
@ -257,7 +257,7 @@ export default definePlugin({
{ {
find: '"alt+shift+down"', find: '"alt+shift+down"',
replacement: { 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})` 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 // 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))` 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 // 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)" replace: "&&!$self.isHiddenChannel($1)"
} }
] ]

View file

@ -47,9 +47,9 @@ export default definePlugin({
} }
}, },
{ {
find: ".trackEmojiSearchEmpty,200", find: ".EMOJI_PICKER_CONSTANTS_EMOJI_CONTAINER_PADDING_HORIZONTAL)",
replacement: { 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})` replace: (_, rest, isBurstReactionVariable, isReactionIntention) => `${rest}$self.shouldSuperReactByDefault&&${isReactionIntention})`
} }
} }

View file

@ -6,7 +6,7 @@
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin from "@utils/types"; import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { findByCodeLazy } from "@webpack";
import { FluxDispatcher, RestAPI } from "@webpack/common"; import { FluxDispatcher, RestAPI } from "@webpack/common";
import { Message, User } from "discord-types/general"; import { Message, User } from "discord-types/general";
import { Channel } from "discord-types/general/index.js"; import { Channel } from "discord-types/general/index.js";
@ -29,7 +29,7 @@ interface Reply {
const fetching = new Map<string, string>(); const fetching = new Map<string, string>();
let ReplyStore: any; let ReplyStore: any;
const { createMessageRecord } = findByPropsLazy("createMessageRecord"); const createMessageRecord = findByCodeLazy(".createFromServer(", ".isBlockedForMessage", "messageReference:");
export default definePlugin({ export default definePlugin({
name: "ValidReply", name: "ValidReply",

View file

@ -219,4 +219,5 @@ export interface IconUtils {
export interface Constants { export interface Constants {
Endpoints: Record<string, any>; Endpoints: Record<string, any>;
UserFlags: Record<string, number>; UserFlags: Record<string, number>;
FriendsSections: Record<string, string>;
} }

View file

@ -16,6 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { canonicalizeMatch } from "@utils/patches";
import type { Channel } from "discord-types/general"; import type { Channel } from "discord-types/general";
// eslint-disable-next-line path-alias/no-relative // 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"', { export const Constants: t.Constants = mapMangledModuleLazy('ME:"/users/@me"', {
Endpoints: filters.byProps("USER", "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); 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 InviteActions = findByPropsLazy("resolveInvite");
export const IconUtils: t.IconUtils = findByPropsLazy("getGuildBannerURL", "getUserAvatarURL"); 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()),
});

View file

@ -106,7 +106,7 @@ export const find = traceFunction("find", function find(filter: FilterFn, { isIn
for (const key in cache) { for (const key in cache) {
const mod = cache[key]; const mod = cache[key];
if (!mod?.exports) continue; if (!mod.loaded || !mod?.exports) continue;
if (filter(mod.exports)) { if (filter(mod.exports)) {
return isWaitFor ? [mod.exports, key] : mod.exports; return isWaitFor ? [mod.exports, key] : mod.exports;
@ -142,7 +142,7 @@ export function findAll(filter: FilterFn) {
const ret = [] as any[]; const ret = [] as any[];
for (const key in cache) { for (const key in cache) {
const mod = cache[key]; const mod = cache[key];
if (!mod?.exports) continue; if (!mod.loaded || !mod?.exports) continue;
if (filter(mod.exports)) if (filter(mod.exports))
ret.push(mod.exports); ret.push(mod.exports);
@ -190,7 +190,7 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns
outer: outer:
for (const key in cache) { for (const key in cache) {
const mod = cache[key]; const mod = cache[key];
if (!mod?.exports) continue; if (!mod.loaded || !mod?.exports) continue;
for (let j = 0; j < length; j++) { for (let j = 0; j < length; j++) {
const filter = filters[j]; const filter = filters[j];
@ -486,7 +486,7 @@ export function mapMangledModuleLazy<S extends string>(code: string, mappers: Re
return proxyLazy(() => mapMangledModule(code, mappers)); 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; export const ChunkIdsRegex = /\("([^"]+?)"\)/g;
/** /**