diff --git a/packages/discord-types/src/components.d.ts b/packages/discord-types/src/components.d.ts index 76e03a918..bb26e5ecd 100644 --- a/packages/discord-types/src/components.d.ts +++ b/packages/discord-types/src/components.d.ts @@ -317,14 +317,6 @@ export type Slider = ComponentClass>; -// TODO - type maybe idk probably not that useful other than the constants -export type Flex = ComponentType> & { - Align: Record<"START" | "END" | "CENTER" | "STRETCH" | "BASELINE", string>; - Direction: Record<"VERTICAL" | "HORIZONTAL" | "HORIZONTAL_REVERSE", string>; - Justify: Record<"START" | "END" | "CENTER" | "BETWEEN" | "AROUND", string>; - Wrap: Record<"NO_WRAP" | "WRAP" | "WRAP_REVERSE", string>; -}; - declare enum PopoutAnimation { NONE = "1", TRANSLATE = "2", diff --git a/src/plugins/fakeNitro/index.tsx b/src/plugins/fakeNitro/index.tsx index 8f9127f59..824744c1a 100644 --- a/src/plugins/fakeNitro/index.tsx +++ b/src/plugins/fakeNitro/index.tsx @@ -23,7 +23,7 @@ import { Devs } from "@utils/constants"; import { getCurrentGuild, getEmojiURL } from "@utils/discord"; import { Logger } from "@utils/Logger"; import definePlugin, { OptionType, Patch } from "@utils/types"; -import type { Emoji, Message } from "@vencord/discord-types"; +import type { Emoji, Message, Sticker } from "@vencord/discord-types"; import { StickerFormatType } from "@vencord/discord-types/enums"; import { findByCodeLazy, findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack"; import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, lodash, Parser, PermissionsBits, PermissionStore, StickersStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common"; @@ -702,8 +702,9 @@ export default definePlugin({ } }, - getStickerLink(stickerId: string) { - return `https://media.discordapp.net/stickers/${stickerId}.png?size=${settings.store.stickerSize}`; + getStickerLink({ format_type, id }: Sticker) { + const ext = format_type === StickerFormatType.GIF; + return `https://media.discordapp.net/stickers/${id}.${ext}?size=${settings.store.stickerSize}`; }, async sendAnimatedSticker(stickerLink: string, stickerId: string, channelId: string) { @@ -840,14 +841,7 @@ export default definePlugin({ if (sticker.available !== false && (canUseStickers || sticker.guild_id === guildId)) break stickerBypass; - // [12/12/2023] - // Work around an annoying bug where getStickerLink will return StickerType.GIF, - // but will give us a normal non animated png for no reason - // TODO: Remove this workaround when it's not needed anymore - let link = this.getStickerLink(sticker.id); - if (sticker.format_type === StickerFormatType.GIF && link.includes(".png")) { - link = link.replace(".png", ".gif"); - } + const link = this.getStickerLink(sticker); if (sticker.format_type === StickerFormatType.APNG) { if (!hasAttachmentPerms(channelId)) { diff --git a/src/plugins/noBlockedMessages/index.ts b/src/plugins/noBlockedMessages/index.ts index c8fe022aa..f8153750f 100644 --- a/src/plugins/noBlockedMessages/index.ts +++ b/src/plugins/noBlockedMessages/index.ts @@ -18,7 +18,7 @@ import { definePluginSettings, migratePluginSetting } from "@api/Settings"; import { Devs } from "@utils/constants"; -import { runtimeHashMessageKey, runtimeHashMessageKeyLegacy } from "@utils/intlHash"; +import { runtimeHashMessageKey } from "@utils/intlHash"; import { Logger } from "@utils/Logger"; import definePlugin, { OptionType } from "@utils/types"; import { Message } from "@vencord/discord-types"; @@ -92,7 +92,7 @@ export default definePlugin({ shouldHide(props: MessageDeleteProps): boolean { try { const collapsedReason = props.collapsedReason(); - const is = (key: string) => collapsedReason === i18n.t[runtimeHashMessageKey(key)]() || collapsedReason === i18n.t[runtimeHashMessageKeyLegacy(key)](); + const is = (key: string) => collapsedReason === i18n.t[runtimeHashMessageKey(key)](); return is("BLOCKED_MESSAGE_COUNT") || (settings.store.applyToIgnoredUsers && is("IGNORED_MESSAGE_COUNT")); } catch (e) { diff --git a/src/utils/discord.tsx b/src/utils/discord.tsx index 08c9c3497..1198ef220 100644 --- a/src/utils/discord.tsx +++ b/src/utils/discord.tsx @@ -22,21 +22,19 @@ import { ChannelActionCreators, ChannelStore, ComponentDispatch, Constants, Flux import { Except } from "type-fest"; import { copyToClipboard } from "./clipboard"; -import { runtimeHashMessageKey, runtimeHashMessageKeyLegacy } from "./intlHash"; +import { runtimeHashMessageKey } from "./intlHash"; import { Logger } from "./Logger"; import { MediaModalItem, MediaModalProps, openMediaModal } from "./modal"; const IntlManagerLogger = new Logger("IntlManager"); -// TODO: remove legacy hashing function once Discord ships new one everywhere for a while - /** * Get an internationalized message from a non hashed key * @param key The plain message key * @param values The values to interpolate, if it's a rich message */ export function getIntlMessage(key: string, values?: Record): any { - return getIntlMessageFromHash(runtimeHashMessageKey(key), values, key) || getIntlMessageFromHash(runtimeHashMessageKeyLegacy(key), values, key); + return getIntlMessageFromHash(runtimeHashMessageKey(key), values, key); } /** diff --git a/src/utils/intlHash.ts b/src/utils/intlHash.ts index b66cd4d82..ac80d1368 100644 --- a/src/utils/intlHash.ts +++ b/src/utils/intlHash.ts @@ -50,18 +50,3 @@ export function runtimeHashMessageKey(key: string): string { BASE64_TABLE[((bytes[3] & 0x03) << 4) | (bytes[4] >> 4)], ].join(""); } - -// Old variant for compatibility -// TODO: remove once Discord shipped new one everywhere for a while -export function runtimeHashMessageKeyLegacy(key: string): string { - const hash = h64(key, 0); - const bytes = numberToBytes(hash); - return [ - BASE64_TABLE[bytes[0] >> 2], - BASE64_TABLE[((bytes[0] & 0x03) << 4) | (bytes[1] >> 4)], - BASE64_TABLE[((bytes[1] & 0x0f) << 2) | (bytes[2] >> 6)], - BASE64_TABLE[bytes[2] & 0x3f], - BASE64_TABLE[bytes[3] >> 2], - BASE64_TABLE[((bytes[3] & 0x03) << 4) | (bytes[3] >> 4)], - ].join(""); -} diff --git a/src/utils/patches.ts b/src/utils/patches.ts index c70249019..b212e6241 100644 --- a/src/utils/patches.ts +++ b/src/utils/patches.ts @@ -16,66 +16,35 @@ * along with this program. If not, see . */ -import { runtimeHashMessageKey, runtimeHashMessageKeyLegacy } from "./intlHash"; +import { runtimeHashMessageKey } from "./intlHash"; import { Patch, PatchReplacement, ReplaceFn } from "./types"; -// TODO: remove legacy hashing function once Discord ships new one everywhere for a while - -// @ts-expect-error "RegExp.escape" is very new and not yet in DOM types -const escapeRegex = RegExp.escape || ((s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")); - -function getReplacement(isString: boolean, hashed: string) { - const hasSpecialChars = !Number.isNaN(Number(hashed[0])) || hashed.includes("+") || hashed.includes("/"); - - if (hasSpecialChars) { - return isString - ? `["${hashed}"]` - : String.raw`(?:\["${hashed}"\])`.replaceAll("+", "\\+"); - } - - return isString ? `.${hashed}` : String.raw`(?:\.${hashed})`; -} - -function getCompatReplacement(key: string) { - const hashed = getReplacement(false, runtimeHashMessageKey(key)); - const legacyHashed = getReplacement(false, runtimeHashMessageKeyLegacy(key)); - - return String.raw`(?:${hashed}|${legacyHashed})`; -} - -function canonicalizeMatchCompatString(str: string) { - let result = ""; - let lastIndex = 0; - const re = /#{intl::([\w$+/]*)(?:::(\w+))?}/g; - for (const match of str.matchAll(re)) { - result += escapeRegex(str.slice(lastIndex, match.index)); - result += match[2] === "raw" ? getReplacement(false, match[1]) : getCompatReplacement(match[1]); - lastIndex = (match.index ?? 0) + match[0].length; - } - result += escapeRegex(str.slice(lastIndex)); - return new RegExp(result); -} - -export function canonicalizeMatch(match: T): T extends RegExp ? RegExp : string | RegExp { - if (typeof match === "string") { - return canonicalizeMatchCompatString(match) as any; - } - +export function canonicalizeMatch(match: T): T { let partialCanon = typeof match === "string" ? match : match.source; partialCanon = partialCanon.replaceAll(/#{intl::([\w$+/]*)(?:::(\w+))?}/g, (_, key, modifier) => { - if (modifier === "raw") return getReplacement(false, key); - return getCompatReplacement(key); + const hashed = modifier === "raw" ? key : runtimeHashMessageKey(key); + + const isString = typeof match === "string"; + const hasSpecialChars = !Number.isNaN(Number(hashed[0])) || hashed.includes("+") || hashed.includes("/"); + + if (hasSpecialChars) { + return isString + ? `["${hashed}"]` + : String.raw`(?:\["${hashed}"\])`.replaceAll("+", "\\+"); + } + + return isString ? `.${hashed}` : String.raw`(?:\.${hashed})`; }); if (typeof match === "string") { - return partialCanon as any; + return partialCanon as T; } const canonSource = partialCanon.replaceAll("\\i", String.raw`(?:[A-Za-z_$][\w$]*)`); const canonRegex = new RegExp(canonSource, match.flags); canonRegex.toString = match.toString.bind(match); - return canonRegex as any; + return canonRegex as T; } export function canonicalizeReplace(replace: T, pluginPath: string): T { diff --git a/src/webpack/common/utils.ts b/src/webpack/common/utils.ts index ff4c0b29a..95bb5f267 100644 --- a/src/webpack/common/utils.ts +++ b/src/webpack/common/utils.ts @@ -205,8 +205,7 @@ export const DisplayProfileUtils: t.DisplayProfileUtils = mapMangledModuleLazy(/ export const DateUtils: t.DateUtils = mapMangledModuleLazy("millisecondsInUnit:", { calendarFormat: filters.byCode("sameElse"), dateFormat: filters.byCode('":'), - // TODO: the +? are for compat with the old version - Remove them once no longer needed - isSameDay: filters.byCode(/Math\.abs\(\+?\i-\+?\i\)/), + isSameDay: filters.byCode(/Math\.abs\(\i-\i\)/), diffAsUnits: filters.byCode("days:0", "millisecondsInUnit") }); diff --git a/src/webpack/patchWebpack.ts b/src/webpack/patchWebpack.ts index 2e2a793e6..57751b597 100644 --- a/src/webpack/patchWebpack.ts +++ b/src/webpack/patchWebpack.ts @@ -8,7 +8,6 @@ import { Settings } from "@api/Settings"; import { makeLazy } from "@utils/lazy"; import { Logger } from "@utils/Logger"; import { interpolateIfDefined } from "@utils/misc"; -import { canonicalizeReplacement } from "@utils/patches"; import { Patch, PatchReplacement } from "@utils/types"; import { WebpackRequire } from "@vencord/discord-types/webpack"; @@ -548,11 +547,6 @@ function patchFactory(moduleId: PropertyKey, originalFactory: AnyModuleFactory): continue; } - // TODO: remove once Vesktop has been updated to use addPatch - if (patch.plugin === "Vesktop") { - canonicalizeReplacement(replacement, "VCDP"); - } - const lastCode = code; const lastFactory = originalFactory;