Fix canary crashing (#1833)
This commit is contained in:
parent
4a2def03e7
commit
1a1d9b07e8
@ -63,26 +63,26 @@ export default definePlugin({
|
|||||||
replacement: {
|
replacement: {
|
||||||
get match() {
|
get match() {
|
||||||
switch (Settings.plugins.Settings.settingsLocation) {
|
switch (Settings.plugins.Settings.settingsLocation) {
|
||||||
case "top": return /\{section:(\i)\.ID\.HEADER,\s*label:(\i)\.\i\.Messages\.USER_SETTINGS\}/;
|
case "top": return /\{section:(\i\.\i)\.HEADER,\s*label:(\i)\.\i\.Messages\.USER_SETTINGS\}/;
|
||||||
case "aboveNitro": return /\{section:(\i)\.ID\.HEADER,\s*label:(\i)\.\i\.Messages\.BILLING_SETTINGS\}/;
|
case "aboveNitro": return /\{section:(\i\.\i)\.HEADER,\s*label:(\i)\.\i\.Messages\.BILLING_SETTINGS\}/;
|
||||||
case "belowNitro": return /\{section:(\i)\.ID\.HEADER,\s*label:(\i)\.\i\.Messages\.APP_SETTINGS\}/;
|
case "belowNitro": return /\{section:(\i\.\i)\.HEADER,\s*label:(\i)\.\i\.Messages\.APP_SETTINGS\}/;
|
||||||
case "belowActivity": return /(?<=\{section:(\i)\.ID\.DIVIDER},)\{section:"changelog"/;
|
case "belowActivity": return /(?<=\{section:(\i\.\i)\.DIVIDER},)\{section:"changelog"/;
|
||||||
case "bottom": return /\{section:(\i)\.ID\.CUSTOM,\s*element:.+?}/;
|
case "bottom": return /\{section:(\i\.\i)\.CUSTOM,\s*element:.+?}/;
|
||||||
case "aboveActivity":
|
case "aboveActivity":
|
||||||
default:
|
default:
|
||||||
return /\{section:(\i)\.ID\.HEADER,\s*label:(\i)\.\i\.Messages\.ACTIVITY_SETTINGS\}/;
|
return /\{section:(\i\.\i)\.HEADER,\s*label:(\i)\.\i\.Messages\.ACTIVITY_SETTINGS\}/;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
replace: "...$self.makeSettingsCategories($1),$&"
|
replace: "...$self.makeSettingsCategories($1),$&"
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
|
||||||
customSections: [] as ((ID: Record<string, unknown>) => any)[],
|
customSections: [] as ((SectionTypes: Record<string, unknown>) => any)[],
|
||||||
|
|
||||||
makeSettingsCategories({ ID }: { ID: Record<string, unknown>; }) {
|
makeSettingsCategories(SectionTypes: Record<string, unknown>) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
section: ID.HEADER,
|
section: SectionTypes.HEADER,
|
||||||
label: "Vencord",
|
label: "Vencord",
|
||||||
className: "vc-settings-header"
|
className: "vc-settings-header"
|
||||||
},
|
},
|
||||||
@ -128,9 +128,9 @@ export default definePlugin({
|
|||||||
element: require("@components/VencordSettings/PatchHelperTab").default,
|
element: require("@components/VencordSettings/PatchHelperTab").default,
|
||||||
className: "vc-patch-helper"
|
className: "vc-patch-helper"
|
||||||
},
|
},
|
||||||
...this.customSections.map(func => func(ID)),
|
...this.customSections.map(func => func(SectionTypes)),
|
||||||
{
|
{
|
||||||
section: ID.DIVIDER
|
section: SectionTypes.DIVIDER
|
||||||
}
|
}
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
},
|
},
|
||||||
|
@ -360,7 +360,7 @@ export default definePlugin({
|
|||||||
{
|
{
|
||||||
// Render editHistory in the deepest div for message content
|
// Render editHistory in the deepest div for message content
|
||||||
match: /(\)\("div",\{id:.+?children:\[)/,
|
match: /(\)\("div",\{id:.+?children:\[)/,
|
||||||
replace: "$1 (arguments[0].message.editHistory.length > 0 ? arguments[0].message.editHistory.map(edit => $self.renderEdit(edit)) : null), "
|
replace: "$1 (arguments[0].message.editHistory?.length > 0 ? arguments[0].message.editHistory.map(edit => $self.renderEdit(edit)) : null), "
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -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 ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { UserStore } from "@webpack/common";
|
import { UserStore } from "@webpack/common";
|
||||||
@ -39,17 +40,17 @@ function shouldShow(message: Message): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PronounsChatComponentWrapper({ message }: { message: Message; }) {
|
export const PronounsChatComponentWrapper = ErrorBoundary.wrap(({ message }: { message: Message; }) => {
|
||||||
return shouldShow(message)
|
return shouldShow(message)
|
||||||
? <PronounsChatComponent message={message} />
|
? <PronounsChatComponent message={message} />
|
||||||
: null;
|
: null;
|
||||||
}
|
}, { noop: true });
|
||||||
|
|
||||||
export function CompactPronounsChatComponentWrapper({ message }: { message: Message; }) {
|
export const CompactPronounsChatComponentWrapper = ErrorBoundary.wrap(({ message }: { message: Message; }) => {
|
||||||
return shouldShow(message)
|
return shouldShow(message)
|
||||||
? <CompactPronounsChatComponent message={message} />
|
? <CompactPronounsChatComponent message={message} />
|
||||||
: null;
|
: null;
|
||||||
}
|
}, { noop: true });
|
||||||
|
|
||||||
function PronounsChatComponent({ message }: { message: Message; }) {
|
function PronounsChatComponent({ message }: { message: Message; }) {
|
||||||
const [result] = useFormattedPronouns(message.author.id);
|
const [result] = useFormattedPronouns(message.author.id);
|
||||||
@ -63,7 +64,7 @@ function PronounsChatComponent({ message }: { message: Message; }) {
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CompactPronounsChatComponent({ message }: { message: Message; }) {
|
export const CompactPronounsChatComponent = ErrorBoundary.wrap(({ message }: { message: Message; }) => {
|
||||||
const [result] = useFormattedPronouns(message.author.id);
|
const [result] = useFormattedPronouns(message.author.id);
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -73,4 +74,4 @@ export function CompactPronounsChatComponent({ message }: { message: Message; })
|
|||||||
>• {result}</span>
|
>• {result}</span>
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
}
|
}, { noop: true });
|
||||||
|
@ -41,7 +41,7 @@ export default definePlugin({
|
|||||||
find: "showCommunicationDisabledStyles",
|
find: "showCommunicationDisabledStyles",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /("span",{id:\i,className:\i,children:\i}\))/,
|
match: /("span",{id:\i,className:\i,children:\i}\))/,
|
||||||
replace: "$1, $self.CompactPronounsChatComponentWrapper(e)"
|
replace: "$1, $self.CompactPronounsChatComponentWrapper(arguments[0])"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Patch the chat timestamp element (normal mode)
|
// Patch the chat timestamp element (normal mode)
|
||||||
@ -49,7 +49,7 @@ export default definePlugin({
|
|||||||
find: "showCommunicationDisabledStyles",
|
find: "showCommunicationDisabledStyles",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=return\s*\(0,\i\.jsxs?\)\(.+!\i&&)(\(0,\i.jsxs?\)\(.+?\{.+?\}\))/,
|
match: /(?<=return\s*\(0,\i\.jsxs?\)\(.+!\i&&)(\(0,\i.jsxs?\)\(.+?\{.+?\}\))/,
|
||||||
replace: "[$1, $self.PronounsChatComponentWrapper(e)]"
|
replace: "[$1, $self.PronounsChatComponentWrapper(arguments[0])]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Patch the profile popout username header to use our pronoun hook instead of Discord's pronouns
|
// Patch the profile popout username header to use our pronoun hook instead of Discord's pronouns
|
||||||
|
@ -16,7 +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 { filters, findByCode, mapMangledModuleLazy } from "@webpack";
|
import { filters, findByCode, findByPropsLazy, mapMangledModuleLazy } from "@webpack";
|
||||||
import type { ComponentType, PropsWithChildren, ReactNode, Ref } from "react";
|
import type { ComponentType, PropsWithChildren, ReactNode, Ref } from "react";
|
||||||
|
|
||||||
import { LazyComponent } from "./react";
|
import { LazyComponent } from "./react";
|
||||||
@ -132,12 +132,7 @@ export const ModalContent = LazyComponent(() => Modals.ModalContent);
|
|||||||
export const ModalFooter = LazyComponent(() => Modals.ModalFooter);
|
export const ModalFooter = LazyComponent(() => Modals.ModalFooter);
|
||||||
export const ModalCloseButton = LazyComponent(() => Modals.ModalCloseButton);
|
export const ModalCloseButton = LazyComponent(() => Modals.ModalCloseButton);
|
||||||
|
|
||||||
const ModalAPI = mapMangledModuleLazy("onCloseRequest:null!=", {
|
const ModalAPI = findByPropsLazy("openModalLazy");
|
||||||
openModal: filters.byCode("onCloseRequest:null!="),
|
|
||||||
closeModal: filters.byCode("onCloseCallback&&"),
|
|
||||||
openModalLazy: m => m?.length === 1 && filters.byCode(".apply(this,arguments)")(m),
|
|
||||||
closeAllModals: filters.byCode(".value.key,")
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for the render promise to resolve, then open a modal with it.
|
* Wait for the render promise to resolve, then open a modal with it.
|
||||||
|
@ -16,10 +16,11 @@
|
|||||||
* 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 { proxyLazy } from "@utils/lazy";
|
||||||
import type * as Stores from "discord-types/stores";
|
import type * as Stores from "discord-types/stores";
|
||||||
|
|
||||||
// eslint-disable-next-line path-alias/no-relative
|
// eslint-disable-next-line path-alias/no-relative
|
||||||
import { filters, findByCodeLazy, findByPropsLazy, mapMangledModuleLazy } from "../webpack";
|
import { filters, findByCode, findByProps, findByPropsLazy, mapMangledModuleLazy } from "../webpack";
|
||||||
import { waitForStore } from "./internal";
|
import { waitForStore } from "./internal";
|
||||||
import * as t from "./types/stores";
|
import * as t from "./types/stores";
|
||||||
|
|
||||||
@ -83,7 +84,14 @@ export const useStateFromStores: <T>(
|
|||||||
idk?: any,
|
idk?: any,
|
||||||
isEqual?: (old: T, newer: T) => boolean
|
isEqual?: (old: T, newer: T) => boolean
|
||||||
) => T
|
) => T
|
||||||
= findByCodeLazy("useStateFromStores");
|
// FIXME: hack to support old stable and new canary
|
||||||
|
= proxyLazy(() => {
|
||||||
|
try {
|
||||||
|
return findByProps("useStateFromStores").useStateFromStores;
|
||||||
|
} catch {
|
||||||
|
return findByCode('("useStateFromStores")');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
waitForStore("DraftStore", s => DraftStore = s);
|
waitForStore("DraftStore", s => DraftStore = s);
|
||||||
waitForStore("UserStore", s => UserStore = s);
|
waitForStore("UserStore", s => UserStore = s);
|
||||||
|
@ -16,10 +16,11 @@
|
|||||||
* 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 { proxyLazy } from "@utils/lazy";
|
||||||
import type { User } from "discord-types/general";
|
import type { User } from "discord-types/general";
|
||||||
|
|
||||||
// eslint-disable-next-line path-alias/no-relative
|
// eslint-disable-next-line path-alias/no-relative
|
||||||
import { _resolveReady, filters, findByCodeLazy, findByPropsLazy, findLazy, mapMangledModuleLazy, waitFor } from "../webpack";
|
import { _resolveReady, filters, find, findByCodeLazy, findByPropsLazy, findLazy, mapMangledModuleLazy, waitFor } from "../webpack";
|
||||||
import type * as t from "./types/utils";
|
import type * as t from "./types/utils";
|
||||||
|
|
||||||
export let FluxDispatcher: t.FluxDispatcher;
|
export let FluxDispatcher: t.FluxDispatcher;
|
||||||
@ -126,4 +127,11 @@ waitFor("parseTopic", m => Parser = m);
|
|||||||
export let SettingsRouter: any;
|
export let SettingsRouter: any;
|
||||||
waitFor(["open", "saveAccountChanges"], m => SettingsRouter = m);
|
waitFor(["open", "saveAccountChanges"], m => SettingsRouter = m);
|
||||||
|
|
||||||
export const PermissionsBits: t.PermissionsBits = findLazy(m => typeof m.ADMINISTRATOR === "bigint");
|
// FIXME: hack to support old stable and new canary
|
||||||
|
export const PermissionsBits: t.PermissionsBits = proxyLazy(() => {
|
||||||
|
try {
|
||||||
|
return find(m => m.Permissions?.ADMINISTRATOR).Permissions;
|
||||||
|
} catch {
|
||||||
|
return find(m => typeof m.ADMINISTRATOR === "bigint");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
@ -36,9 +36,8 @@ if (window[WEBPACK_CHUNK]) {
|
|||||||
Object.defineProperty(window, WEBPACK_CHUNK, {
|
Object.defineProperty(window, WEBPACK_CHUNK, {
|
||||||
get: () => webpackChunk,
|
get: () => webpackChunk,
|
||||||
set: v => {
|
set: v => {
|
||||||
if (v?.push !== Array.prototype.push) {
|
if (v?.push !== Array.prototype.push && _initWebpack(v)) {
|
||||||
logger.info(`Patching ${WEBPACK_CHUNK}.push`);
|
logger.info(`Patching ${WEBPACK_CHUNK}.push`);
|
||||||
_initWebpack(v);
|
|
||||||
patchPush();
|
patchPush();
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
delete window[WEBPACK_CHUNK];
|
delete window[WEBPACK_CHUNK];
|
||||||
@ -85,10 +84,9 @@ function patchPush() {
|
|||||||
logger.error("Error in patched chunk", err);
|
logger.error("Error in patched chunk", err);
|
||||||
return void originalMod(module, exports, require);
|
return void originalMod(module, exports, require);
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are (at the time of writing) 11 modules exporting the window
|
// There are (at the time of writing) 11 modules exporting the window
|
||||||
// Make these non enumerable to improve webpack search performance
|
// Make these non enumerable to improve webpack search performance
|
||||||
if (module.exports === window) {
|
if (exports === window) {
|
||||||
Object.defineProperty(require.c, id, {
|
Object.defineProperty(require.c, id, {
|
||||||
value: require.c[id],
|
value: require.c[id],
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
|
@ -62,9 +62,50 @@ export type CallbackFn = (mod: any, id: number) => void;
|
|||||||
export function _initWebpack(instance: typeof window.webpackChunkdiscord_app) {
|
export function _initWebpack(instance: typeof window.webpackChunkdiscord_app) {
|
||||||
if (cache !== void 0) throw "no.";
|
if (cache !== void 0) throw "no.";
|
||||||
|
|
||||||
wreq = instance.push([[Symbol("Vencord")], {}, r => r]);
|
instance.push([[Symbol("Vencord")], {}, r => wreq = r]);
|
||||||
|
if (!wreq) return false;
|
||||||
|
|
||||||
cache = wreq.c;
|
cache = wreq.c;
|
||||||
instance.pop();
|
instance.pop();
|
||||||
|
|
||||||
|
for (const id in cache) {
|
||||||
|
const { exports } = cache[id];
|
||||||
|
if (!exports) continue;
|
||||||
|
|
||||||
|
const numberId = Number(id);
|
||||||
|
|
||||||
|
for (const callback of listeners) {
|
||||||
|
try {
|
||||||
|
callback(exports, numberId);
|
||||||
|
} catch (err) {
|
||||||
|
logger.error("Error in webpack listener", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [filter, callback] of subscriptions) {
|
||||||
|
try {
|
||||||
|
if (filter(exports)) {
|
||||||
|
subscriptions.delete(filter);
|
||||||
|
callback(exports, numberId);
|
||||||
|
} else if (typeof exports === "object") {
|
||||||
|
if (exports.default && filter(exports.default)) {
|
||||||
|
subscriptions.delete(filter);
|
||||||
|
callback(exports.default, numberId);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const nested in exports) if (nested.length <= 3) {
|
||||||
|
if (exports[nested] && filter(exports[nested])) {
|
||||||
|
subscriptions.delete(filter);
|
||||||
|
callback(exports[nested], numberId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
logger.error("Error while firing callback for webpack chunk", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_DEV && IS_DISCORD_DESKTOP) {
|
if (IS_DEV && IS_DISCORD_DESKTOP) {
|
||||||
|
Loading…
Reference in New Issue
Block a user