🧹🧹🧹

This commit is contained in:
Nuckyz 2024-07-24 17:55:35 -03:00 committed by GitHub
parent fb394c6e1a
commit 1f20074d4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 184 additions and 187 deletions

View file

@ -97,12 +97,15 @@ async function runReporter() {
result = findResult; result = findResult;
for (const innerMap in result) { for (const innerMap in result) {
if (result[innerMap][SYM_PROXY_INNER_GET] != null && result[innerMap][SYM_PROXY_INNER_VALUE] == null) { if (
throw new Error("Webpack Find Fail"); (result[innerMap][SYM_PROXY_INNER_GET] != null && result[innerMap][SYM_PROXY_INNER_VALUE] == null) ||
} else if (result[innerMap][SYM_LAZY_COMPONENT_INNER] != null && result[innerMap][SYM_LAZY_COMPONENT_INNER]() == null) { (result[innerMap][SYM_LAZY_COMPONENT_INNER] != null && result[innerMap][SYM_LAZY_COMPONENT_INNER]() == null)
) {
throw new Error("Webpack Find Fail"); throw new Error("Webpack Find Fail");
} }
} }
break;
} }
// This can happen if a `find` was immediately found // This can happen if a `find` was immediately found
@ -125,9 +128,10 @@ async function runReporter() {
if (args[0].$$vencordProps != null) { if (args[0].$$vencordProps != null) {
if (["find", "findComponent", "waitFor"].includes(searchType)) { if (["find", "findComponent", "waitFor"].includes(searchType)) {
filterName = args[0].$$vencordProps[0]; filterName = args[0].$$vencordProps[0];
parsedArgs = args[0].$$vencordProps.slice(1);
} else {
parsedArgs = args[0].$$vencordProps;
} }
parsedArgs = args[0].$$vencordProps.slice(1);
} }
function stringifyCodeFilter(code: string | RegExp | Webpack.CodeFilter) { function stringifyCodeFilter(code: string | RegExp | Webpack.CodeFilter) {

View file

@ -93,7 +93,7 @@ export default definePlugin({
// Ensure this is most likely the Sentry WebpackInstance. // Ensure this is most likely the Sentry WebpackInstance.
// Function.g is a very generic property and is not uncommon for another WebpackInstance (or even a React component: <g></g>) to include it // Function.g is a very generic property and is not uncommon for another WebpackInstance (or even a React component: <g></g>) to include it
const { stack } = new Error(); const { stack } = new Error();
if (!(stack?.includes("discord.com") || stack?.includes("discordapp.com")) || !String(this).includes("exports:{}") || this.c != null) { if (!stack?.includes("/assets/") || !String(this).includes("exports:{}") || this.c != null) {
return; return;
} }

View file

@ -37,14 +37,14 @@ function setTheme(theme: string) {
} }
const ThemeStore = findStore("ThemeStore"); const ThemeStore = findStore("ThemeStore");
const NitroThemeStore = findStore("ClientThemesBackgroundStore"); const ClientThemesBackgroundStore = findStore("ClientThemesBackgroundStore");
function ThemeSettings() { function ThemeSettings() {
const theme = useStateFromStores([ThemeStore], () => ThemeStore.theme); const theme = useStateFromStores([ThemeStore], () => ThemeStore.theme);
const isLightTheme = theme === "light"; const isLightTheme = theme === "light";
const oppositeTheme = isLightTheme ? "dark" : "light"; const oppositeTheme = isLightTheme ? "dark" : "light";
const nitroTheme = useStateFromStores([NitroThemeStore], () => NitroThemeStore.gradientPreset); const nitroTheme = useStateFromStores([ClientThemesBackgroundStore], () => ClientThemesBackgroundStore.gradientPreset);
const nitroThemeEnabled = nitroTheme !== undefined; const nitroThemeEnabled = nitroTheme !== undefined;
const selectedLuminance = relativeLuminance(settings.store.color); const selectedLuminance = relativeLuminance(settings.store.color);

View file

@ -94,8 +94,8 @@ function makeShortcuts() {
findAllByProps: (...props: string[]) => cacheFindAll(filters.byProps(...props)), findAllByProps: (...props: string[]) => cacheFindAll(filters.byProps(...props)),
findByCode: newFindWrapper(filters.byCode), findByCode: newFindWrapper(filters.byCode),
findAllByCode: (code: string) => cacheFindAll(filters.byCode(code)), findAllByCode: (code: string) => cacheFindAll(filters.byCode(code)),
findComponentByCode: newFindWrapper(filters.byComponentCode), findComponentByCode: newFindWrapper(filters.componentByCode),
findAllComponentsByCode: (...code: string[]) => cacheFindAll(filters.byComponentCode(...code)), findAllComponentsByCode: (...code: string[]) => cacheFindAll(filters.componentByCode(...code)),
findExportedComponent: (...props: string[]) => findByProps(...props)[props[0]], findExportedComponent: (...props: string[]) => findByProps(...props)[props[0]],
findStore: newFindWrapper(filters.byStoreName), findStore: newFindWrapper(filters.byStoreName),
findByFactoryCode: newFindWrapper(filters.byFactoryCode), findByFactoryCode: newFindWrapper(filters.byFactoryCode),

View file

@ -19,9 +19,7 @@ type DecorationGridItemComponent = ComponentType<PropsWithChildren<HTMLProps<HTM
export let DecorationGridItem: DecorationGridItemComponent = NoopComponent; export let DecorationGridItem: DecorationGridItemComponent = NoopComponent;
export const setDecorationGridItem = v => DecorationGridItem = v; export const setDecorationGridItem = v => DecorationGridItem = v;
export const AvatarDecorationModalPreview = findComponentByCode(".shopPreviewBanner", component => { export const AvatarDecorationModalPreview = findComponentByCode(".shopPreviewBanner", component => React.memo(component));
return React.memo(component);
});
type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivElement> & { type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivElement> & {
avatarDecoration: AvatarDecoration; avatarDecoration: AvatarDecoration;

View file

@ -20,7 +20,7 @@ import { AvatarDecorationModalPreview } from "../components";
const FileUpload = findComponentByCode("fileUploadInput,"); const FileUpload = findComponentByCode("fileUploadInput,");
const { HelpMessage, HelpMessageTypes } = mapMangledModule('POSITIVE=3]="POSITIVE', { const { HelpMessage, HelpMessageTypes } = mapMangledModule('POSITIVE=3]="POSITIVE', {
HelpMessage: filters.byComponentCode(".iconDiv,", "messageType"), HelpMessage: filters.componentByCode(".iconDiv,", "messageType"),
HelpMessageTypes: filters.byProps("POSITIVE", "WARNING"), HelpMessageTypes: filters.byProps("POSITIVE", "WARNING"),
}); });

View file

@ -216,7 +216,7 @@ function initWs(isManual = false) {
results = Object.keys(search(parsedArgs[0])); results = Object.keys(search(parsedArgs[0]));
break; break;
case "ComponentByCode": case "ComponentByCode":
results = cacheFindAll(filters.byComponentCode(...parsedArgs)); results = cacheFindAll(filters.componentByCode(...parsedArgs));
break; break;
default: default:
return reply("Unknown Find Type " + type); return reply("Unknown Find Type " + type);

View file

@ -30,7 +30,7 @@ import type { Message } from "discord-types/general";
import { applyPalette, GIFEncoder, quantize } from "gifenc"; import { applyPalette, GIFEncoder, quantize } from "gifenc";
import type { ReactElement, ReactNode } from "react"; import type { ReactElement, ReactNode } from "react";
const StickerStore = findStore("StickersStore") as { const StickersStore = findStore("StickersStore") as {
getPremiumPacks(): StickerPack[]; getPremiumPacks(): StickerPack[];
getAllGuildStickers(): Map<string, Sticker[]>; getAllGuildStickers(): Map<string, Sticker[]>;
getStickerById(id: string): Sticker | undefined; getStickerById(id: string): Sticker | undefined;
@ -566,8 +566,8 @@ export default definePlugin({
const gifMatch = child.props.href.match(fakeNitroGifStickerRegex); const gifMatch = child.props.href.match(fakeNitroGifStickerRegex);
if (gifMatch) { if (gifMatch) {
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker // There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
if (StickerStore.getStickerById(gifMatch[1])) return null; if (StickersStore.getStickerById(gifMatch[1])) return null;
} }
} }
@ -655,7 +655,7 @@ export default definePlugin({
url = new URL(item); url = new URL(item);
} catch { } } catch { }
const stickerName = StickerStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroSticker"; const stickerName = StickersStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroSticker";
stickers.push({ stickers.push({
format_type: 1, format_type: 1,
id: imgMatch[1], id: imgMatch[1],
@ -668,9 +668,9 @@ export default definePlugin({
const gifMatch = item.match(fakeNitroGifStickerRegex); const gifMatch = item.match(fakeNitroGifStickerRegex);
if (gifMatch) { if (gifMatch) {
if (!StickerStore.getStickerById(gifMatch[1])) continue; if (!StickersStore.getStickerById(gifMatch[1])) continue;
const stickerName = StickerStore.getStickerById(gifMatch[1])?.name ?? "FakeNitroSticker"; const stickerName = StickersStore.getStickerById(gifMatch[1])?.name ?? "FakeNitroSticker";
stickers.push({ stickers.push({
format_type: 2, format_type: 2,
id: gifMatch[1], id: gifMatch[1],
@ -703,8 +703,8 @@ export default definePlugin({
const gifMatch = embed.url!.match(fakeNitroGifStickerRegex); const gifMatch = embed.url!.match(fakeNitroGifStickerRegex);
if (gifMatch) { if (gifMatch) {
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker // There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
if (StickerStore.getStickerById(gifMatch[1])) return true; if (StickersStore.getStickerById(gifMatch[1])) return true;
} }
} }
@ -721,8 +721,8 @@ export default definePlugin({
const match = attachment.url.match(fakeNitroGifStickerRegex); const match = attachment.url.match(fakeNitroGifStickerRegex);
if (match) { if (match) {
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker // There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
if (StickerStore.getStickerById(match[1])) return false; if (StickersStore.getStickerById(match[1])) return false;
} }
return true; return true;
@ -878,7 +878,7 @@ export default definePlugin({
if (!s.enableStickerBypass) if (!s.enableStickerBypass)
break stickerBypass; break stickerBypass;
const sticker = StickerStore.getStickerById(extra.stickers?.[0]!); const sticker = StickersStore.getStickerById(extra.stickers?.[0]!);
if (!sticker) if (!sticker)
break stickerBypass; break stickerBypass;

View file

@ -21,7 +21,7 @@ import { Link } from "@components/Link";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByProps } from "@webpack"; import { findStore } from "@webpack";
import { ApplicationAssetUtils, FluxDispatcher, Forms } from "@webpack/common"; import { ApplicationAssetUtils, FluxDispatcher, Forms } from "@webpack/common";
interface ActivityAssets { interface ActivityAssets {
@ -86,7 +86,7 @@ const placeholderId = "2a96cbd8b46e442fc41c2b86b821562f";
const logger = new Logger("LastFMRichPresence"); const logger = new Logger("LastFMRichPresence");
const presenceStore = findByProps("getLocalPresence"); const SelfPresenceStore = findStore("SelfPresenceStore");
async function getApplicationAsset(key: string): Promise<string> { async function getApplicationAsset(key: string): Promise<string> {
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0]; return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];
@ -275,7 +275,7 @@ export default definePlugin({
async getActivity(): Promise<Activity | null> { async getActivity(): Promise<Activity | null> {
if (settings.store.hideWithSpotify) { if (settings.store.hideWithSpotify) {
for (const activity of presenceStore.getActivities()) { for (const activity of SelfPresenceStore.getActivities()) {
if (activity.type === ActivityType.LISTENING && activity.application_id !== applicationId) { if (activity.type === ActivityType.LISTENING && activity.application_id !== applicationId) {
// there is already music status because of Spotify or richerCider (probably more) // there is already music status because of Spotify or richerCider (probably more)
return null; return null;

View file

@ -20,11 +20,11 @@ import { addClickListener, removeClickListener } from "@api/MessageEvents";
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 { findByProps } from "@webpack"; import { findByProps, findStore } from "@webpack";
import { FluxDispatcher, PermissionsBits, PermissionStore, UserStore } from "@webpack/common"; import { FluxDispatcher, PermissionsBits, PermissionStore, UserStore } from "@webpack/common";
const MessageActions = findByProps("deleteMessage", "startEditMessage"); const MessageActions = findByProps("deleteMessage", "startEditMessage");
const EditStore = findByProps("isEditing", "isEditingAny"); const EditMessageStore = findStore("EditMessageStore");
let isDeletePressed = false; let isDeletePressed = false;
const keydown = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = true); const keydown = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = true);
@ -74,7 +74,7 @@ export default definePlugin({
if (msg.deleted === true) return; if (msg.deleted === true) return;
if (isMe) { if (isMe) {
if (!settings.store.enableDoubleClickToEdit || EditStore.isEditing(channel.id, msg.id)) return; if (!settings.store.enableDoubleClickToEdit || EditMessageStore.isEditing(channel.id, msg.id)) return;
MessageActions.startEditMessage(channel.id, msg.id, msg.content); MessageActions.startEditMessage(channel.id, msg.id, msg.content);
event.preventDefault(); event.preventDefault();

View file

@ -21,9 +21,9 @@ import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByProps } from "@webpack"; import { findByProps } from "@webpack";
import { Message } from "discord-types/general"; import { RelationshipStore } from "@webpack/common";
const RelationshipStore = findByProps("getRelationships", "isBlocked"); import { Message } from "discord-types/general";
const settings = definePluginSettings({ const settings = definePluginSettings({
ignoreBlockedMessages: { ignoreBlockedMessages: {

View file

@ -19,9 +19,9 @@
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 { findByProps } from "@webpack"; import { findStore } from "@webpack";
const MessageRequestStore = findByProps("getMessageRequestsCount"); const MessageRequestStore = findStore("MessageRequestStore");
const settings = definePluginSettings({ const settings = definePluginSettings({
hideFriendRequestsCount: { hideFriendRequestsCount: {

View file

@ -20,7 +20,7 @@ import { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, Co
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { makeLazy } from "@utils/lazy"; import { makeLazy } from "@utils/lazy";
import definePlugin from "@utils/types"; import definePlugin from "@utils/types";
import { findByProps } from "@webpack"; import { findStore } from "@webpack";
import { DraftType, UploadHandler, UploadManager, UserUtils } from "@webpack/common"; import { DraftType, UploadHandler, UploadManager, UserUtils } from "@webpack/common";
import { applyPalette, GIFEncoder, quantize } from "gifenc"; import { applyPalette, GIFEncoder, quantize } from "gifenc";
@ -35,7 +35,7 @@ const getFrames = makeLazy(() => Promise.all(
)) ))
); );
const UploadStore = findByProps("getUploads"); const UploadAttachmentStore = findStore("UploadAttachmentStore");
function loadImage(source: File | string) { function loadImage(source: File | string) {
const isFile = source instanceof File; const isFile = source instanceof File;
@ -58,7 +58,7 @@ async function resolveImage(options: Argument[], ctx: CommandContext, noServerPf
for (const opt of options) { for (const opt of options) {
switch (opt.name) { switch (opt.name) {
case "image": case "image":
const upload = UploadStore.getUpload(ctx.channel.id, opt.name, DraftType.SlashCommand); const upload = UploadAttachmentStore.getUpload(ctx.channel.id, opt.name, DraftType.SlashCommand);
if (upload) { if (upload) {
if (!upload.isImage) { if (!upload.isImage) {
UploadManager.clearAll(ctx.channel.id, DraftType.SlashCommand); UploadManager.clearAll(ctx.channel.id, DraftType.SlashCommand);

View file

@ -20,15 +20,14 @@ import { addChatBarButton, ChatBarButton, removeChatBarButton } from "@api/ChatB
import { generateId, sendBotMessage } from "@api/Commands"; import { generateId, sendBotMessage } from "@api/Commands";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin, { StartAt } from "@utils/types"; import definePlugin, { StartAt } from "@utils/types";
import { findByProps } from "@webpack"; import { findStore } from "@webpack";
import { DraftStore, DraftType, SelectedChannelStore, UserStore, useStateFromStores } from "@webpack/common"; import { DraftStore, DraftType, SelectedChannelStore, UserStore, useStateFromStores } from "@webpack/common";
import { MessageAttachment } from "discord-types/general"; import { MessageAttachment } from "discord-types/general";
const UploadStore = findByProps("getUploads"); const UploadAttachmentStore = findStore("UploadAttachmentStore");
const getDraft = (channelId: string) => DraftStore.getDraft(channelId, DraftType.ChannelMessage); const getDraft = (channelId: string) => DraftStore.getDraft(channelId, DraftType.ChannelMessage);
const getImageBox = (url: string): Promise<{ width: number, height: number; } | null> => const getImageBox = (url: string): Promise<{ width: number, height: number; } | null> =>
new Promise(res => { new Promise(res => {
const img = new Image(); const img = new Image();
@ -44,7 +43,7 @@ const getImageBox = (url: string): Promise<{ width: number, height: number; } |
const getAttachments = async (channelId: string) => const getAttachments = async (channelId: string) =>
await Promise.all( await Promise.all(
UploadStore.getUploads(channelId, DraftType.ChannelMessage) UploadAttachmentStore.getUploads(channelId, DraftType.ChannelMessage)
.map(async (upload: any) => { .map(async (upload: any) => {
const { isImage, filename, spoiler, item: { file } } = upload; const { isImage, filename, spoiler, item: { file } } = upload;
const url = URL.createObjectURL(file); const url = URL.createObjectURL(file);
@ -79,7 +78,7 @@ const PreviewButton: ChatBarButton = ({ isMainChat, isEmpty, type: { attachments
if (!isMainChat) return null; if (!isMainChat) return null;
const hasAttachments = attachments && UploadStore.getUploads(channelId, DraftType.ChannelMessage).length > 0; const hasAttachments = attachments && UploadAttachmentStore.getUploads(channelId, DraftType.ChannelMessage).length > 0;
const hasContent = !isEmpty && draft?.length > 0; const hasContent = !isEmpty && draft?.length > 0;
if (!hasContent && !hasAttachments) return null; if (!hasContent && !hasAttachments) return null;

View file

@ -20,11 +20,10 @@ import { definePluginSettings, Settings } 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 { findByProps } from "@webpack"; import { findByProps } from "@webpack";
import { ChannelStore, FluxDispatcher as Dispatcher, MessageStore, PermissionsBits, PermissionStore, SelectedChannelStore, UserStore } from "@webpack/common"; import { ChannelStore, FluxDispatcher as Dispatcher, MessageStore, PermissionsBits, PermissionStore, RelationshipStore, SelectedChannelStore, UserStore } from "@webpack/common";
import { Message } from "discord-types/general"; import { Message } from "discord-types/general";
const Kangaroo = findByProps("jumpToMessage"); const Kangaroo = findByProps("jumpToMessage");
const RelationshipStore = findByProps("getRelationships", "isBlocked");
const isMac = navigator.platform.includes("Mac"); // bruh const isMac = navigator.platform.includes("Mac"); // bruh
let replyIdx = -1; let replyIdx = -1;

View file

@ -8,14 +8,12 @@ import { DataStore } from "@api/index";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import { openModal } from "@utils/modal"; import { openModal } from "@utils/modal";
import { findExportedComponent } from "@webpack"; import { findExportedComponent } from "@webpack";
import { showToast, Toasts, UserStore } from "@webpack/common"; import { OAuth2AuthorizeModal, showToast, Toasts, UserStore } from "@webpack/common";
import { ReviewDBAuth } from "./entities"; import { ReviewDBAuth } from "./entities";
const DATA_STORE_KEY = "rdb-auth"; const DATA_STORE_KEY = "rdb-auth";
const OAuth2AuthorizeModal = findExportedComponent("OAuth2AuthorizeModal");
export let Auth: ReviewDBAuth = {}; export let Auth: ReviewDBAuth = {};
export async function initAuth() { export async function initAuth() {

View file

@ -8,10 +8,10 @@ import { DataStore } from "@api/index";
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 { findByCode, findByProps } from "@webpack"; import { findByCode, findStore } from "@webpack";
import { ChannelStore, GuildStore } from "@webpack/common"; import { ChannelStore, GuildStore } from "@webpack/common";
const SummaryStore = findByProps("allSummaries", "findSummary"); const SummaryStore = findStore("SummaryStore");
const createSummaryFromServer = findByCode(".people)),startId:", ".type}"); const createSummaryFromServer = findByCode(".people)),startId:", ".type}");
const settings = definePluginSettings({ const settings = definePluginSettings({

View file

@ -20,8 +20,7 @@ import { proxyLazy } from "@utils/lazy";
import { findByProps, webpackDependantLazy } from "@webpack"; import { findByProps, webpackDependantLazy } from "@webpack";
import { Flux, FluxDispatcher } from "@webpack/common"; import { Flux, FluxDispatcher } from "@webpack/common";
// Avoid circular dependency import { settings } from ".";
const SpotifyControls = proxyLazy(() => require(".")) as typeof import(".");
export interface Track { export interface Track {
id: string; id: string;
@ -91,7 +90,7 @@ export const SpotifyStore = webpackDependantLazy(() => {
public isSettingPosition = false; public isSettingPosition = false;
public openExternal(path: string) { public openExternal(path: string) {
const url = SpotifyControls.settings.store.useSpotifyUris || Vencord.Plugins.isPluginEnabled("OpenInApp") const url = settings.store.useSpotifyUris || Vencord.Plugins.isPluginEnabled("OpenInApp")
? "spotify:" + path.replaceAll("/", (_, idx) => idx === 0 ? "" : ":") ? "spotify:" + path.replaceAll("/", (_, idx) => idx === 0 ? "" : ":")
: "https://open.spotify.com" + path; : "https://open.spotify.com" + path;

View file

@ -19,7 +19,7 @@
import { ApplicationCommandInputType, 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 { findByProps } from "@webpack"; import { findStore } from "@webpack";
import { FluxDispatcher, MessageActions } from "@webpack/common"; import { FluxDispatcher, MessageActions } from "@webpack/common";
interface Album { interface Album {
@ -52,8 +52,8 @@ interface Track {
name: string; name: string;
} }
const Spotify = findByProps("getPlayerState"); const SpotifyStore = findStore("SpotifyStore");
const PendingReplyStore = findByProps("getPendingReply"); const PendingReplyStore = findStore("PendingReplyStore");
function sendMessage(channelId, message) { function sendMessage(channelId, message) {
message = { message = {
@ -84,7 +84,7 @@ export default definePlugin({
inputType: ApplicationCommandInputType.BUILT_IN, inputType: ApplicationCommandInputType.BUILT_IN,
options: [], options: [],
execute: (_, ctx) => { execute: (_, ctx) => {
const track: Track | null = Spotify.getTrack(); const track: Track | null = SpotifyStore.getTrack();
if (track === null) { if (track === null) {
sendBotMessage(ctx.channel.id, { sendBotMessage(ctx.channel.id, {
content: "You're not listening to any music." content: "You're not listening to any music."
@ -103,7 +103,7 @@ export default definePlugin({
inputType: ApplicationCommandInputType.BUILT_IN, inputType: ApplicationCommandInputType.BUILT_IN,
options: [], options: [],
execute: (_, ctx) => { execute: (_, ctx) => {
const track: Track | null = Spotify.getTrack(); const track: Track | null = SpotifyStore.getTrack();
if (track === null) { if (track === null) {
sendBotMessage(ctx.channel.id, { sendBotMessage(ctx.channel.id, {
content: "You're not listening to any music." content: "You're not listening to any music."
@ -121,7 +121,7 @@ export default definePlugin({
inputType: ApplicationCommandInputType.BUILT_IN, inputType: ApplicationCommandInputType.BUILT_IN,
options: [], options: [],
execute: (_, ctx) => { execute: (_, ctx) => {
const track: Track | null = Spotify.getTrack(); const track: Track | null = SpotifyStore.getTrack();
if (track === null) { if (track === null) {
sendBotMessage(ctx.channel.id, { sendBotMessage(ctx.channel.id, {
content: "You're not listening to any music." content: "You're not listening to any music."

View file

@ -24,7 +24,7 @@ import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { wordsToTitle } from "@utils/text"; import { wordsToTitle } from "@utils/text";
import definePlugin, { OptionType, ReporterTestable } from "@utils/types"; import definePlugin, { OptionType, ReporterTestable } from "@utils/types";
import { findByProps } from "@webpack"; import { findStore } from "@webpack";
import { Button, ChannelStore, Forms, GuildMemberStore, SelectedChannelStore, SelectedGuildStore, useMemo, UserStore } from "@webpack/common"; import { Button, ChannelStore, Forms, GuildMemberStore, SelectedChannelStore, SelectedGuildStore, useMemo, UserStore } from "@webpack/common";
interface VoiceState { interface VoiceState {
@ -37,7 +37,7 @@ interface VoiceState {
selfMute: boolean; selfMute: boolean;
} }
const VoiceStateStore = findByProps("getVoiceStatesForChannel", "getCurrentClientVoiceChannelId"); const VoiceStateStore = findStore("VoiceStateStore");
// Mute/Deaf for other people than you is commented out, because otherwise someone can spam it and it will be annoying // Mute/Deaf for other people than you is commented out, because otherwise someone can spam it and it will be annoying
// Filtering out events is not as simple as just dropping duplicates, as otherwise mute, unmute, mute would // Filtering out events is not as simple as just dropping duplicates, as otherwise mute, unmute, mute would

View file

@ -113,7 +113,7 @@ export const filters = {
return filter; return filter;
}, },
byComponentCode: (...code: CodeFilter): FilterFn => { componentByCode: (...code: CodeFilter): FilterFn => {
const byCodeFilter = filters.byCode(...code); const byCodeFilter = filters.byCode(...code);
const filter: FilterFn = m => { const filter: FilterFn = m => {
let inner = m; let inner = m;
@ -129,7 +129,7 @@ export const filters = {
return false; return false;
}; };
filter.$$vencordProps = ["byComponentCode", ...code]; filter.$$vencordProps = ["componentByCode", ...code];
filter.$$vencordIsComponentFilter = true; filter.$$vencordIsComponentFilter = true;
return filter; return filter;
}, },
@ -232,7 +232,7 @@ export function waitFor(filter: FilterFn, callback: ModCallbackFn, { isIndirect
* *
* @param filter A function that takes an export or module exports and returns a boolean * @param filter A function that takes an export or module exports and returns a boolean
* @param parse A function that takes the find result as its first argument and returns something to use as the proxy inner value. Useful if you want to use a value from the find result, instead of all of it. Defaults to the find result itself * @param parse A function that takes the find result as its first argument and returns something to use as the proxy inner value. Useful if you want to use a value from the find result, instead of all of it. Defaults to the find result itself
* @returns A proxy that has the parse function return value as its true value, or the plain parse function return value if it was called immediately. * @returns A proxy that has the parse function return value as its true value, or the plain parse function return value, if it was called immediately.
*/ */
export function find<T = any>(filter: FilterFn, parse: (module: ModuleExports) => ModuleExports = m => m, { isIndirect = false }: { isIndirect?: boolean; } = {}) { export function find<T = any>(filter: FilterFn, parse: (module: ModuleExports) => ModuleExports = m => m, { isIndirect = false }: { isIndirect?: boolean; } = {}) {
if (typeof filter !== "function") if (typeof filter !== "function")
@ -306,7 +306,7 @@ export function findExportedComponent<T extends object = any>(...props: PropsFil
} }
/** /**
* Find the first component in an export that includes all the given code. * Find the first exported component which when its code is stringified includes all the given code.
* *
* @example findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR") * @example findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR")
* @example findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)", ColorPicker => React.memo(ColorPicker)) * @example findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)", ColorPicker => React.memo(ColorPicker))
@ -319,7 +319,7 @@ export function findComponentByCode<T extends object = any>(...code: CodeFilter
const parse = (typeof code.at(-1) === "function" ? code.pop() : m => m) as (component: ModuleExports) => LazyComponentType<T>; const parse = (typeof code.at(-1) === "function" ? code.pop() : m => m) as (component: ModuleExports) => LazyComponentType<T>;
const newCode = code as CodeFilter; const newCode = code as CodeFilter;
const ComponentResult = findComponent<T>(filters.byComponentCode(...newCode), parse, { isIndirect: true }); const ComponentResult = findComponent<T>(filters.componentByCode(...newCode), parse, { isIndirect: true });
if (IS_REPORTER) { if (IS_REPORTER) {
webpackSearchHistory.push(["findComponentByCode", [ComponentResult, ...newCode]]); webpackSearchHistory.push(["findComponentByCode", [ComponentResult, ...newCode]]);
@ -369,7 +369,7 @@ export function findByPropsAndExtract<T = any>(...props: PropsFilter | [...Props
} }
/** /**
* Find the first export that includes all the given code. * Find the first exported function which when stringified includes all the given code.
* *
* @param code A list of code to search each export for * @param code A list of code to search each export for
* @param parse A function that takes the find result as its first argument and returns something. Useful if you want to use a value from the find result, instead of all of it. Defaults to the find result itself * @param parse A function that takes the find result as its first argument and returns something. Useful if you want to use a value from the find result, instead of all of it. Defaults to the find result itself
@ -403,7 +403,7 @@ export function findStore<T = GenericStore>(name: StoreNameFilter) {
} }
/** /**
* Find the module exports of the first module which the factory includes all the given code. * Find the module exports of the first module which the factory when stringified includes all the given code.
* *
* @param code A list of code to search each factory for * @param code A list of code to search each factory for
* @param parse A function that takes the find result as its first argument and returns something. Useful if you want to use a value from the find result, instead of all of it. Defaults to the find result itself * @param parse A function that takes the find result as its first argument and returns something. Useful if you want to use a value from the find result, instead of all of it. Defaults to the find result itself
@ -422,7 +422,7 @@ export function findByFactoryCode<T = any>(...code: CodeFilter | [...CodeFilter,
} }
/** /**
* Find the module exports of the first module which the factory includes all the given code, * Find the module exports of the first module which the factory when stringified includes all the given code,
* then map them into an easily usable object via the specified mappers. * then map them into an easily usable object via the specified mappers.
* *
* IMPORTANT: You can destructure the properties of the returned object at top level as long as the property filter does not return a primitive value export. * IMPORTANT: You can destructure the properties of the returned object at top level as long as the property filter does not return a primitive value export.
@ -465,6 +465,8 @@ export function mapMangledModule<S extends PropertyKey>(code: string | RegExp |
waitFor(factoryFilter, exports => { waitFor(factoryFilter, exports => {
callbackCalled = true; callbackCalled = true;
if (typeof exports !== "object") return;
for (const exportKey in exports) { for (const exportKey in exports) {
const exportValue = exports[exportKey]; const exportValue = exports[exportKey];
if (exportValue == null) continue; if (exportValue == null) continue;
@ -507,7 +509,7 @@ export function mapMangledModule<S extends PropertyKey>(code: string | RegExp |
} }
/** /**
* Find the first module factory that includes all the given code. * Find the first module factory which when stringified includes all the given code.
*/ */
export function findModuleFactory(...code: CodeFilter) { export function findModuleFactory(...code: CodeFilter) {
const filter = filters.byFactoryCode(...code); const filter = filters.byFactoryCode(...code);

View file

@ -120,7 +120,7 @@ export const UserUtils: t.UserUtils = {
export const UploadManager = findByProps("clearAll", "addFile"); export const UploadManager = findByProps("clearAll", "addFile");
export const UploadHandler: t.UploadHandler = { export const UploadHandler: t.UploadHandler = {
promptToUpload: findByCode(".ATTACHMENT_TOO_MANY_ERROR_TITLE,") as (files: File[], channel: Channel, draftType: Number) => void promptToUpload: findByCode(".ATTACHMENT_TOO_MANY_ERROR_TITLE,")
}; };
export const ApplicationAssetUtils = findByProps<t.ApplicationAssetUtils>("fetchAssetIds", "getAssetImage"); export const ApplicationAssetUtils = findByProps<t.ApplicationAssetUtils>("fetchAssetIds", "getAssetImage");

View file

@ -50,7 +50,7 @@ define(Function.prototype, "m", {
// We may also catch Discord bundled libs, React Devtools or other extensions WebpackInstance here. // We may also catch Discord bundled libs, React Devtools or other extensions WebpackInstance here.
// This ensures we actually got the right ones // This ensures we actually got the right ones
const { stack } = new Error(); const { stack } = new Error();
if (!(stack?.includes("discord.com") || stack?.includes("discordapp.com")) || (stack != null ? /at \d+? \(/.test(stack) : true) || !String(this).includes("exports:{}")) { if (!stack?.includes("/assets/") || stack?.match(/at \d+? \(/) || !String(this).includes("exports:{}")) {
return; return;
} }
@ -68,7 +68,7 @@ define(Function.prototype, "m", {
define(this, "p", { value: bundlePath }); define(this, "p", { value: bundlePath });
clearTimeout(setterTimeout); clearTimeout(setterTimeout);
if (window.GLOBAL_ENV?.PUBLIC_PATH != null && bundlePath !== window.GLOBAL_ENV.PUBLIC_PATH) return; if (bundlePath !== "/assets/") return;
logger.info("Main Webpack found" + interpolateIfDefined` in ${fileName}` + ", initializing internal references to WebpackRequire"); logger.info("Main Webpack found" + interpolateIfDefined` in ${fileName}` + ", initializing internal references to WebpackRequire");
_initWebpack(this); _initWebpack(this);
@ -117,7 +117,7 @@ const moduleFactoriesHandler: ProxyHandler<AnyWebpackRequire["m"]> = {
// Same thing as get // Same thing as get
has: (target, p) => { has: (target, p) => {
return false; return false;
} },
*/ */
// The set trap for patching or defining getters for the module factories when new module factories are loaded // The set trap for patching or defining getters for the module factories when new module factories are loaded
@ -207,12 +207,12 @@ function defineModulesFactoryGetter(id: PropertyKey, factory: WrappedModuleFacto
return (factory = wrapAndPatchFactory(id, factory)); return (factory = wrapAndPatchFactory(id, factory));
}, },
set(v: AnyModuleFactory) { set(newFactory: AnyModuleFactory) {
if (factory.$$vencordOriginal != null) { if (factory.$$vencordOriginal != null) {
factory.toString = v.toString.bind(v); factory.toString = newFactory.toString.bind(v);
factory.$$vencordOriginal = v; factory.$$vencordOriginal = newFactory;
} else { } else {
factory = v; factory = newFactory;
} }
} }
}); });
@ -229,141 +229,139 @@ function defineModulesFactoryGetter(id: PropertyKey, factory: WrappedModuleFacto
function wrapAndPatchFactory(id: PropertyKey, originalFactory: AnyModuleFactory) { function wrapAndPatchFactory(id: PropertyKey, originalFactory: AnyModuleFactory) {
const patchedFactory = patchFactory(id, originalFactory); const patchedFactory = patchFactory(id, originalFactory);
// The patched factory wrapper, define it in an object to preserve the name after minification const wrappedFactory: WrappedModuleFactory = function (...args) {
const wrappedFactory: WrappedModuleFactory = { // Restore the original factory in all the module factories objects. We want to make sure the original factory is restored properly, no matter what is the Webpack instance
PatchedFactory(...args: Parameters<AnyModuleFactory>) { for (const wreq of allWebpackInstances) {
// Restore the original factory in all the module factories objects. We want to make sure the original factory is restored properly, no matter what is the Webpack instance define(wreq.m, id, { value: wrappedFactory.$$vencordOriginal });
for (const wreq of allWebpackInstances) { }
define(wreq.m, id, { value: wrappedFactory.$$vencordOriginal });
}
// eslint-disable-next-line prefer-const // eslint-disable-next-line prefer-const
let [module, exports, require] = args; let [module, exports, require] = args;
if (wreq == null) { if (wreq == null) {
if (!wreqFallbackApplied) { if (!wreqFallbackApplied) {
wreqFallbackApplied = true; wreqFallbackApplied = true;
// Make sure the require argument is actually the WebpackRequire function // Make sure the require argument is actually the WebpackRequire function
if (typeof require === "function" && require.m != null) { if (typeof require === "function" && require.m != null) {
const { stack } = new Error(); const { stack } = new Error();
const webpackInstanceFileName = stack?.match(/\/assets\/(.+?\.js)/)?.[1]; const webpackInstanceFileName = stack?.match(/\/assets\/(.+?\.js)/)?.[1];
logger.warn(
"WebpackRequire was not initialized, falling back to WebpackRequire passed to the first called patched module factory (" +
`id: ${String(id)}` + interpolateIfDefined`, WebpackInstance origin: ${webpackInstanceFileName}` +
")"
);
_initWebpack(require as WebpackRequire);
} else if (IS_DEV) {
logger.error("WebpackRequire was not initialized, running modules without patches instead.");
}
}
if (IS_DEV) { logger.warn(
"WebpackRequire was not initialized, falling back to WebpackRequire passed to the first called patched module factory (" +
`id: ${String(id)}` + interpolateIfDefined`, WebpackInstance origin: ${webpackInstanceFileName}` +
")"
);
_initWebpack(require as WebpackRequire);
} else if (IS_DEV) {
logger.error("WebpackRequire was not initialized, running modules without patches instead.");
return wrappedFactory.$$vencordOriginal!.apply(this, args); return wrappedFactory.$$vencordOriginal!.apply(this, args);
} }
} } else if (IS_DEV) {
let factoryReturn: unknown;
try {
// Call the patched factory
factoryReturn = patchedFactory.apply(this, args);
} catch (err) {
// Just re-throw Discord errors
if (patchedFactory === originalFactory) {
throw err;
}
logger.error("Error in patched module factory:\n", err);
return wrappedFactory.$$vencordOriginal!.apply(this, args); return wrappedFactory.$$vencordOriginal!.apply(this, args);
} }
}
exports = module.exports; let factoryReturn: unknown;
if (exports == null) return; try {
// Call the patched factory
factoryReturn = patchedFactory.apply(this, args);
} catch (err) {
// Just re-throw Discord errors
if (patchedFactory === originalFactory) {
throw err;
}
// There are (at the time of writing) 11 modules exporting the window logger.error("Error in patched module factory:\n", err);
// Make these non enumerable to improve webpack search performance return wrappedFactory.$$vencordOriginal!.apply(this, args);
if (typeof require === "function" && require.c != null) { }
let foundWindow = false;
if (exports === window) { exports = module.exports;
if (exports == null) return;
// There are (at the time of writing) 11 modules exporting the window
// Make these non enumerable to improve webpack search performance
if (typeof require === "function" && require.c != null) {
let foundWindow = false;
if (exports === window) {
foundWindow = true;
} else if (typeof exports === "object") {
if (exports.default === window) {
foundWindow = true; foundWindow = true;
} else if (typeof exports === "object") { } else {
if (exports.default === window) { for (const exportKey in exports) if (exportKey.length <= 3) {
foundWindow = true; if (exports[exportKey] === window) {
} else { foundWindow = true;
for (const exportKey in exports) if (exportKey.length <= 3) {
if (exports[exportKey] === window) {
foundWindow = true;
}
} }
} }
} }
if (foundWindow) {
Object.defineProperty(require.c, id, {
value: require.c[id],
enumerable: false,
configurable: true,
writable: true
});
return factoryReturn;
}
} }
for (const callback of moduleListeners) { if (foundWindow) {
try { Object.defineProperty(require.c, id, {
callback(exports, { id, factory: wrappedFactory.$$vencordOriginal! }); value: require.c[id],
} catch (err) { enumerable: false,
logger.error("Error in Webpack module listener:\n", err, callback); configurable: true,
} writable: true
});
return factoryReturn;
} }
}
for (const [filter, callback] of waitForSubscriptions) { for (const callback of moduleListeners) {
try { try {
if (filter.$$vencordIsFactoryFilter) { callback(exports, { id, factory: wrappedFactory.$$vencordOriginal! });
if (filter(wrappedFactory.$$vencordOriginal!)) { } catch (err) {
waitForSubscriptions.delete(filter); logger.error("Error in Webpack module listener:\n", err, callback);
callback(exports, { id, exportKey: null, factory: wrappedFactory.$$vencordOriginal! }); }
} }
continue; for (const [filter, callback] of waitForSubscriptions) {
} try {
if (filter.$$vencordIsFactoryFilter) {
if (filter(exports)) { if (filter(wrappedFactory.$$vencordOriginal!)) {
waitForSubscriptions.delete(filter); waitForSubscriptions.delete(filter);
callback(exports, { id, exportKey: null, factory: wrappedFactory.$$vencordOriginal! }); callback(exports, { id, exportKey: null, factory: wrappedFactory.$$vencordOriginal! });
continue;
} }
if (typeof exports !== "object") { continue;
continue;
}
if (exports.default != null && filter(exports.default)) {
waitForSubscriptions.delete(filter);
callback(exports.default, { id, exportKey: "default", factory: wrappedFactory.$$vencordOriginal! });
continue;
}
for (const exportKey in exports) if (exportKey.length <= 3) {
const exportValue = exports[exportKey];
if (exportValue != null && filter(exportValue)) {
waitForSubscriptions.delete(filter);
callback(exportValue, { id, exportKey, factory: wrappedFactory.$$vencordOriginal! });
break;
}
}
} catch (err) {
logger.error("Error while firing callback for Webpack waitFor subscription:\n", err, filter, callback);
} }
}
return factoryReturn; if (filter(exports)) {
waitForSubscriptions.delete(filter);
callback(exports, { id, exportKey: null, factory: wrappedFactory.$$vencordOriginal! });
continue;
}
if (typeof exports !== "object") {
continue;
}
if (exports.default != null && filter(exports.default)) {
waitForSubscriptions.delete(filter);
callback(exports.default, { id, exportKey: "default", factory: wrappedFactory.$$vencordOriginal! });
continue;
}
for (const exportKey in exports) if (exportKey.length <= 3) {
const exportValue = exports[exportKey];
if (exportValue != null && filter(exportValue)) {
waitForSubscriptions.delete(filter);
callback(exportValue, { id, exportKey, factory: wrappedFactory.$$vencordOriginal! });
break;
}
}
} catch (err) {
logger.error("Error while firing callback for Webpack waitFor subscription:\n", err, filter, callback);
}
} }
}.PatchedFactory;
return factoryReturn;
};
wrappedFactory.toString = originalFactory.toString.bind(originalFactory); wrappedFactory.toString = originalFactory.toString.bind(originalFactory);
wrappedFactory.$$vencordOriginal = originalFactory; wrappedFactory.$$vencordOriginal = originalFactory;