Skip to content

Commit

Permalink
Merge branch 'dev' into patcher-rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
Nuckyz committed Jan 30, 2025
2 parents e3a3789 + 1eff1a0 commit 8cd8334
Show file tree
Hide file tree
Showing 18 changed files with 87 additions and 103 deletions.
1 change: 1 addition & 0 deletions src/plugins/_api/chatButtons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default definePlugin({
{
find: '"sticker")',
replacement: {
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /return\((!)?\i\.\i(?:\|\||&&)(?=\(\i\.isDM.+?(\i)\.push)/,
replace: (m, not, children) => not
? `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),true)&&`
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/_api/messageEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ export default definePlugin({
{
find: ".handleSendMessage,onResize",
replacement: {
// FIXME: Simplify this change once all branches share the same code
// props.chatInputType...then((function(isMessageValid)... var parsedMessage = b.c.parse(channel,... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply);
// Lookbehind: validateMessage)({openWarningPopout:..., type: i.props.chatInputType, content: t, stickers: r, ...}).then((function(isMessageValid)
match: /(\{openWarningPopout:.{0,100}type:this.props.chatInputType.+?\.then\()(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);)(?<=\)\(({.+?})\)\.then.+?)/,
match: /(\{openWarningPopout:.{0,100}type:this.props.chatInputType.+?\.then\((?:async )?)(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);)(?<=\)\(({.+?})\)\.then.+?)/,
// props.chatInputType...then((async function(isMessageValid)... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); if(await Vencord.api...) return { shoudClear:true, shouldRefocus:true };
replace: (_, rest1, rest2, parsedMessage, channel, replyOptions, extra) => "" +
`${rest1}async ${rest2}` +
`${rest1}${rest1.includes("async") ? "" : "async "}${rest2}` +
`if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` +
"return{shouldClear:false,shouldRefocus:true};"
}
Expand Down
1 change: 1 addition & 0 deletions src/plugins/_core/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export default definePlugin({
replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}`
},
{
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /({(?=.+?function (\i).{0,160}(\i)=\i\.useMemo.{0,140}return \i\.useMemo\(\(\)=>\i\(\3).+?(?:function\(\){return |\(\)=>))\2/,
replace: (_, rest, settingsHook) => `${rest}$self.wrapSettingsHook(${settingsHook})`
}
Expand Down
1 change: 1 addition & 0 deletions src/plugins/ctrlEnterSend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export default definePlugin({
{
find: ".selectPreviousCommandOption(",
replacement: {
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /(?<=(\i)\.which(?:!==|===)\i\.\i.ENTER(\|\||&&)).{0,100}(\(0,\i\.\i\)\(\i\)).{0,100}(?=(?:\|\||&&)\(\i\.preventDefault)/,
replace: (_, event, condition, codeblock) => `${condition === "||" ? "!" : ""}$self.shouldSubmit(${event},${codeblock})`
}
Expand Down
1 change: 1 addition & 0 deletions src/plugins/fakeNitro/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ export default definePlugin({
},
{
// Disallow the emoji for premium locked if the intention doesn't allow it
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /(!)?(\i\.\i\.canUseEmojisEverywhere\(\i\))/,
replace: (m, not) => not
? `(${m}&&!${IS_BYPASSEABLE_INTENTION})`
Expand Down
12 changes: 3 additions & 9 deletions src/plugins/ircColors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ import definePlugin, { OptionType } from "@utils/types";
import { useMemo } from "@webpack/common";

// Calculate a CSS color string based on the user ID
function calculateNameColorForUser(id: string) {
function calculateNameColorForUser(id?: string) {
const { lightness } = settings.use(["lightness"]);
const idHash = useMemo(() => h64(id), [id]);
const idHash = useMemo(() => id ? h64(id) : null, [id]);

return `hsl(${idHash % 360n}, 100%, ${lightness}%)`;
return idHash && `hsl(${idHash % 360n}, 100%, ${lightness}%)`;
}

const settings = definePluginSettings({
Expand Down Expand Up @@ -70,16 +70,10 @@ export default definePlugin({

calculateNameColorForMessageContext(context: any) {
const id = context?.message?.author?.id;
if (id == null) {
return null;
}
return calculateNameColorForUser(id);
},
calculateNameColorForListContext(context: any) {
const id = context?.user?.id;
if (id == null) {
return null;
}
return calculateNameColorForUser(id);
}
});
2 changes: 1 addition & 1 deletion src/plugins/messageTags/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export default definePlugin({
settings,

async start() {
// TODO: Remove DataStore tags migration once enough time has passed
// TODO(OptionType.CUSTOM Related): Remove DataStore tags migration once enough time has passed
const oldTags = await DataStore.get<Tag[]>(DATA_KEY);
if (oldTags != null) {
// @ts-ignore
Expand Down
42 changes: 0 additions & 42 deletions src/plugins/noScreensharePreview/index.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/plugins/openInApp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export default definePlugin({
replace: "true"
},
{
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /(!)?\(0,\i\.isDesktop\)\(\)/,
replace: (_, not) => not ? "false" : "true"
}
Expand Down
1 change: 1 addition & 0 deletions src/plugins/permissionFreeWill/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export default definePlugin({
find: "#{intl::ONBOARDING_CHANNEL_THRESHOLD_WARNING}",
replacement: [
{
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /{(?:\i:(?:function\(\){return |\(\)=>)\i}?,?){2}}/,
replace: m => m.replaceAll(canonicalizeMatch(/(function\(\){return |\(\)=>)\i/g), "$1()=>Promise.resolve(true)")
}
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/pinDms/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export function moveChannel(channelId: string, direction: -1 | 1) {
swapElementsInArray(category.channels, a, b);
}

// TODO: Remove DataStore PinnedDms migration once enough time has passed
// TODO(OptionType.CUSTOM Related): Remove DataStore PinnedDms migration once enough time has passed
async function migrateData() {
if (Settings.plugins.PinDMs.dmSectioncollapsed != null) {
settings.store.dmSectionCollapsed = Settings.plugins.PinDMs.dmSectioncollapsed;
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/quickReply/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ function nextReply(isUp: boolean) {
channel,
message,
shouldMention: shouldMention(message),
showMentionToggle: channel.isPrivate() && message.author.id !== meId,
showMentionToggle: !channel.isPrivate() && message.author.id !== meId,
_isQuickReply: true
});
ComponentDispatch.dispatchToLastSubscribed("TEXTAREA_FOCUS");
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/showHiddenChannels/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export default definePlugin({
},
{
// Prevent Discord from trying to connect to hidden voice channels
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /(?=(\|\||&&)\i\.\i\.selectVoiceChannel\((\i)\.id\))/,
replace: (_, condition, channel) => condition === "||"
? `||$self.isHiddenChannel(${channel})`
Expand All @@ -124,6 +125,7 @@ export default definePlugin({
{
find: ".AUDIENCE),{isSubscriptionGated",
replacement: {
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /(!)?(\i)\.isRoleSubscriptionTemplatePreviewChannel\(\)/,
replace: (m, not, channel) => not
? `${m}&&!$self.isHiddenChannel(${channel})`
Expand Down Expand Up @@ -177,6 +179,7 @@ export default definePlugin({
},
// Make voice channels also appear as muted if they are muted
{
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /(?<=\.wrapper:\i\.notInteractive,)(.+?)(if\()?(\i)(?:\)return |\?)(\i\.MUTED)/,
replace: (_, otherClasses, isIf, isMuted, mutedClassExpression) => isIf
? `${isMuted}?${mutedClassExpression}:"",${otherClasses}if(${isMuted})return ""`
Expand All @@ -190,6 +193,7 @@ export default definePlugin({
{
// Make muted channels also appear as unread if hide unreads is false, using the HiddenIconWithMutedStyle and the channel is hidden
predicate: () => settings.store.hideUnreads === false && settings.store.showMode === ShowMode.HiddenIconWithMutedStyle,
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
match: /(?<=\.LOCKED(?:;if\(|:))(?<={channel:(\i).+?)/,
replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&`
},
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/textReplace/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ export default definePlugin({
},

async start() {
// TODO: Remove DataStore rules migrations once enough time has passed
// TODO(OptionType.CUSTOM Related): Remove DataStore rules migrations once enough time has passed
const oldStringRules = await DataStore.get<Rule[]>(STRING_RULES_KEY);
if (oldStringRules != null) {
settings.store.stringRules = oldStringRules;
Expand Down
28 changes: 18 additions & 10 deletions src/plugins/typingIndicator/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,24 @@ function TypingIndicator({ channelId, guildId }: { channelId: string; guildId: s
{props => (
<div className="vc-typing-indicator" {...props}>
{((settings.store.indicatorMode & IndicatorMode.Avatars) === IndicatorMode.Avatars) && (
<UserSummaryItem
users={typingUsersArray.map(id => UserStore.getUser(id))}
guildId={guildId}
renderIcon={false}
max={3}
showDefaultAvatarsForNullUsers
showUserPopout
size={16}
className="vc-typing-indicator-avatars"
/>
<div
onClick={e => {
e.stopPropagation();
e.preventDefault();
}}
onKeyPress={e => e.stopPropagation()}
>
<UserSummaryItem
users={typingUsersArray.map(id => UserStore.getUser(id))}
guildId={guildId}
renderIcon={false}
max={3}
showDefaultAvatarsForNullUsers
showUserPopout
size={16}
className="vc-typing-indicator-avatars"
/>
</div>
)}
{((settings.store.indicatorMode & IndicatorMode.Dots) === IndicatorMode.Dots) && (
<div className="vc-typing-indicator-dots">
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/whoReacted/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function makeRenderMoreUsers(users: User[]) {
};
}

function handleClickAvatar(event: React.MouseEvent<HTMLElement, MouseEvent>) {
function handleClickAvatar(event: React.UIEvent<HTMLElement, Event>) {
event.stopPropagation();
}

Expand Down Expand Up @@ -165,7 +165,7 @@ export default definePlugin({
<div
style={{ marginLeft: "0.5em", transform: "scale(0.9)" }}
>
<div onClick={handleClickAvatar}>
<div onClick={handleClickAvatar} onKeyPress={handleClickAvatar}>
<UserSummaryItem
users={users}
guildId={ChannelStore.getChannel(message.channel_id)?.guild_id}
Expand Down
29 changes: 3 additions & 26 deletions src/webpack/patchWebpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { PatchReplacement } from "@utils/types";

import { traceFunctionWithResults } from "../debug/Tracer";
import { patches } from "../plugins";
import { _initWebpack, AnyModuleFactory, AnyWebpackRequire, factoryListeners, findModuleId, ModuleExports, moduleListeners, waitForSubscriptions, WebpackRequire, WrappedModuleFactory, wreq } from ".";
import { _initWebpack, _shouldIgnoreModule, AnyModuleFactory, AnyWebpackRequire, factoryListeners, findModuleId, ModuleExports, moduleListeners, waitForSubscriptions, WebpackRequire, WrappedModuleFactory, wreq } from ".";

const logger = new Logger("WebpackInterceptor", "#8caaee");

Expand Down Expand Up @@ -327,33 +327,10 @@ function wrapAndPatchFactory(id: PropertyKey, originalFactory: AnyModuleFactory)
exports = module.exports;
if (exports == null) return factoryReturn;

// 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") {
let shouldMakeNonEnumerable = false;

nonEnumerableChecking: {
// There are (at the time of writing) 11 modules exporting the window,
// and also modules exporting DOMTokenList, which breaks webpack finding
// Make these non enumerable to improve search performance and avoid erros
if (exports === window || exports[Symbol.toStringTag] === "DOMTokenList") {
shouldMakeNonEnumerable = true;
break nonEnumerableChecking;
}

if (typeof exports !== "object") {
break nonEnumerableChecking;
}

for (const exportKey in exports) {
if (exports[exportKey] === window || exports[exportKey]?.[Symbol.toStringTag] === "DOMTokenList") {
shouldMakeNonEnumerable = true;
break nonEnumerableChecking;
}
}
}
const shouldIgnoreModule = _shouldIgnoreModule(exports);

if (shouldMakeNonEnumerable) {
if (shouldIgnoreModule) {
if (require.c != null) {
Object.defineProperty(require.c, id, {
value: require.c[id],
Expand Down
52 changes: 44 additions & 8 deletions src/webpack/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,16 @@ export const filters = {
componentByCode: (...code: CodeFilter): FilterFn => {
const filter = filters.byCode(...code);
return m => {
if (filter(m)) return true;
if (!m.$$typeof) return false;
if (m.type)
return m.type.render
? filter(m.type.render) // memo + forwardRef
: filter(m.type); // memo
if (m.render) return filter(m.render); // forwardRef
let inner = m;

while (inner != null) {
if (filter(inner)) return true;
else if (!inner.$$typeof) return false;
else if (inner.type) inner = inner.type; // memos
else if (inner.render) inner = inner.render; // forwardRefs
else return false;
}

return false;
};
}
Expand All @@ -104,6 +107,38 @@ export function _initWebpack(webpackRequire: WebpackRequire) {
});
}

// Credits to Zerebos for implementing this in BD, thus giving the idea for us to implement it too
const TypedArray = Object.getPrototypeOf(Int8Array);

function _shouldIgnoreValue(value: any) {
if (value == null) return true;
if (value === window) return true;
if (value === document || value === document.documentElement) return true;
if (value[Symbol.toStringTag] === "DOMTokenList") return true;
if (value instanceof TypedArray) return true;

return false;
}

export function _shouldIgnoreModule(exports: any) {
if (_shouldIgnoreValue(exports)) {
return true;
}

if (typeof exports !== "object") {
return false;
}

let allNonEnumerable = true;
for (const exportKey in exports) {
if (!_shouldIgnoreValue(exports[exportKey])) {
allNonEnumerable = false;
}
}

return allNonEnumerable;
}

let devToolsOpen = false;
if (IS_DEV && IS_DISCORD_DESKTOP) {
// At this point in time, DiscordNative has not been exposed yet, so setImmediate is needed
Expand Down Expand Up @@ -164,7 +199,8 @@ export function findAll(filter: FilterFn) {

if (filter(mod.exports))
ret.push(mod.exports);
else if (typeof mod.exports !== "object")

if (typeof mod.exports !== "object")
continue;

for (const nestedMod in mod.exports) {
Expand Down

0 comments on commit 8cd8334

Please sign in to comment.