🧹🧹🧹

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;
for (const innerMap in result) {
if (result[innerMap][SYM_PROXY_INNER_GET] != null && result[innerMap][SYM_PROXY_INNER_VALUE] == null) {
throw new Error("Webpack Find Fail");
} else if (result[innerMap][SYM_LAZY_COMPONENT_INNER] != null && result[innerMap][SYM_LAZY_COMPONENT_INNER]() == null) {
if (
(result[innerMap][SYM_PROXY_INNER_GET] != null && result[innerMap][SYM_PROXY_INNER_VALUE] == null) ||
(result[innerMap][SYM_LAZY_COMPONENT_INNER] != null && result[innerMap][SYM_LAZY_COMPONENT_INNER]() == null)
) {
throw new Error("Webpack Find Fail");
}
}
break;
}
// This can happen if a `find` was immediately found
@ -125,9 +128,10 @@ async function runReporter() {
if (args[0].$$vencordProps != null) {
if (["find", "findComponent", "waitFor"].includes(searchType)) {
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) {

View file

@ -93,7 +93,7 @@ export default definePlugin({
// 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
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;
}

View file

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

View file

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

View file

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

View file

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

View file

@ -216,7 +216,7 @@ function initWs(isManual = false) {
results = Object.keys(search(parsedArgs[0]));
break;
case "ComponentByCode":
results = cacheFindAll(filters.byComponentCode(...parsedArgs));
results = cacheFindAll(filters.componentByCode(...parsedArgs));
break;
default:
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 type { ReactElement, ReactNode } from "react";
const StickerStore = findStore("StickersStore") as {
const StickersStore = findStore("StickersStore") as {
getPremiumPacks(): StickerPack[];
getAllGuildStickers(): Map<string, Sticker[]>;
getStickerById(id: string): Sticker | undefined;
@ -566,8 +566,8 @@ export default definePlugin({
const gifMatch = child.props.href.match(fakeNitroGifStickerRegex);
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
if (StickerStore.getStickerById(gifMatch[1])) return null;
// 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 (StickersStore.getStickerById(gifMatch[1])) return null;
}
}
@ -655,7 +655,7 @@ export default definePlugin({
url = new URL(item);
} 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({
format_type: 1,
id: imgMatch[1],
@ -668,9 +668,9 @@ export default definePlugin({
const gifMatch = item.match(fakeNitroGifStickerRegex);
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({
format_type: 2,
id: gifMatch[1],
@ -703,8 +703,8 @@ export default definePlugin({
const gifMatch = embed.url!.match(fakeNitroGifStickerRegex);
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
if (StickerStore.getStickerById(gifMatch[1])) return true;
// 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 (StickersStore.getStickerById(gifMatch[1])) return true;
}
}
@ -721,8 +721,8 @@ export default definePlugin({
const match = attachment.url.match(fakeNitroGifStickerRegex);
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
if (StickerStore.getStickerById(match[1])) return false;
// 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 (StickersStore.getStickerById(match[1])) return false;
}
return true;
@ -878,7 +878,7 @@ export default definePlugin({
if (!s.enableStickerBypass)
break stickerBypass;
const sticker = StickerStore.getStickerById(extra.stickers?.[0]!);
const sticker = StickersStore.getStickerById(extra.stickers?.[0]!);
if (!sticker)
break stickerBypass;

View file

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

View file

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

View file

@ -21,9 +21,9 @@ import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
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({
ignoreBlockedMessages: {

View file

@ -19,9 +19,9 @@
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
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({
hideFriendRequestsCount: {

View file

@ -20,7 +20,7 @@ import { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, Co
import { Devs } from "@utils/constants";
import { makeLazy } from "@utils/lazy";
import definePlugin from "@utils/types";
import { findByProps } from "@webpack";
import { findStore } from "@webpack";
import { DraftType, UploadHandler, UploadManager, UserUtils } from "@webpack/common";
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) {
const isFile = source instanceof File;
@ -58,7 +58,7 @@ async function resolveImage(options: Argument[], ctx: CommandContext, noServerPf
for (const opt of options) {
switch (opt.name) {
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.isImage) {
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 { Devs } from "@utils/constants";
import definePlugin, { StartAt } from "@utils/types";
import { findByProps } from "@webpack";
import { findStore } from "@webpack";
import { DraftStore, DraftType, SelectedChannelStore, UserStore, useStateFromStores } from "@webpack/common";
import { MessageAttachment } from "discord-types/general";
const UploadStore = findByProps("getUploads");
const UploadAttachmentStore = findStore("UploadAttachmentStore");
const getDraft = (channelId: string) => DraftStore.getDraft(channelId, DraftType.ChannelMessage);
const getImageBox = (url: string): Promise<{ width: number, height: number; } | null> =>
new Promise(res => {
const img = new Image();
@ -44,7 +43,7 @@ const getImageBox = (url: string): Promise<{ width: number, height: number; } |
const getAttachments = async (channelId: string) =>
await Promise.all(
UploadStore.getUploads(channelId, DraftType.ChannelMessage)
UploadAttachmentStore.getUploads(channelId, DraftType.ChannelMessage)
.map(async (upload: any) => {
const { isImage, filename, spoiler, item: { file } } = upload;
const url = URL.createObjectURL(file);
@ -79,7 +78,7 @@ const PreviewButton: ChatBarButton = ({ isMainChat, isEmpty, type: { attachments
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;
if (!hasContent && !hasAttachments) return null;

View file

@ -20,11 +20,10 @@ import { definePluginSettings, Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
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";
const Kangaroo = findByProps("jumpToMessage");
const RelationshipStore = findByProps("getRelationships", "isBlocked");
const isMac = navigator.platform.includes("Mac"); // bruh
let replyIdx = -1;

View file

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

View file

@ -8,10 +8,10 @@ import { DataStore } from "@api/index";
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByCode, findByProps } from "@webpack";
import { findByCode, findStore } from "@webpack";
import { ChannelStore, GuildStore } from "@webpack/common";
const SummaryStore = findByProps("allSummaries", "findSummary");
const SummaryStore = findStore("SummaryStore");
const createSummaryFromServer = findByCode(".people)),startId:", ".type}");
const settings = definePluginSettings({

View file

@ -20,8 +20,7 @@ import { proxyLazy } from "@utils/lazy";
import { findByProps, webpackDependantLazy } from "@webpack";
import { Flux, FluxDispatcher } from "@webpack/common";
// Avoid circular dependency
const SpotifyControls = proxyLazy(() => require(".")) as typeof import(".");
import { settings } from ".";
export interface Track {
id: string;
@ -91,7 +90,7 @@ export const SpotifyStore = webpackDependantLazy(() => {
public isSettingPosition = false;
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 ? "" : ":")
: "https://open.spotify.com" + path;

View file

@ -19,7 +19,7 @@
import { ApplicationCommandInputType, sendBotMessage } from "@api/Commands";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByProps } from "@webpack";
import { findStore } from "@webpack";
import { FluxDispatcher, MessageActions } from "@webpack/common";
interface Album {
@ -52,8 +52,8 @@ interface Track {
name: string;
}
const Spotify = findByProps("getPlayerState");
const PendingReplyStore = findByProps("getPendingReply");
const SpotifyStore = findStore("SpotifyStore");
const PendingReplyStore = findStore("PendingReplyStore");
function sendMessage(channelId, message) {
message = {
@ -84,7 +84,7 @@ export default definePlugin({
inputType: ApplicationCommandInputType.BUILT_IN,
options: [],
execute: (_, ctx) => {
const track: Track | null = Spotify.getTrack();
const track: Track | null = SpotifyStore.getTrack();
if (track === null) {
sendBotMessage(ctx.channel.id, {
content: "You're not listening to any music."
@ -103,7 +103,7 @@ export default definePlugin({
inputType: ApplicationCommandInputType.BUILT_IN,
options: [],
execute: (_, ctx) => {
const track: Track | null = Spotify.getTrack();
const track: Track | null = SpotifyStore.getTrack();
if (track === null) {
sendBotMessage(ctx.channel.id, {
content: "You're not listening to any music."
@ -121,7 +121,7 @@ export default definePlugin({
inputType: ApplicationCommandInputType.BUILT_IN,
options: [],
execute: (_, ctx) => {
const track: Track | null = Spotify.getTrack();
const track: Track | null = SpotifyStore.getTrack();
if (track === null) {
sendBotMessage(ctx.channel.id, {
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 { wordsToTitle } from "@utils/text";
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";
interface VoiceState {
@ -37,7 +37,7 @@ interface VoiceState {
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
// 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;
},
byComponentCode: (...code: CodeFilter): FilterFn => {
componentByCode: (...code: CodeFilter): FilterFn => {
const byCodeFilter = filters.byCode(...code);
const filter: FilterFn = m => {
let inner = m;
@ -129,7 +129,7 @@ export const filters = {
return false;
};
filter.$$vencordProps = ["byComponentCode", ...code];
filter.$$vencordProps = ["componentByCode", ...code];
filter.$$vencordIsComponentFilter = true;
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 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; } = {}) {
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", ".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 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) {
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 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 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.
*
* 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 => {
callbackCalled = true;
if (typeof exports !== "object") return;
for (const exportKey in exports) {
const exportValue = exports[exportKey];
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) {
const filter = filters.byFactoryCode(...code);

View file

@ -120,7 +120,7 @@ export const UserUtils: t.UserUtils = {
export const UploadManager = findByProps("clearAll", "addFile");
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");

View file

@ -50,7 +50,7 @@ define(Function.prototype, "m", {
// We may also catch Discord bundled libs, React Devtools or other extensions WebpackInstance here.
// This ensures we actually got the right ones
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;
}
@ -68,7 +68,7 @@ define(Function.prototype, "m", {
define(this, "p", { value: bundlePath });
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");
_initWebpack(this);
@ -117,7 +117,7 @@ const moduleFactoriesHandler: ProxyHandler<AnyWebpackRequire["m"]> = {
// Same thing as get
has: (target, p) => {
return false;
}
},
*/
// 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));
},
set(v: AnyModuleFactory) {
set(newFactory: AnyModuleFactory) {
if (factory.$$vencordOriginal != null) {
factory.toString = v.toString.bind(v);
factory.$$vencordOriginal = v;
factory.toString = newFactory.toString.bind(v);
factory.$$vencordOriginal = newFactory;
} else {
factory = v;
factory = newFactory;
}
}
});
@ -229,141 +229,139 @@ function defineModulesFactoryGetter(id: PropertyKey, factory: WrappedModuleFacto
function wrapAndPatchFactory(id: PropertyKey, originalFactory: AnyModuleFactory) {
const patchedFactory = patchFactory(id, originalFactory);
// The patched factory wrapper, define it in an object to preserve the name after minification
const wrappedFactory: WrappedModuleFactory = {
PatchedFactory(...args: Parameters<AnyModuleFactory>) {
// 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
for (const wreq of allWebpackInstances) {
define(wreq.m, id, { value: wrappedFactory.$$vencordOriginal });
}
const wrappedFactory: WrappedModuleFactory = function (...args) {
// 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
for (const wreq of allWebpackInstances) {
define(wreq.m, id, { value: wrappedFactory.$$vencordOriginal });
}
// eslint-disable-next-line prefer-const
let [module, exports, require] = args;
// eslint-disable-next-line prefer-const
let [module, exports, require] = args;
if (wreq == null) {
if (!wreqFallbackApplied) {
wreqFallbackApplied = true;
if (wreq == null) {
if (!wreqFallbackApplied) {
wreqFallbackApplied = true;
// Make sure the require argument is actually the WebpackRequire function
if (typeof require === "function" && require.m != null) {
const { stack } = new Error();
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.");
}
}
// Make sure the require argument is actually the WebpackRequire function
if (typeof require === "function" && require.m != null) {
const { stack } = new Error();
const webpackInstanceFileName = stack?.match(/\/assets\/(.+?\.js)/)?.[1];
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);
}
}
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);
} else if (IS_DEV) {
return wrappedFactory.$$vencordOriginal!.apply(this, args);
}
}
exports = module.exports;
if (exports == null) return;
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;
}
// 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;
logger.error("Error in patched module factory:\n", err);
return wrappedFactory.$$vencordOriginal!.apply(this, args);
}
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;
} else if (typeof exports === "object") {
if (exports.default === window) {
foundWindow = true;
} else {
for (const exportKey in exports) if (exportKey.length <= 3) {
if (exports[exportKey] === window) {
foundWindow = true;
}
} else {
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) {
try {
callback(exports, { id, factory: wrappedFactory.$$vencordOriginal! });
} catch (err) {
logger.error("Error in Webpack module listener:\n", err, callback);
}
if (foundWindow) {
Object.defineProperty(require.c, id, {
value: require.c[id],
enumerable: false,
configurable: true,
writable: true
});
return factoryReturn;
}
}
for (const [filter, callback] of waitForSubscriptions) {
try {
if (filter.$$vencordIsFactoryFilter) {
if (filter(wrappedFactory.$$vencordOriginal!)) {
waitForSubscriptions.delete(filter);
callback(exports, { id, exportKey: null, factory: wrappedFactory.$$vencordOriginal! });
}
for (const callback of moduleListeners) {
try {
callback(exports, { id, factory: wrappedFactory.$$vencordOriginal! });
} catch (err) {
logger.error("Error in Webpack module listener:\n", err, callback);
}
}
continue;
}
if (filter(exports)) {
for (const [filter, callback] of waitForSubscriptions) {
try {
if (filter.$$vencordIsFactoryFilter) {
if (filter(wrappedFactory.$$vencordOriginal!)) {
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);
continue;
}
}
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.$$vencordOriginal = originalFactory;