This commit is contained in:
Ulysia 2025-03-25 17:46:05 +01:00
commit 8085325814
14 changed files with 45 additions and 34 deletions

View file

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

View file

@ -31,6 +31,7 @@ export const commands = {} as Record<string, Command>;
// hack for plugins being evaluated before we can grab these from webpack
const OptPlaceholder = Symbol("OptionalMessageOption") as any as Option;
const ReqPlaceholder = Symbol("RequiredMessageOption") as any as Option;
/**
* Optional message option named "message" you can use in commands.
* Used in "tableflip" or "shrug"
@ -44,11 +45,16 @@ export let OptionalMessageOption: Option = OptPlaceholder;
*/
export let RequiredMessageOption: Option = ReqPlaceholder;
// Discord's command list has random gaps for some reason, which can cause issues while rendering the commands
// Add this offset to every added command to keep them unique
let commandIdOffset: number;
export const _init = function (cmds: Command[]) {
try {
BUILT_IN = cmds;
OptionalMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "shrug")!.options![0];
RequiredMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "me")!.options![0];
commandIdOffset = Math.abs(BUILT_IN.map(x => Number(x.id)).sort((x, y) => x - y)[0]) - BUILT_IN.length;
} catch (e) {
new Logger("CommandsAPI").error("Failed to load CommandsApi", e, " - cmds is", cmds);
}
@ -142,7 +148,7 @@ export function registerCommand<C extends Command>(command: C, plugin: string) {
command.isVencordCommand = true;
command.untranslatedName ??= command.name;
command.untranslatedDescription ??= command.description;
command.id ??= `-${BUILT_IN.length + 1}`;
command.id ??= `-${BUILT_IN.length + commandIdOffset + 1}`;
command.applicationId ??= "-1"; // BUILT_IN;
command.type ??= ApplicationCommandType.CHAT_INPUT;
command.inputType ??= ApplicationCommandInputType.BUILT_IN_TEXT;

View file

@ -101,7 +101,7 @@ if (IS_VESKTOP || !IS_VANILLA) {
// TODO: Restrict this to only imported packages with fixed version.
// Perhaps auto generate with esbuild
csp["script-src"] ??= [];
csp["script-src"].push("'unsafe-eval'", "https://unpkg.com", "https://cdnjs.cloudflare.com");
csp["script-src"].push("'unsafe-eval'", "https://cdn.jsdelivr.net", "https://cdnjs.cloudflare.com");
headers[header] = [stringifyPolicy(csp)];
}
};

View file

@ -73,7 +73,7 @@ export default definePlugin({
find: "#{intl::PROFILE_USER_BADGES}",
replacement: [
{
match: /(alt:" ","aria-hidden":!0,src:)(.{0,20}(\i)\.icon\))/,
match: /(alt:" ","aria-hidden":!0,src:)(.+?)(?=,)(?<=href:(\i)\.link.+?)/,
replace: (_, rest, originalSrc, badge) => `...${badge}.props,${rest}${badge}.image??(${originalSrc})`
},
{

View file

@ -73,8 +73,8 @@ export default definePlugin({
group: true,
replacement: [
{
match: /(?<=\.AVATAR_SIZE\).{0,100};)(?=return)/,
replace: "$self.useAccountPanelRef();"
match: /let{speaking:\i/,
replace: "$self.useAccountPanelRef();$&"
},
{
match: /(\.AVATAR,children:.+?renderPopout:(\i)=>){(.+?)}(?=,position)(?<=currentUser:(\i).+?)/,

View file

@ -44,15 +44,15 @@ export default definePlugin({
find: "#{intl::GUILD_OWNER}),children:",
replacement: {
match: /(\.CUSTOM_STATUS.+?animate:)\i/,
replace: (_, rest) => `${rest}!0`
replace: "$1!0"
}
},
{
// Guild Banner
find: ".animatedBannerHoverLayer,onMouseEnter:",
replacement: {
match: /(?<=guildBanner:\i,animate:)\i(?=}\))/,
replace: "!0"
match: /(\.headerContent.+?guildBanner:\i,animate:)\i/,
replace: "$1!0"
}
}
]

View file

@ -99,7 +99,7 @@ export default definePlugin({
},
// Current user area, at bottom of channels/dm list
{
find: "renderAvatarWithPopout(){",
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
replacement: [
// Use Decor avatar decoration hook
{

View file

@ -260,14 +260,7 @@ export default definePlugin({
replace: (m, props, nowPlaying) => `${m}$self.renderToggleGameActivityButton(${props},${nowPlaying}),`
}
},
// Discord has 2 different components for activities. Currently, the last is the one being used
{
find: ".activityTitleText,variant",
replacement: {
match: /\.activityTitleText.+?children:(\i)\.name.*?}\),/,
replace: (m, props) => `${m}$self.renderToggleActivityButton(${props}),`
},
},
// Activities from the apps launcher in the bottom right of the chat bar
{
find: ".promotedLabelWrapperNonBanner,children",
replacement: {

View file

@ -149,6 +149,12 @@ export default definePlugin({
renderChatBarButton: ChatBarIcon,
colorCodeFromNumber(color: number): string {
return `#${[color >> 16, color >> 8, color]
.map(x => (x & 0xFF).toString(16))
.join("")}`;
},
// Gets the Embed of a Link
async getEmbed(url: URL): Promise<Object | {}> {
const { body } = await RestAPI.post({
@ -157,6 +163,8 @@ export default definePlugin({
urls: [url]
}
});
// The endpoint returns the color as a number, but Discord expects a string
body.embeds[0].color = this.colorCodeFromNumber(body.embeds[0].color);
return await body.embeds[0];
},
@ -166,7 +174,7 @@ export default definePlugin({
message.embeds.push({
type: "rich",
rawTitle: "Decrypted Message",
color: "0x45f5f5",
color: "#45f5f5",
rawDescription: revealed,
footer: {
text: "Made with ❤️ by c0dine and Sammy!",

View file

@ -73,17 +73,21 @@ export default definePlugin({
{
find: "#{intl::GUILD_OWNER}),children:",
replacement: {
match: /(?<=\.MEMBER_LIST}\),\[\]\),)(.+?color:)null!=.{0,50}?(?=,)/,
replace: (_, rest) => `ircColor=$self.calculateNameColorForListContext(arguments[0]),${rest}ircColor`
match: /(typingIndicatorRef:.+?},)(\i=.+?)color:null!=.{0,50}?(?=,)/,
replace: (_, rest1, rest2) => `${rest1}ircColor=$self.calculateNameColorForListContext(arguments[0]),${rest2}color:ircColor`
},
predicate: () => settings.store.memberListColors
}
],
calculateNameColorForMessageContext(context: any) {
const id = context?.message?.author?.id;
const userId: string | undefined = context?.message?.author?.id;
const colorString = context?.author?.colorString;
const color = calculateNameColorForUser(id);
const color = calculateNameColorForUser(userId);
// Color preview in role settings
if (context?.message?.channel_id === "1337" && userId === "313337")
return colorString;
if (settings.store.applyColorOnlyInDms && !context?.channel?.isPrivate()) {
return colorString;

View file

@ -63,11 +63,11 @@ export default definePlugin({
stringDelta(delta: number, showMillis: boolean) {
const diff: Diff = {
days: Math.round(delta / (60 * 60 * 24 * 1000)),
hours: Math.round((delta / (60 * 60 * 1000)) % 24),
minutes: Math.round((delta / (60 * 1000)) % 60),
seconds: Math.round(delta / 1000 % 60),
milliseconds: Math.round(delta % 1000)
days: Math.floor(delta / (60 * 60 * 24 * 1000)),
hours: Math.floor((delta / (60 * 60 * 1000)) % 24),
minutes: Math.floor((delta / (60 * 1000)) % 60),
seconds: Math.floor(delta / 1000 % 60),
milliseconds: Math.floor(delta % 1000)
};
const str = (k: DiffKey) => diff[k] > 0 ? `${diff[k]} ${diff[k] > 1 ? k : k.substring(0, k.length - 1)}` : null;

View file

@ -57,10 +57,10 @@ export default definePlugin({
patches: [
{
find: "#{intl::BLOCKED_MESSAGES_HIDE}",
find: ".__invalid_blocked,",
replacement: [
{
match: /let\{[^}]*collapsedReason[^}]*\}/,
match: /let{expanded:\i,[^}]*?collapsedReason[^}]*}/,
replace: "if($self.shouldHide(arguments[0]))return null;$&"
}
]

View file

@ -136,7 +136,7 @@ export default definePlugin({
// @ts-expect-error
if (data.sinkId != null && data.sinkId !== data.audioContext.sinkId && "setSinkId" in AudioContext.prototype) {
// @ts-expect-error https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/setSinkId
data.audioContext.setSinkId(data.sinkId);
data.audioContext.setSinkId(data.sinkId === "default" ? "" : data.sinkId);
}
data.gainNode.gain.value = data._mute

View file

@ -69,8 +69,8 @@ export interface ApngFrameData {
// The below code is only used on the Desktop (electron) build of Vencord.
// Browser (extension) builds do not contain these remote imports.
export const shikiWorkerSrc = `https://unpkg.com/@vap/shiki-worker@0.0.8/dist/${IS_DEV ? "index.js" : "index.min.js"}`;
export const shikiOnigasmSrc = "https://unpkg.com/@vap/shiki@0.10.3/dist/onig.wasm";
export const shikiWorkerSrc = `https://cdn.jsdelivr.net/npm/@vap/shiki-worker@0.0.8/dist/${IS_DEV ? "index.js" : "index.min.js"}`;
export const shikiOnigasmSrc = "https://cdn.jsdelivr.net/npm/@vap/shiki@0.10.3/dist/onig.wasm";
// @ts-expect-error
export const getStegCloak = /* #__PURE__*/ makeLazy(() => import("https://unpkg.com/stegcloak-dist@1.0.0/index.js"));
export const getStegCloak = /* #__PURE__*/ makeLazy(() => import("https://cdn.jsdelivr.net/npm/stegcloak-dist@1.0.0/index.js"));