chore: init
This commit is contained in:
207
antiRickroll/index.tsx
Normal file
207
antiRickroll/index.tsx
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { addMessageAccessory, removeMessageAccessory } from "@api/MessageAccessories";
|
||||||
|
import { definePluginSettings } from "@api/Settings";
|
||||||
|
import { getUserSettingLazy } from "@api/UserSettings";
|
||||||
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
import { Message } from "@vencord/discord-types";
|
||||||
|
import { React, Text } from "@webpack/common";
|
||||||
|
|
||||||
|
import { knownHosts } from "./knownHosts";
|
||||||
|
import { knownVideoIds } from "./knownVideoIDs";
|
||||||
|
const MessageDisplayCompact = getUserSettingLazy(
|
||||||
|
"textAndImages",
|
||||||
|
"messageDisplayCompact"
|
||||||
|
)!;
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
customLinks: {
|
||||||
|
description: "Custom links to check for (separated by commas)",
|
||||||
|
type: OptionType.STRING,
|
||||||
|
default: "",
|
||||||
|
restartNeeded: true,
|
||||||
|
},
|
||||||
|
customVideoIds: {
|
||||||
|
description:
|
||||||
|
"Custom YouTube video IDs to check for (separated by commas)",
|
||||||
|
type: OptionType.STRING,
|
||||||
|
default: "",
|
||||||
|
restartNeeded: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function isPotentialRickroll(url: string): boolean {
|
||||||
|
try {
|
||||||
|
const parsedUrl = new URL(url);
|
||||||
|
const hostname = parsedUrl.hostname.replace("www.", "");
|
||||||
|
|
||||||
|
const customLinks = settings.store.customLinks
|
||||||
|
.split(",")
|
||||||
|
.map(s => s.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
const customVideoIDs = settings.store.customVideoIds
|
||||||
|
.split(",")
|
||||||
|
.map(s => s.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
if (customLinks.some(link => parsedUrl.href.includes(link))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostname === "youtube.com" || hostname === "youtu.be") {
|
||||||
|
let videoID = "";
|
||||||
|
|
||||||
|
if (hostname === "youtube.com") {
|
||||||
|
videoID =
|
||||||
|
parsedUrl.searchParams.get("v") ||
|
||||||
|
parsedUrl.searchParams.get("V") ||
|
||||||
|
"";
|
||||||
|
} else if (hostname === "youtu.be") {
|
||||||
|
videoID = parsedUrl.pathname.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const knownVideoIDs = [...knownVideoIds, ...customVideoIDs];
|
||||||
|
|
||||||
|
if (knownVideoIDs.includes(videoID)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (knownHosts.includes(hostname)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Invalid URL, ignore :trolley:
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractUrls(content: string): string[] {
|
||||||
|
const urls: string[] = [];
|
||||||
|
const markdownLinkRegex = /\[.*?\]\((<)?(https?:\/\/[^\s>]+)(>)?\)/g;
|
||||||
|
const urlRegex = /https?:\/\/[^\s<]+/g;
|
||||||
|
const maskedUrlRegex = /<(https?:\/\/[^\s>]+)>/g;
|
||||||
|
|
||||||
|
let match: RegExpExecArray | null;
|
||||||
|
|
||||||
|
while ((match = markdownLinkRegex.exec(content)) !== null) {
|
||||||
|
urls.push(match[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((match = urlRegex.exec(content)) !== null) {
|
||||||
|
urls.push(match[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((match = maskedUrlRegex.exec(content)) !== null) {
|
||||||
|
urls.push(match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
function RickrollWarningAccessory({ message }: { message: Message; }) {
|
||||||
|
const urls = extractUrls(message.content);
|
||||||
|
if (urls.length === 0) return null;
|
||||||
|
|
||||||
|
for (const url of urls) {
|
||||||
|
const isCustom = isCustomRickroll(url);
|
||||||
|
if (isPotentialRickroll(url) || isCustom) {
|
||||||
|
return (
|
||||||
|
<ErrorBoundary>
|
||||||
|
<RickrollWarning message={message} isCustom={isCustom} />
|
||||||
|
</ErrorBoundary>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isCustomRickroll(url: string): boolean {
|
||||||
|
try {
|
||||||
|
const parsedUrl = new URL(url);
|
||||||
|
const customLinks = settings.store.customLinks
|
||||||
|
.split(",")
|
||||||
|
.map(s => s.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
const customVideoIDs = settings.store.customVideoIds
|
||||||
|
.split(",")
|
||||||
|
.map(s => s.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
if (customLinks.some(link => parsedUrl.href.includes(link))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hostname = parsedUrl.hostname.replace("www.", "");
|
||||||
|
if (hostname === "youtube.com" || hostname === "youtu.be") {
|
||||||
|
let videoID = "";
|
||||||
|
if (hostname === "youtube.com") {
|
||||||
|
videoID = parsedUrl.searchParams.get("v") || "";
|
||||||
|
} else if (hostname === "youtu.be") {
|
||||||
|
videoID = parsedUrl.pathname.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customVideoIDs.includes(videoID)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Invalid URL, ignore :trolley: (could probably merge this)
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function RickrollWarning({
|
||||||
|
message,
|
||||||
|
isCustom,
|
||||||
|
}: {
|
||||||
|
message: Message;
|
||||||
|
isCustom: boolean;
|
||||||
|
}) {
|
||||||
|
const compact = MessageDisplayCompact.useSetting();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Text color="text-danger" variant="text-xs/semibold">
|
||||||
|
⚠️ This link is{" "}
|
||||||
|
{isCustom
|
||||||
|
? "matching one of your filters for rickrolls."
|
||||||
|
: "a known rickroll."}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "AntiRickroll",
|
||||||
|
description:
|
||||||
|
"Warns you of potential Rickrolls in messages, including masked links (supports custom rules)",
|
||||||
|
authors: [{ name: "ryanamay", id: 1262793452236570667n }],
|
||||||
|
dependencies: ["MessageAccessoriesAPI", "UserSettingsAPI"],
|
||||||
|
|
||||||
|
settings,
|
||||||
|
|
||||||
|
start() {
|
||||||
|
addMessageAccessory(
|
||||||
|
"rickrollWarning",
|
||||||
|
(props: Record<string, any>) => {
|
||||||
|
return (
|
||||||
|
<RickrollWarningAccessory
|
||||||
|
message={props.message as Message}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
4
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
removeMessageAccessory("rickrollWarning");
|
||||||
|
},
|
||||||
|
});
|
||||||
106
antiRickroll/knownHosts.ts
Normal file
106
antiRickroll/knownHosts.ts
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const knownHosts = [
|
||||||
|
"rickroll.link",
|
||||||
|
"rickrolled.fr",
|
||||||
|
"dub.sh/MetropolisOffline",
|
||||||
|
"my-cool-app.com",
|
||||||
|
"1227.com",
|
||||||
|
"203.24.182.170",
|
||||||
|
"74.125.95.104/search?q=cache:YLZLcPVmjrsJ:smouch.net/lol/+rick+roll&hl=en&ct=clnk&cd=5&gl=us",
|
||||||
|
"8chan.henriwatson.com/b",
|
||||||
|
"adurah.com/img/hp7_spoilers.jpg",
|
||||||
|
"ali3ns.net",
|
||||||
|
"almightypickle.deviantart.com/art/a-very-stupid-flash-movie-83440015",
|
||||||
|
"apoke.com",
|
||||||
|
"asongbyagayguy.ytmnd.com",
|
||||||
|
"bit.ly/1628nB",
|
||||||
|
"bringvictory.com",
|
||||||
|
"choose.yudia.net",
|
||||||
|
"classpc.nl",
|
||||||
|
"collegehumor.com/video:1809841",
|
||||||
|
"comicwonder.com/joke/8a46a9b4a",
|
||||||
|
"crappypc.com",
|
||||||
|
"ebaumsworld.com/video/watch/411687",
|
||||||
|
"ecritters.biz/sr",
|
||||||
|
"epicwinrar.com",
|
||||||
|
"evanball.com",
|
||||||
|
"finalclan.net",
|
||||||
|
"freeppcsecrets.com",
|
||||||
|
"fuckdreamhost.com",
|
||||||
|
"furryartpile.com",
|
||||||
|
"i65games.tk",
|
||||||
|
"internetisseriousbusiness.com",
|
||||||
|
"irc.infinitynet.info",
|
||||||
|
"johncow.com/moo.html",
|
||||||
|
"just-different.info/secret",
|
||||||
|
"keiraknightley.ytmnd.com",
|
||||||
|
"krazykustoms.co.cc/pages",
|
||||||
|
"krazykustoms.co.cc/phpBB3/index.php",
|
||||||
|
"liner.org",
|
||||||
|
"members.tele2.nl/class-pc",
|
||||||
|
"mxweas.com/docs/jailbreakservhack",
|
||||||
|
"newroupdates.tk",
|
||||||
|
"niya.cc/flash/rick",
|
||||||
|
"noelurl.easyasweb.eu/u0Rx744fi",
|
||||||
|
"palmsout.net/music/remixsunday/104/Never%20Gonna%20Give%20You%20Up%20%28Solly%20Remix%29.mp3",
|
||||||
|
"paulsmom.prohosts.org",
|
||||||
|
"pottermisleading.ytmnd.com",
|
||||||
|
"prankdialer.com/rickroll.php",
|
||||||
|
"pspemporium.webs.com/rickdance.html",
|
||||||
|
"punahou.com",
|
||||||
|
"rasher.dk/r",
|
||||||
|
"rasher.dk/r/linode-dns",
|
||||||
|
"ravenstorm.byethost15.com",
|
||||||
|
"raygoldmodels.com",
|
||||||
|
"reichroll.com",
|
||||||
|
"reichrolled.com",
|
||||||
|
"rick-rolld.com",
|
||||||
|
"rickroll.net",
|
||||||
|
"rickrolling.com/lol",
|
||||||
|
"rr.rezbit.com",
|
||||||
|
"rr.rezbit.com/blog/021107/rick-astley-speaks-about-rickroll.html",
|
||||||
|
"rurl.org/2vq",
|
||||||
|
"sirpnut.info/sorry.jpg",
|
||||||
|
"smouch.net/lol",
|
||||||
|
"sprigler.com/steven",
|
||||||
|
"stucknut.com/locker/files/jessica.gif",
|
||||||
|
"t1ny.us/7wp5i",
|
||||||
|
"technocolbert.co.nr",
|
||||||
|
"techsmartly.net",
|
||||||
|
"thekickback.com/rickroll/rickroll.php",
|
||||||
|
"tinyurl.com/interfont",
|
||||||
|
"tinyurl.com/244u3n",
|
||||||
|
"tinyurl.com/2nmscj",
|
||||||
|
"tinyurl.com/2tcnbl",
|
||||||
|
"tinyurl.com/2w4apm",
|
||||||
|
"tinyurl.com/37ws8e",
|
||||||
|
"tinyurl.com/4xur8r",
|
||||||
|
"tinyurl.com/5a3jqf",
|
||||||
|
"tinyurl.com/5sb29l",
|
||||||
|
"tinyurl.com/CELEBRITY-XXX-VIDS",
|
||||||
|
"tinyurl.com/KIM-KARDASHIAN-SEX-TAPE",
|
||||||
|
"tinyurl.com/britneyspearsXXX",
|
||||||
|
"tinyurl.com/rickrolll",
|
||||||
|
"tinyurl.com/ynupj4",
|
||||||
|
"tinyurl.com/yowxeq",
|
||||||
|
"tobi-x.com/kate_moss_nude",
|
||||||
|
"todaysbigthing.com/2008/04/07",
|
||||||
|
"todo.is",
|
||||||
|
"url.uppix.net/NFWGJ",
|
||||||
|
"video.hexxeh.net",
|
||||||
|
"video.yahoo.com/watch/1313289/4562193",
|
||||||
|
"video.yahoo.com/watch/2013707/v2138974",
|
||||||
|
"video.yahoo.com/watch/804885/3375801",
|
||||||
|
"vids.myspace.com/index.cfm?fuseaction=vids.individual&videoid=25992858",
|
||||||
|
"warlocksnerfed.ytmnd.com",
|
||||||
|
"ww.rickroll.net",
|
||||||
|
"you-host.info",
|
||||||
|
"yougotrickrolled.com",
|
||||||
|
"zeroboard.com/16979949#0",
|
||||||
|
"zideo.nl/index.php?option=com_podfeed&zideo=6c4971596d513d3d&playzideo=6c344f596d31593d&Itemid=",
|
||||||
|
];
|
||||||
500
antiRickroll/knownVideoIDs.ts
Normal file
500
antiRickroll/knownVideoIDs.ts
Normal file
@@ -0,0 +1,500 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const knownVideoIds = [
|
||||||
|
"dQw4w9WgXcQ", // The original
|
||||||
|
"oHg5SJYRHA0", // In case they know that link
|
||||||
|
"p7YXXieghto", // But with a different link
|
||||||
|
"E4WlUXrJgy4", // Yet another alt link
|
||||||
|
"6_b7RDuLwcI", // Lyrics
|
||||||
|
"G8iEMVr7GFg", // Otamatone (favorite)
|
||||||
|
"AyOqGRjVtls", // Kermit
|
||||||
|
"6mhmcwmgWbA", // Fortnite
|
||||||
|
"SpZ2FsEfwP4", // Minecraft
|
||||||
|
"H01BwSD9eyQ", // Undertale
|
||||||
|
"nrsnN23tmUA", // Toad
|
||||||
|
"8mkofgRW1II", // Karl Wheezer
|
||||||
|
"rAx5LIul1N8", // 24 cartoon impressions
|
||||||
|
"sO4wVSA9UPs", // Wii Theme
|
||||||
|
"rrs0B_LM898", // Pufferfish
|
||||||
|
"doEqUhFiQS4", // Rick is going to give you up
|
||||||
|
"epyRUp0BhrA", // Sung by 169 movies (2nd favorite)
|
||||||
|
"uK5WDo_3s7s", // Ninja
|
||||||
|
"wzSVOcgKq04", // Barack Obama
|
||||||
|
"7B--1KArxow", // Recorder
|
||||||
|
"rbsPu1z3ugQ", // Brian (Family guy)
|
||||||
|
"ptw2FLKXDQE", // Wreck Roll
|
||||||
|
"E50L-JYWm3w", // Dead memes (this one sucks lmao)
|
||||||
|
"8leAAwMIigI", // Karaoke
|
||||||
|
"ByqFY-Boq5Y", // Just Dance 4
|
||||||
|
"E4ihJMQUmUQ", // Anime style
|
||||||
|
"cjBHXvBYw5s", // Goofy
|
||||||
|
"xaazUgEKuVA", // 1 hr
|
||||||
|
"TzXXHVhGXTQ", // 10 hr
|
||||||
|
"Uj1ykZWtPYI", // R2D2's secret message
|
||||||
|
"EE-xtCF3T94", // Who's that pokemon?
|
||||||
|
"V-_O7nl0Ii0", // Ocean waves
|
||||||
|
"cqF6M25kqq4", // Patrick's secret box
|
||||||
|
"0SoNH07Slj0", // Jellyfish
|
||||||
|
"xfr64zoBTAQ", // Breaking news
|
||||||
|
"j5a0jTc9S10", // Cute dogs
|
||||||
|
"dPmZqsQNzGA", // True Love by Coldplay
|
||||||
|
"nHRbZW097Uk", // Hidden message
|
||||||
|
"BjDebmqFRuc", // Voice cracks, among other weird stuff
|
||||||
|
"Gc2u6AFImn8", // WTF grandayy
|
||||||
|
"8VFzHYtOARw", // Bass boosted
|
||||||
|
"cSAp9sBzPbc", // All notes are C
|
||||||
|
"Dx5i1t0mN78", // ????????
|
||||||
|
"Oo0twK2ZbLU", // Vocals get higher, instruments get lower
|
||||||
|
"cvh0nX08nRw", // It never starts
|
||||||
|
"lXMskKTw3Bc", // Nice singing bro
|
||||||
|
"7z_1E8VGJOw", // Lyrics are Roblox usernames
|
||||||
|
"VgojnNgmgVs", // Beats 2 and 4 are switched
|
||||||
|
"5wOXc03RwVA", // Sung by a cat
|
||||||
|
"2xx_2XNxxfA", // Lofi.
|
||||||
|
"lpiB2wMc49g", // Made anime
|
||||||
|
"H8ZH_mkfPUY", // Rebooted
|
||||||
|
"Svj1bZz2mXw", // Lyrics in alphabetical order
|
||||||
|
"iik25wqIuFo", // Different link
|
||||||
|
"hvL1339luv0", // A cat sings it
|
||||||
|
"N9w1lCZfaWI", // Gamecube version
|
||||||
|
"ivV-kssG3NI", // Kasane Teto
|
||||||
|
"0SoNH07Slj0",
|
||||||
|
"2xx_2XNxxfA",
|
||||||
|
"5wOXc03RwVA",
|
||||||
|
"6_b7RDuLwcI",
|
||||||
|
"6mhmcwmgWbA",
|
||||||
|
"7B--1KArxow",
|
||||||
|
"7z_1E8VGJOw",
|
||||||
|
"8VFzHYtOARw",
|
||||||
|
"8leAAwMIigI",
|
||||||
|
"8mkofgRW1II",
|
||||||
|
"AyOqGRjVtls",
|
||||||
|
"BjDebmqFRuc",
|
||||||
|
"ByqFY-Boq5Y",
|
||||||
|
"Dx5i1t0mN78",
|
||||||
|
"E4WlUXrJgy4",
|
||||||
|
"E4ihJMQUmUQ",
|
||||||
|
"E50L-JYWm3w",
|
||||||
|
"EE-xtCF3T94",
|
||||||
|
"G8iEMVr7GFg",
|
||||||
|
"Gc2u6AFImn8",
|
||||||
|
"H01BwSD9eyQ",
|
||||||
|
"H8ZH_mkfPUY",
|
||||||
|
"N9w1lCZfaWI",
|
||||||
|
"Oo0twK2ZbLU",
|
||||||
|
"SpZ2FsEfwP4",
|
||||||
|
"Svj1bZz2mXw",
|
||||||
|
"TzXXHVhGXTQ",
|
||||||
|
"Uj1ykZWtPYI",
|
||||||
|
"V-_O7nl0Ii0",
|
||||||
|
"VgojnNgmgVs",
|
||||||
|
"cSAp9sBzPbc",
|
||||||
|
"cjBHXvBYw5s",
|
||||||
|
"cqF6M25kqq4",
|
||||||
|
"cvh0nX08nRw",
|
||||||
|
"dPmZqsQNzGA",
|
||||||
|
"dQw4w9WgXcQ",
|
||||||
|
"doEqUhFiQS4",
|
||||||
|
"epyRUp0BhrA",
|
||||||
|
"hvL1339luv0",
|
||||||
|
"iik25wqIuFo",
|
||||||
|
"ivV-kssG3NI",
|
||||||
|
"j5a0jTc9S10",
|
||||||
|
"lXMskKTw3Bc",
|
||||||
|
"lpiB2wMc49g",
|
||||||
|
"nHRbZW097Uk",
|
||||||
|
"nrsnN23tmUA",
|
||||||
|
"oHg5SJYRHA0",
|
||||||
|
"p7YXXieghto",
|
||||||
|
"ptw2FLKXDQE",
|
||||||
|
"rAx5LIul1N8",
|
||||||
|
"rbsPu1z3ugQ",
|
||||||
|
"rrs0B_LM898",
|
||||||
|
"sO4wVSA9UPs",
|
||||||
|
"uK5WDo_3s7s",
|
||||||
|
"wzSVOcgKq04",
|
||||||
|
"xaazUgEKuVA",
|
||||||
|
"xfr64zoBTAQ",
|
||||||
|
"AuKR2fQbMBk",
|
||||||
|
"xvFZjo5PgG0",
|
||||||
|
"BBJa32lCaaY",
|
||||||
|
"QB7ACr7pUuE",
|
||||||
|
"pKskW7wJ0v0",
|
||||||
|
"j7gKwxRe7MQ",
|
||||||
|
"LWErcuHm_C4",
|
||||||
|
"a6pbjksYUHY",
|
||||||
|
"ll-mQPDCn-U",
|
||||||
|
"dRV6NaciZVk",
|
||||||
|
"MCjlo7PtXMQ",
|
||||||
|
"mrThFRR3n8A",
|
||||||
|
"HnfkEVtetuE",
|
||||||
|
"j8PxqgliIno",
|
||||||
|
"AACOcpA8i-U",
|
||||||
|
"bIwVIx5pp88",
|
||||||
|
"OyHQlZeyEr4",
|
||||||
|
"8ybW48rKBME",
|
||||||
|
"ZK1pNGmNBEc",
|
||||||
|
"cSQTZoZPJzs",
|
||||||
|
"6lhwMJuBIEw",
|
||||||
|
"IR_rbAer7kY",
|
||||||
|
"5iqIug1Rox8",
|
||||||
|
"EkfDmzprwrw",
|
||||||
|
"EjahYsvSTts",
|
||||||
|
"8NBdab8iors",
|
||||||
|
"UHYLsSLSUCw",
|
||||||
|
"QMIaYRaUC5E",
|
||||||
|
"JDuaYGd0zUI",
|
||||||
|
"dy4bWkj4_RA",
|
||||||
|
"55C1L77QrGk",
|
||||||
|
"TSi6_A74lCw",
|
||||||
|
"w-kk-bU_QVw",
|
||||||
|
"uPbl8o3bjY0",
|
||||||
|
"dQw4w9WgXcQ",
|
||||||
|
"hVzINKRbekY",
|
||||||
|
"wzSVOcgKq04",
|
||||||
|
"xaazUgEKuVA",
|
||||||
|
"xfr64zoBTAQ",
|
||||||
|
"xm3YgoEiEDc",
|
||||||
|
"xvFZjo5PgG0",
|
||||||
|
"zL19uMsnpSU",
|
||||||
|
"-HRRGn6tNd4",
|
||||||
|
"-umtVthRGJI",
|
||||||
|
"1V_aE_Xdde8",
|
||||||
|
"3HrSN7176XI",
|
||||||
|
"3KANI2dpXLw",
|
||||||
|
"4TJB9FQo45E",
|
||||||
|
"4ynGOr9vmyc",
|
||||||
|
"5F5nc1bAaKw",
|
||||||
|
"5kQKh2tdisQ",
|
||||||
|
"5uZr3JWYdy8",
|
||||||
|
"65I0HNvTDH4",
|
||||||
|
"67KOFEEOhkI",
|
||||||
|
"6SYVdI7Llrg",
|
||||||
|
"8Set3JpJJ4w",
|
||||||
|
"8aJjMOy-Ops",
|
||||||
|
"A1sgzEDUG-o",
|
||||||
|
"ABUhOJxZQmg",
|
||||||
|
"AP12uZvfvag",
|
||||||
|
"AS35zlAdaSQ",
|
||||||
|
"CZoJt0Sbqrs",
|
||||||
|
"DpPhnECPe2I",
|
||||||
|
"EEbzptEFsKk",
|
||||||
|
"FGEUClII8x0",
|
||||||
|
"G_vas-7a7is",
|
||||||
|
"HiaBjpzLgQI",
|
||||||
|
"I6_0tpqg3ZE",
|
||||||
|
"IHKAgwIxUAY",
|
||||||
|
"IVvl_R2jYMo",
|
||||||
|
"IpjGmx2v6bM",
|
||||||
|
"J3VnZMoh7sk",
|
||||||
|
"Kmt4wrn1MTk",
|
||||||
|
"LeSnAn-Sc0g",
|
||||||
|
"LqXTU8YAGzo",
|
||||||
|
"MJCH_wT9TaU",
|
||||||
|
"MoUPdJrjkCM",
|
||||||
|
"NZ-AAD7Ci_c",
|
||||||
|
"PIMrL4qXtJ0",
|
||||||
|
"PXrHCBoEj7g",
|
||||||
|
"QumbExFAj-U",
|
||||||
|
"R5P1_U7LZX8",
|
||||||
|
"RSsJ19sy3JI",
|
||||||
|
"RgIDuaxiT0w",
|
||||||
|
"RzoZGNsJ71w",
|
||||||
|
"SGi7qi_y0Jw",
|
||||||
|
"UDTGvgE5eJw",
|
||||||
|
"VBY4TV5qK-4",
|
||||||
|
"VVjUWKSZSsc",
|
||||||
|
"WpEVccrkYQ0",
|
||||||
|
"X-j828DqqnY",
|
||||||
|
"XfTUDW93z6E",
|
||||||
|
"Xsvi9uNrDSI",
|
||||||
|
"YWn54TjfBkk",
|
||||||
|
"Yu_moia-oVI",
|
||||||
|
"ZIQZHqNQODo",
|
||||||
|
"ZOU8GIRUd_g",
|
||||||
|
"Zc2tpMgz6MI",
|
||||||
|
"_0719DxMOUY",
|
||||||
|
"_FyXC-SsAPE",
|
||||||
|
"aSzhxllE0RM",
|
||||||
|
"atiNprQmjks",
|
||||||
|
"b1WWpKEPdT4",
|
||||||
|
"b43GgNbz9fg",
|
||||||
|
"cjeogv9VUAE",
|
||||||
|
"cxwxBheZniM",
|
||||||
|
"dS9DO6kx-Ek",
|
||||||
|
"eKDcl0V6o6k",
|
||||||
|
"eLiXPfl8EPY",
|
||||||
|
"f2b1D5w82yU",
|
||||||
|
"f8FHqEIzSlE",
|
||||||
|
"fMzkMpMraFY",
|
||||||
|
"fmxGLQd3J0U",
|
||||||
|
"gLVtavM962w",
|
||||||
|
"gdpijMRhoT8",
|
||||||
|
"gvUiLtwlEl8",
|
||||||
|
"hq05IRf0dBQ",
|
||||||
|
"hyX_krrTBZ0",
|
||||||
|
"iJbwc4wm5Y0",
|
||||||
|
"lAQIiNTH46I",
|
||||||
|
"lfO4Z5WEUuE",
|
||||||
|
"lfao5IToml4",
|
||||||
|
"lp6nr-rD_g8",
|
||||||
|
"lzSjyzqfegI",
|
||||||
|
"oHg5SJYRHA0",
|
||||||
|
"piLTpv1eKdU",
|
||||||
|
"q6NwqFlctZY",
|
||||||
|
"r8tXjJL3xcM",
|
||||||
|
"rfp7FbsnsbU",
|
||||||
|
"tazYxtJcwCc",
|
||||||
|
"thNTPin2RBY",
|
||||||
|
"uYMIMPVK1vU",
|
||||||
|
"ub_VBGajh-s",
|
||||||
|
"uwnuL5Fy5g8",
|
||||||
|
"uxIsiTo4VJo",
|
||||||
|
"v7cyQ-dVaAM",
|
||||||
|
"veFrQTKQy7A",
|
||||||
|
"vf79MCuQ8jM",
|
||||||
|
"vp8fkB0uwd0",
|
||||||
|
"vvs7cXmVwN8",
|
||||||
|
"xAp3HqpE7V8",
|
||||||
|
"xm_EMOdpDhc",
|
||||||
|
"xpupxRzumYs",
|
||||||
|
"y5Ja-E529sU",
|
||||||
|
"yXGqsnkLg0A",
|
||||||
|
"ywoqy9PBN-0",
|
||||||
|
"yxnWl63Avo4",
|
||||||
|
"z-HWXfRKkJU",
|
||||||
|
"z2kThcO6ig8",
|
||||||
|
"zGm0nGF_y2E",
|
||||||
|
"BUykFA7FCo4",
|
||||||
|
"0SoNH07Slj0",
|
||||||
|
"2mun7xy12H0",
|
||||||
|
"34Ig3X59_qA",
|
||||||
|
"5wOXc03RwVA",
|
||||||
|
"6-HUgzYPm9g",
|
||||||
|
"6_b7RDuLwcI",
|
||||||
|
"6mhmcwmgWbA",
|
||||||
|
"7B--1KArxow",
|
||||||
|
"7z_1E8VGJOw",
|
||||||
|
"828hEBkvA5g",
|
||||||
|
"8VFzHYtOARw",
|
||||||
|
"8leAAwMIigI",
|
||||||
|
"8mkofgRW1II",
|
||||||
|
"AyOqGRjVtls",
|
||||||
|
"BjDebmqFRuc",
|
||||||
|
"ByqFY-Boq5Y",
|
||||||
|
"DLzxrzFCyOs",
|
||||||
|
"Dx5i1t0mN78",
|
||||||
|
"E4ihJMQUmUQ",
|
||||||
|
"EE-xtCF3T94",
|
||||||
|
"G8iEMVr7GFg",
|
||||||
|
"Gc2u6AFImn8",
|
||||||
|
"H01BwSD9eyQ",
|
||||||
|
"IdkCEioCp24",
|
||||||
|
"Oo0twK2ZbLU",
|
||||||
|
"Rtqkxkt7Hyg",
|
||||||
|
"SpZ2FsEfwP4",
|
||||||
|
"TOcAAaZ1HhU",
|
||||||
|
"TzXXHVhGXTQ",
|
||||||
|
"Uj1ykZWtPYI",
|
||||||
|
"UmOi40tnUcM",
|
||||||
|
"V-_O7nl0Ii0",
|
||||||
|
"VbUuB1aN2DA",
|
||||||
|
"VgojnNgmgVs",
|
||||||
|
"YJWSAJjkTsI",
|
||||||
|
"ZzUsKizhb8o",
|
||||||
|
"a3Z7zEc7AXQ",
|
||||||
|
"cSAp9sBzPbc",
|
||||||
|
"cqF6M25kqq4",
|
||||||
|
"cvh0nX08nRw",
|
||||||
|
"dPmZqsQNzGA",
|
||||||
|
"dQw4w9WgXcQ",
|
||||||
|
"doEqUhFiQS4",
|
||||||
|
"epyRUp0BhrA",
|
||||||
|
"gvGyS5j9aFY",
|
||||||
|
"hLZW4U86cL4",
|
||||||
|
"iik25wqIuFo",
|
||||||
|
"j5a0jTc9S10",
|
||||||
|
"lXMskKTw3Bc",
|
||||||
|
"nHRbZW097Uk",
|
||||||
|
"nrsnN23tmUA",
|
||||||
|
"oHg5SJYRHA0",
|
||||||
|
"oT3mCybbhf0",
|
||||||
|
"ptw2FLKXDQE",
|
||||||
|
"r7VYFiPoZk4",
|
||||||
|
"r8tXjJL3xcM",
|
||||||
|
"rAx5LIul1N8",
|
||||||
|
"rbsPu1z3ugQ",
|
||||||
|
"rrs0B_LM898",
|
||||||
|
"sO4wVSA9UPs",
|
||||||
|
"tzYPr9w22VU",
|
||||||
|
"uK5WDo_3s7s",
|
||||||
|
"ub82Xb1C8os",
|
||||||
|
"wpV-gGA4PSk",
|
||||||
|
"wuggc60TVzU",
|
||||||
|
"cSAp9sBzPbc",
|
||||||
|
"8ybW48rKBME",
|
||||||
|
"Tt7bzxurJ1I",
|
||||||
|
"gidHrKbTpog",
|
||||||
|
"vcq30ywIKlc",
|
||||||
|
"y6120QOlsfU",
|
||||||
|
"QhuZIEkKkXA",
|
||||||
|
"rW7hXs-81hM",
|
||||||
|
"Oo0twK2ZbLU",
|
||||||
|
"0SoNH07Slj0",
|
||||||
|
"LLFhKaqnWwk",
|
||||||
|
"SpZ2FsEfwP4",
|
||||||
|
"SO4c1NlGCpY",
|
||||||
|
"MCjlo7PtXMQ",
|
||||||
|
"TCUPeAlpDVE",
|
||||||
|
"5wOXc03RwVA",
|
||||||
|
"oJl25bABYac",
|
||||||
|
"a6pbjksYUHY",
|
||||||
|
"Dx5i1t0mN78",
|
||||||
|
"Uj1ykZWtPYI",
|
||||||
|
"E50L-JYWm3w",
|
||||||
|
"BjDebmqFRuc",
|
||||||
|
"PibwQR9nRus",
|
||||||
|
"rrs0B_LM898",
|
||||||
|
"cH1NLToRz_o",
|
||||||
|
"j5a0jTc9S10",
|
||||||
|
"p7YXXieghto",
|
||||||
|
"qxeokP0n6V0",
|
||||||
|
"GHMjD0Lp5DY",
|
||||||
|
"bIwVIx5pp88",
|
||||||
|
"7z_1E8VGJOw",
|
||||||
|
"QB7ACr7pUuE",
|
||||||
|
"LjQZaD9EEJ0",
|
||||||
|
"cvh0nX08nRw",
|
||||||
|
"fZi4JxbTwPo",
|
||||||
|
"2ocykBzWDiM",
|
||||||
|
"H01BwSD9eyQ",
|
||||||
|
"PzqQSOaCcnw",
|
||||||
|
"lXMskKTw3Bc",
|
||||||
|
"JzjldPdpT7Q",
|
||||||
|
"7B--1KArxow",
|
||||||
|
"lHyeAtiiL18",
|
||||||
|
"s0akG-V_Y30",
|
||||||
|
"HV8IxKtAlrA",
|
||||||
|
"6_b7RDuLwcI",
|
||||||
|
"rbsPu1z3ugQ",
|
||||||
|
"8O_ifyIIrN4",
|
||||||
|
"xvFZjo5PgG0",
|
||||||
|
"N3MKlU5_Gs0",
|
||||||
|
"AyOqGRjVtls",
|
||||||
|
"bCh5IlXTckA",
|
||||||
|
"pSxJqmMNU-A",
|
||||||
|
"ByqFY-Boq5Y",
|
||||||
|
"G8iEMVr7GFg",
|
||||||
|
"s99hC5WUwjo",
|
||||||
|
"uK5WDo_3s7s",
|
||||||
|
"TzXXHVhGXTQ",
|
||||||
|
"OYPG7j8rKZY",
|
||||||
|
"Kiz3PM387FI",
|
||||||
|
"2l51wyMM9hs",
|
||||||
|
"ptw2FLKXDQE",
|
||||||
|
"wzSVOcgKq04",
|
||||||
|
"rAx5LIul1N8",
|
||||||
|
"ll-mQPDCn-U",
|
||||||
|
"hxCXEX2JOKE",
|
||||||
|
"6RyOsIseJbk",
|
||||||
|
"HUU3kOhjFfg",
|
||||||
|
"3KANI2dpXLw",
|
||||||
|
"-51AfyMqnpI",
|
||||||
|
"6mhmcwmgWbA",
|
||||||
|
"7lEodsmjeQU",
|
||||||
|
"8leAAwMIigI",
|
||||||
|
"xaazUgEKuVA",
|
||||||
|
"dQw4w9WgXcQ",
|
||||||
|
"nHRbZW097Uk",
|
||||||
|
"vkbQmH5MPME",
|
||||||
|
"6vBnqJhP7f8",
|
||||||
|
"xfr64zoBTAQ",
|
||||||
|
"EE-xtCF3T94",
|
||||||
|
"zL19uMsnpSU",
|
||||||
|
"mrThFRR3n8A",
|
||||||
|
"E4ihJMQUmUQ",
|
||||||
|
"kczWpSN6emg",
|
||||||
|
"bkOVXdvijmQ",
|
||||||
|
"cqF6M25kqq4",
|
||||||
|
"cAN30xJp2Cs",
|
||||||
|
"doEqUhFiQS4",
|
||||||
|
"iiUIi5b9RlE",
|
||||||
|
"H8ZH_mkfPUY",
|
||||||
|
"HPk-VhRjNI8",
|
||||||
|
"INbRpclIFsE",
|
||||||
|
"ikFZLI4HLpQ",
|
||||||
|
"dPmZqsQNzGA",
|
||||||
|
"cjBHXvBYw5s",
|
||||||
|
"SjTOn5scRmY",
|
||||||
|
"JkcHqN6YswU",
|
||||||
|
"IO9XlQrEt2Y",
|
||||||
|
"oHg5SJYRHA0",
|
||||||
|
"lpiB2wMc49g",
|
||||||
|
"DIs7dtlMCP0",
|
||||||
|
"gvGyS5j9aFY",
|
||||||
|
"VgojnNgmgVs",
|
||||||
|
"SsiHLiXBlcM",
|
||||||
|
"Q53-mWHvxJo",
|
||||||
|
"XfIIQYnBHrQ",
|
||||||
|
"LWErcuHm_C4",
|
||||||
|
"AACOcpA8i-U",
|
||||||
|
"QdNEtVH9bZE",
|
||||||
|
"dRV6NaciZVk",
|
||||||
|
"ub82Xb1C8os",
|
||||||
|
"ENYalQvZG4Q",
|
||||||
|
"BXuxOeg6PiQ",
|
||||||
|
"0Z0i-nimHkU",
|
||||||
|
"Mdq6sQPKYqQ",
|
||||||
|
"C5GGeuFPVVE",
|
||||||
|
"Gc2u6AFImn8",
|
||||||
|
"klqi_h9FElc",
|
||||||
|
"Eg7XtrH0duI",
|
||||||
|
"aaP6xIkMqzo",
|
||||||
|
"xbXoWRs2C8M",
|
||||||
|
"pKskW7wJ0v0",
|
||||||
|
"HnfkEVtetuE",
|
||||||
|
"9oxRDJjAQKI",
|
||||||
|
"j7gKwxRe7MQ",
|
||||||
|
"42OleX0HR4E",
|
||||||
|
"nrsnN23tmUA",
|
||||||
|
"iik25wqIuFo",
|
||||||
|
"E458nb_pPmk",
|
||||||
|
"06pBzAlItwI",
|
||||||
|
"rTgj1HxmUbg",
|
||||||
|
"epyRUp0BhrA",
|
||||||
|
"rEtZzcxQ_pA",
|
||||||
|
"Yb6dZ1IFlKc",
|
||||||
|
"eBGIQ7ZuuiU",
|
||||||
|
"soq9cLVa5Xo",
|
||||||
|
"r8tXjJL3xcM",
|
||||||
|
"XB3EQrj1maw",
|
||||||
|
"RvBwypGUkPo",
|
||||||
|
"d4N5LnsNpF0",
|
||||||
|
"j8PxqgliIno",
|
||||||
|
"th0pH9srXRY",
|
||||||
|
"sO4wVSA9UPs",
|
||||||
|
"8mkofgRW1II",
|
||||||
|
"fMnIpIMuBJI",
|
||||||
|
"gPkZS92WCIo",
|
||||||
|
"_sWG4uhLiWo",
|
||||||
|
"8VFzHYtOARw",
|
||||||
|
"V-_O7nl0Ii0",
|
||||||
|
"eBsIpefmXvE",
|
||||||
|
"nW0P2hYBm9A",
|
||||||
|
"MAM--whuMcU",
|
||||||
|
"QKr_0DMYV5g",
|
||||||
|
"VZrDxD0Za9I",
|
||||||
|
"WSBK_NePew",
|
||||||
|
"1kj837fWpo",
|
||||||
|
"oAyaw1ohiWs",
|
||||||
|
"iadFGiLRgFo",
|
||||||
|
"A4hJPP0Zn9I",
|
||||||
|
"r1JAZlyhKMc",
|
||||||
|
"DdpBpn6txTk",
|
||||||
|
"yS6LYj-y1HA",
|
||||||
|
"WyltKn3pi9U",
|
||||||
|
];
|
||||||
603
badgesSelector/index.tsx
Normal file
603
badgesSelector/index.tsx
Normal file
@@ -0,0 +1,603 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2025 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as DataStore from "@api/DataStore";
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
import { findStoreLazy } from "@webpack";
|
||||||
|
import { Menu, Toasts } from "@webpack/common";
|
||||||
|
const UserProfileStore = findStoreLazy("UserProfileStore");
|
||||||
|
const userBadgesMap = new Map<string, any[]>();
|
||||||
|
|
||||||
|
const removedBadgesMap = new Map<string, Set<string>>();
|
||||||
|
|
||||||
|
function getNitroSinceDate(months: number): string {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const sinceDate = new Date(currentDate);
|
||||||
|
sinceDate.setMonth(currentDate.getMonth() - months);
|
||||||
|
const month = sinceDate.getMonth() + 1;
|
||||||
|
const day = sinceDate.getDate();
|
||||||
|
const year = sinceDate.getFullYear();
|
||||||
|
return `${month}/${day}/${year.toString().slice(-2)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBoostSinceDate(months: number): string {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const sinceDate = new Date(currentDate);
|
||||||
|
sinceDate.setMonth(currentDate.getMonth() - months);
|
||||||
|
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
||||||
|
return `${monthNames[sinceDate.getMonth()]} ${sinceDate.getDate()}, ${sinceDate.getFullYear()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const availableBadges = [
|
||||||
|
{
|
||||||
|
id: "staff",
|
||||||
|
title: "Discord Staff",
|
||||||
|
description: "Discord Staff",
|
||||||
|
icon: "5e74e9b61934fc1f67c65515d1f7e60d",
|
||||||
|
link: "https://discord.com/company"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "premium",
|
||||||
|
title: "Nitro Subscriber",
|
||||||
|
description: "Subscriber since Dec 22, 2016",
|
||||||
|
icon: "2ba85e8026a8614b640c2837bcdfe21b",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "premium_tenure_1_month_v2",
|
||||||
|
title: "Nitro Bronze (1 month)",
|
||||||
|
description: `Subscriber since ${getNitroSinceDate(1)}`,
|
||||||
|
icon: "4f33c4a9c64ce221936bd256c356f91f",
|
||||||
|
link: "https://discord.com/nitro"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "premium_tenure_3_month_v2",
|
||||||
|
title: "Nitro Silver (3 months)",
|
||||||
|
description: `Subscriber since ${getNitroSinceDate(3)}`,
|
||||||
|
icon: "4514fab914bdbfb4ad2fa23df76121a6",
|
||||||
|
link: "https://discord.com/nitro"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "premium_tenure_6_month_v2",
|
||||||
|
title: "Nitro Gold (6 months)",
|
||||||
|
description: `Subscriber since ${getNitroSinceDate(6)}`,
|
||||||
|
icon: "2895086c18d5531d499862e41d1155a6",
|
||||||
|
link: "https://discord.com/nitro"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "premium_tenure_12_month_v2",
|
||||||
|
title: "Nitro Platinum (1 year)",
|
||||||
|
description: `Subscriber since ${getNitroSinceDate(12)}`,
|
||||||
|
icon: "0334688279c8359120922938dcb1d6f8",
|
||||||
|
link: "https://discord.com/nitro"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "premium_tenure_24_month_v2",
|
||||||
|
title: "Nitro Diamond (2 years)",
|
||||||
|
description: `Subscriber since ${getNitroSinceDate(24)}`,
|
||||||
|
icon: "0d61871f72bb9a33a7ae568c1fb4f20a",
|
||||||
|
link: "https://discord.com/nitro"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "premium_tenure_36_month_v2",
|
||||||
|
title: "Nitro Emerald (3 years)",
|
||||||
|
description: `Subscriber since ${getNitroSinceDate(36)}`,
|
||||||
|
icon: "11e2d339068b55d3a506cff34d3780f3",
|
||||||
|
link: "https://discord.com/nitro"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "premium_tenure_60_month_v2",
|
||||||
|
title: "Nitro Ruby (5 years)",
|
||||||
|
description: `Subscriber since ${getNitroSinceDate(60)}`,
|
||||||
|
icon: "cd5e2cfd9d7f27a8cdcd3e8a8d5dc9f4",
|
||||||
|
link: "https://discord.com/nitro"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "premium_tenure_72_month_v2",
|
||||||
|
title: "Nitro Opal (6+ years)",
|
||||||
|
description: `Subscriber since ${getNitroSinceDate(72)}`,
|
||||||
|
icon: "5b154df19c53dce2af92c9b61e6be5e2",
|
||||||
|
link: "https://discord.com/nitro"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "partner",
|
||||||
|
title: "Partnered Server Owner",
|
||||||
|
description: "Partnered Server Owner",
|
||||||
|
icon: "3f9748e53446a137a052f3454e2de41e",
|
||||||
|
link: "https://discord.com/partners"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "certified_moderator",
|
||||||
|
title: "Moderator Programs Alumni",
|
||||||
|
description: "Moderator Programs Alumni",
|
||||||
|
icon: "fee1624003e2fee35cb398e125dc479b",
|
||||||
|
link: "https://discord.com/safety"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "hypesquad",
|
||||||
|
title: "HypeSquad Events",
|
||||||
|
description: "HypeSquad Events",
|
||||||
|
icon: "bf01d1073931f921909045f3a39fd264",
|
||||||
|
link: "https://discord.com/hypesquad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "hypesquad_house_1",
|
||||||
|
title: "HypeSquad Bravery",
|
||||||
|
description: "HypeSquad Bravery",
|
||||||
|
icon: "8a88d63823d8a71cd5e390baa45efa02",
|
||||||
|
link: "https://discord.com/settings/hypesquad-online"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "hypesquad_house_2",
|
||||||
|
title: "HypeSquad Brilliance",
|
||||||
|
description: "HypeSquad Brilliance",
|
||||||
|
icon: "011940fd013da3f7fb926e4a1cd2e618",
|
||||||
|
link: "https://discord.com/settings/hypesquad-online"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "hypesquad_house_3",
|
||||||
|
title: "HypeSquad Balance",
|
||||||
|
description: "HypeSquad Balance",
|
||||||
|
icon: "3aa41de486fa12454c3761e8e223442e",
|
||||||
|
link: "https://discord.com/settings/hypesquad-online"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "bug_hunter_level_1",
|
||||||
|
title: "Discord Bug Hunter",
|
||||||
|
description: "Discord Bug Hunter",
|
||||||
|
icon: "2717692c7dca7289b35297368a940dd0",
|
||||||
|
link: "https://support.discord.com/hc/en-us/articles/360046057772-Discord-Bugs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "bug_hunter_level_2",
|
||||||
|
title: "Discord Bug Hunter Gold",
|
||||||
|
description: "Discord Bug Hunter",
|
||||||
|
icon: "848f79194d4be5ff5f81505cbd0ce1e6",
|
||||||
|
link: "https://support.discord.com/hc/en-us/articles/360046057772-Discord-Bugs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "active_developer",
|
||||||
|
title: "Active Developer",
|
||||||
|
description: "Active Developer",
|
||||||
|
icon: "6bdc42827a38498929a4920da12695d9",
|
||||||
|
link: "https://support-dev.discord.com/hc/en-us/articles/10113997751447?ref=badge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "verified_developer",
|
||||||
|
title: "Early Verified Bot Developer",
|
||||||
|
description: "Early Verified Bot Developer",
|
||||||
|
icon: "6df5892e0f35b051f8b61eace34f4967",
|
||||||
|
link: "https://discord.com/developers"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "early_supporter",
|
||||||
|
title: "Early Supporter",
|
||||||
|
description: "Early Supporter",
|
||||||
|
icon: "7060786766c9c840eb3019e725d2b358",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "guild_booster_lvl1",
|
||||||
|
title: "Server Boost 1 Month",
|
||||||
|
description: `Server boosting since ${getBoostSinceDate(1)}`,
|
||||||
|
icon: "51040c70d4f20a921ad6674ff86fc95c",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "guild_booster_lvl2",
|
||||||
|
title: "Server Boost 2 Months",
|
||||||
|
description: `Server boosting since ${getBoostSinceDate(2)}`,
|
||||||
|
icon: "0e4080d1d333bc7ad29ef6528b6f2fb7",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "guild_booster_lvl3",
|
||||||
|
title: "Server Boost 3 Months",
|
||||||
|
description: `Server boosting since ${getBoostSinceDate(3)}`,
|
||||||
|
icon: "72bed924410c304dbe3d00a6e593ff59",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "guild_booster_lvl4",
|
||||||
|
title: "Server Boost 6 Months",
|
||||||
|
description: `Server boosting since ${getBoostSinceDate(6)}`,
|
||||||
|
icon: "df199d2050d3ed4ebf84d64ae83989f8",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "guild_booster_lvl5",
|
||||||
|
title: "Server Boost 9 Months",
|
||||||
|
description: `Server boosting since ${getBoostSinceDate(9)}`,
|
||||||
|
icon: "996b3e870e8a22ce519b3a50e6bdd52f",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "guild_booster_lvl6",
|
||||||
|
title: "Server Boost 12 Months",
|
||||||
|
description: `Server boosting since ${getBoostSinceDate(12)}`,
|
||||||
|
icon: "991c9f39ee33d7537d9f408c3e53141e",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "guild_booster_lvl7",
|
||||||
|
title: "Server Boost 15 Months",
|
||||||
|
description: `Server boosting since ${getBoostSinceDate(15)}`,
|
||||||
|
icon: "cb3ae83c15e970e8f3d410bc62cb8b99",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "guild_booster_lvl8",
|
||||||
|
title: "Server Boost 18 Months",
|
||||||
|
description: `Server boosting since ${getBoostSinceDate(18)}`,
|
||||||
|
icon: "7142225d31238f6387d9f09efaa02759",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "guild_booster_lvl9",
|
||||||
|
title: "Server Boost 24 Months",
|
||||||
|
description: `Server boosting since ${getBoostSinceDate(24)}`,
|
||||||
|
icon: "ec92202290b48d0879b7413d2dde3bab",
|
||||||
|
link: "https://discord.com/settings/premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "legacy_username",
|
||||||
|
title: "Legacy Username",
|
||||||
|
description: "Originally known as their old username",
|
||||||
|
icon: "6de6d34650760ba5551a79732e98ed60",
|
||||||
|
link: "https://discord.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "quest_completed",
|
||||||
|
title: "Quest Completer",
|
||||||
|
description: "Completed a Quest",
|
||||||
|
icon: "7d9ae358c8c5e118768335dbe68b4fb8",
|
||||||
|
link: "https://discord.com/settings/inventory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "bot_commands",
|
||||||
|
title: "Supports Commands",
|
||||||
|
description: "Supports Commands",
|
||||||
|
icon: "6f9e37f9029ff57aef81db857890005e",
|
||||||
|
link: "https://discord.com/blog/welcome-to-the-new-era-of-discord-apps?ref=badge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "automod",
|
||||||
|
title: "Uses AutoMod",
|
||||||
|
description: "Uses automod",
|
||||||
|
icon: "f2459b691ac7453ed6039bbcfaccbfcd",
|
||||||
|
link: "https://discord.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "application_guild_subscription",
|
||||||
|
title: "Server Subscription",
|
||||||
|
description: "Monetized server",
|
||||||
|
icon: "d2010c413a8da2208b7e4311042a4b9d",
|
||||||
|
link: "https://discord.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "orb_profile_badge",
|
||||||
|
title: "Orbs",
|
||||||
|
description: "Collected the Orb Profile Badge",
|
||||||
|
icon: "83d8a1eb09a8d64e59233eec5d4d5c2d",
|
||||||
|
link: "https://discord.com"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
async function loadData() {
|
||||||
|
const savedUserBadges = await DataStore.get("userBadges");
|
||||||
|
if (savedUserBadges) {
|
||||||
|
Object.entries(savedUserBadges).forEach(([userId, badges]) => {
|
||||||
|
const updatedBadges = (badges as any[]).map(badge => {
|
||||||
|
const freshBadge = availableBadges.find(b => b.id === badge.id);
|
||||||
|
if (freshBadge && (badge.id.startsWith("premium_tenure_") || badge.id.startsWith("guild_booster_"))) {
|
||||||
|
return { ...badge, description: freshBadge.description };
|
||||||
|
}
|
||||||
|
return badge;
|
||||||
|
});
|
||||||
|
userBadgesMap.set(userId, updatedBadges);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const savedRemovedBadges = await DataStore.get("removedBadges");
|
||||||
|
if (savedRemovedBadges) {
|
||||||
|
Object.entries(savedRemovedBadges).forEach(([userId, badgeIds]) => {
|
||||||
|
removedBadgesMap.set(userId, new Set(badgeIds as string[]));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveData() {
|
||||||
|
const userBadgesObject = Object.fromEntries(userBadgesMap);
|
||||||
|
await DataStore.set("userBadges", userBadgesObject);
|
||||||
|
|
||||||
|
const removedBadgesObject = Object.fromEntries(
|
||||||
|
Array.from(removedBadgesMap.entries()).map(([userId, badgeIds]) => [userId, Array.from(badgeIds)])
|
||||||
|
);
|
||||||
|
await DataStore.set("removedBadges", removedBadgesObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBadgesToUser(userId: string, badges: any[]) {
|
||||||
|
const existingBadges = userBadgesMap.get(userId) || [];
|
||||||
|
badges.forEach(badge => {
|
||||||
|
const existingIndex = existingBadges.findIndex(b => b.id === badge.id);
|
||||||
|
if (existingIndex === -1) {
|
||||||
|
existingBadges.push(badge);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
userBadgesMap.set(userId, existingBadges);
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeBadgeFromUser(userId: string, badgeId: string) {
|
||||||
|
const existingBadges = userBadgesMap.get(userId) || [];
|
||||||
|
const updatedBadges = existingBadges.filter(b => b.id !== badgeId);
|
||||||
|
if (updatedBadges.length > 0) {
|
||||||
|
userBadgesMap.set(userId, updatedBadges);
|
||||||
|
} else {
|
||||||
|
userBadgesMap.delete(userId);
|
||||||
|
}
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUserBadges(userId: string): any[] {
|
||||||
|
return userBadgesMap.get(userId) || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideRealBadge(userId: string, badgeId: string) {
|
||||||
|
if (!removedBadgesMap.has(userId)) {
|
||||||
|
removedBadgesMap.set(userId, new Set());
|
||||||
|
}
|
||||||
|
removedBadgesMap.get(userId)!.add(badgeId);
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
function unhideRealBadge(userId: string, badgeId: string) {
|
||||||
|
if (removedBadgesMap.has(userId)) {
|
||||||
|
removedBadgesMap.get(userId)!.delete(badgeId);
|
||||||
|
if (removedBadgesMap.get(userId)!.size === 0) {
|
||||||
|
removedBadgesMap.delete(userId);
|
||||||
|
}
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRealBadgeHidden(userId: string, badgeId: string): boolean {
|
||||||
|
return removedBadgesMap.has(userId) && removedBadgesMap.get(userId)!.has(badgeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleBadge(userId: string, badge: any, hasActualBadge: boolean) {
|
||||||
|
const hasUserBadge = getUserBadges(userId).find(b => b.id === badge.id);
|
||||||
|
const isHidden = isRealBadgeHidden(userId, badge.id);
|
||||||
|
|
||||||
|
if (hasActualBadge) {
|
||||||
|
if (isHidden) {
|
||||||
|
unhideRealBadge(userId, badge.id);
|
||||||
|
Toasts.show({
|
||||||
|
message: `Restored ${badge.title}`,
|
||||||
|
type: Toasts.Type.SUCCESS,
|
||||||
|
id: Toasts.genId()
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
hideRealBadge(userId, badge.id);
|
||||||
|
Toasts.show({
|
||||||
|
message: `Removed ${badge.title}`,
|
||||||
|
type: Toasts.Type.SUCCESS,
|
||||||
|
id: Toasts.genId()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (hasUserBadge) {
|
||||||
|
removeBadgeFromUser(userId, badge.id);
|
||||||
|
Toasts.show({
|
||||||
|
message: `Removed ${badge.title}`,
|
||||||
|
type: Toasts.Type.SUCCESS,
|
||||||
|
id: Toasts.genId()
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
addBadgesToUser(userId, [badge]);
|
||||||
|
Toasts.show({
|
||||||
|
message: `Added ${badge.title}`,
|
||||||
|
type: Toasts.Type.SUCCESS,
|
||||||
|
id: Toasts.genId()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function giveAllBadges(userId: string) {
|
||||||
|
addBadgesToUser(userId, availableBadges);
|
||||||
|
Toasts.show({
|
||||||
|
message: "Added all badges",
|
||||||
|
type: Toasts.Type.SUCCESS,
|
||||||
|
id: Toasts.genId()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addUserBadge(userId: string) {
|
||||||
|
const badgeId = prompt("Enter badge ID:");
|
||||||
|
if (!badgeId) return;
|
||||||
|
|
||||||
|
const description = prompt("Enter badge description:");
|
||||||
|
if (!description) return;
|
||||||
|
|
||||||
|
const icon = prompt("Enter badge icon hash:");
|
||||||
|
if (!icon) return;
|
||||||
|
|
||||||
|
const link = prompt("Enter badge link (optional):", "https://discord.com");
|
||||||
|
|
||||||
|
const userBadge = {
|
||||||
|
id: badgeId,
|
||||||
|
description: description,
|
||||||
|
icon: icon,
|
||||||
|
link: link || "https://discord.com"
|
||||||
|
};
|
||||||
|
|
||||||
|
addBadgesToUser(userId, [userBadge]);
|
||||||
|
Toasts.show({
|
||||||
|
message: `Added badge: ${badgeId}`,
|
||||||
|
type: Toasts.Type.SUCCESS,
|
||||||
|
id: Toasts.genId()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let originalGetUserProfile: any;
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "BadgeSelector",
|
||||||
|
description: "Customize user badges - add, remove, or hide any Discord badge",
|
||||||
|
authors: [
|
||||||
|
{ id: 1263457746829705310n, name: ".q1" },
|
||||||
|
{ id: 1147940825330876538n, name: "Jelly" },
|
||||||
|
{ id: 1403404140461297816n, name: "Sami" },
|
||||||
|
],
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
await loadData();
|
||||||
|
originalGetUserProfile = UserProfileStore.getUserProfile;
|
||||||
|
|
||||||
|
UserProfileStore.getUserProfile = function (userId: string) {
|
||||||
|
const userProfile = originalGetUserProfile.call(this, userId);
|
||||||
|
if (!userProfile) return userProfile;
|
||||||
|
|
||||||
|
let newBadges = [...(userProfile.badges || [])];
|
||||||
|
|
||||||
|
if (removedBadgesMap.has(userId)) {
|
||||||
|
const hiddenBadges = removedBadgesMap.get(userId)!;
|
||||||
|
newBadges = newBadges.filter(b => !hiddenBadges.has(b.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userBadgesMap.has(userId)) {
|
||||||
|
const userBadges = userBadgesMap.get(userId)!;
|
||||||
|
userBadges.forEach(badgeObj => {
|
||||||
|
const { id, description, icon, link } = badgeObj;
|
||||||
|
const badgeIndex = newBadges.findIndex(b => b.id === id);
|
||||||
|
if (badgeIndex === -1) {
|
||||||
|
newBadges.push({ id, description, icon, link });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
newBadges.sort((a, b) => {
|
||||||
|
const orderA = availableBadges.findIndex(badge => badge.id === a.id);
|
||||||
|
const orderB = availableBadges.findIndex(badge => badge.id === b.id);
|
||||||
|
|
||||||
|
const finalOrderA = orderA === -1 ? 9999 : orderA;
|
||||||
|
const finalOrderB = orderB === -1 ? 9999 : orderB;
|
||||||
|
|
||||||
|
return finalOrderA - finalOrderB;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
...userProfile,
|
||||||
|
badges: newBadges
|
||||||
|
};
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if (originalGetUserProfile) {
|
||||||
|
UserProfileStore.getUserProfile = originalGetUserProfile;
|
||||||
|
}
|
||||||
|
userBadgesMap.clear();
|
||||||
|
removedBadgesMap.clear();
|
||||||
|
},
|
||||||
|
|
||||||
|
contextMenus: {
|
||||||
|
"user-context"(children, { user }) {
|
||||||
|
if (!user) return;
|
||||||
|
|
||||||
|
const currentUserBadges = getUserBadges(user.id);
|
||||||
|
const userProfile = originalGetUserProfile ? originalGetUserProfile.call(UserProfileStore, user.id) : UserProfileStore.getUserProfile(user.id);
|
||||||
|
const actualBadges = userProfile?.badges || [];
|
||||||
|
|
||||||
|
children.push(
|
||||||
|
<Menu.MenuItem
|
||||||
|
label="Add Badge"
|
||||||
|
key="add-custom-badge"
|
||||||
|
id="user-context-add-custom"
|
||||||
|
color="brand"
|
||||||
|
action={() => addUserBadge(user.id)}
|
||||||
|
/>,
|
||||||
|
<Menu.MenuItem
|
||||||
|
label="Manage Badges"
|
||||||
|
key="custom-badges"
|
||||||
|
id="user-context-custom-badges"
|
||||||
|
>
|
||||||
|
{availableBadges.map(badge => {
|
||||||
|
const hasUserBadge = currentUserBadges.find(b => b.id === badge.id);
|
||||||
|
const hasActualBadge = actualBadges.find(b => b.id === badge.id);
|
||||||
|
const isHidden = isRealBadgeHidden(user.id, badge.id);
|
||||||
|
const isChecked = !!hasUserBadge || (!!hasActualBadge && !isHidden);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Menu.MenuCheckboxItem
|
||||||
|
key={badge.id}
|
||||||
|
id={`badge-${badge.id}`}
|
||||||
|
// label={
|
||||||
|
// <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
|
||||||
|
// <img
|
||||||
|
// src={`https://cdn.discordapp.com/badge-icons/${badge.icon}.png`}
|
||||||
|
// alt=""
|
||||||
|
// width="18"
|
||||||
|
// height="18"
|
||||||
|
// style={{
|
||||||
|
// borderRadius: "3px",
|
||||||
|
// imageRendering: "crisp-edges"
|
||||||
|
// }}
|
||||||
|
// />
|
||||||
|
// <span>{badge.title}</span>
|
||||||
|
// </div>
|
||||||
|
// }
|
||||||
|
label={badge.title}
|
||||||
|
checked={isChecked}
|
||||||
|
action={() => toggleBadge(user.id, badge, !!hasActualBadge)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
<Menu.MenuSeparator />
|
||||||
|
<Menu.MenuItem
|
||||||
|
label="Give All Badges"
|
||||||
|
id="give-all-badges"
|
||||||
|
color="brand"
|
||||||
|
action={() => giveAllBadges(user.id)}
|
||||||
|
/>
|
||||||
|
<Menu.MenuItem
|
||||||
|
label="Remove All Badges"
|
||||||
|
id="remove-all-badges"
|
||||||
|
color="danger"
|
||||||
|
action={() => {
|
||||||
|
actualBadges.forEach(badge => {
|
||||||
|
hideRealBadge(user.id, badge.id);
|
||||||
|
});
|
||||||
|
userBadgesMap.delete(user.id);
|
||||||
|
|
||||||
|
Toasts.show({
|
||||||
|
message: "Removed all badges",
|
||||||
|
type: Toasts.Type.SUCCESS,
|
||||||
|
id: Toasts.genId()
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Menu.MenuItem
|
||||||
|
label="Reset to Original"
|
||||||
|
id="reset-badges"
|
||||||
|
color="default"
|
||||||
|
action={() => {
|
||||||
|
userBadgesMap.delete(user.id);
|
||||||
|
removedBadgesMap.delete(user.id);
|
||||||
|
|
||||||
|
Toasts.show({
|
||||||
|
message: "Reset badges to original state",
|
||||||
|
type: Toasts.Type.SUCCESS,
|
||||||
|
id: Toasts.genId()
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Menu.MenuItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
35
bestPluginEVER/components/IdiotWarning.tsx
Normal file
35
bestPluginEVER/components/IdiotWarning.tsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2025 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Message } from "@vencord/discord-types";
|
||||||
|
import { Text } from "@webpack/common";
|
||||||
|
|
||||||
|
export const IDIOT_REGEX: RegExp[] = [
|
||||||
|
/\b((s+i+x+ s+e+v+e+n+)|(67))\b/i,
|
||||||
|
/skibidi ?(toilets?)?/i,
|
||||||
|
/united kingdom/i,
|
||||||
|
/hitler/i,
|
||||||
|
/we ?are ?charlie ?kirk/i,
|
||||||
|
/darktru/i
|
||||||
|
];
|
||||||
|
|
||||||
|
export function IdiotWarning({
|
||||||
|
message,
|
||||||
|
}: {
|
||||||
|
message: Message;
|
||||||
|
}) {
|
||||||
|
for (const idiot of IDIOT_REGEX) {
|
||||||
|
if (idiot.test(message.content)) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Text color="text-danger" variant="text-xs/semibold">
|
||||||
|
⚠️ This message is stupid.
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
bestPluginEVER/components/VeryCool.tsx
Normal file
30
bestPluginEVER/components/VeryCool.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2025 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Button } from "@components/Button";
|
||||||
|
import { Message } from "@vencord/discord-types";
|
||||||
|
|
||||||
|
export const COOL_REGEX: RegExp[] = [
|
||||||
|
/vencord/i,
|
||||||
|
];
|
||||||
|
|
||||||
|
export function VeryCool({
|
||||||
|
message,
|
||||||
|
}: {
|
||||||
|
message: Message;
|
||||||
|
}) {
|
||||||
|
for (const idiot of COOL_REGEX) {
|
||||||
|
if (idiot.test(message.content)) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button type="button" variant="link" onClick={a => open("roblox://")}>
|
||||||
|
secret :3
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
50
bestPluginEVER/index.tsx
Normal file
50
bestPluginEVER/index.tsx
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2025 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { addMessageAccessory, removeMessageAccessory } from "@api/MessageAccessories";
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
import { Message } from "@vencord/discord-types";
|
||||||
|
|
||||||
|
import { IdiotWarning } from "./components/IdiotWarning";
|
||||||
|
import { VeryCool } from "./components/VeryCool";
|
||||||
|
|
||||||
|
function BigWarning({
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
message: Message;
|
||||||
|
}) {
|
||||||
|
return <>
|
||||||
|
<IdiotWarning message={message} />
|
||||||
|
<VeryCool message={message} />
|
||||||
|
</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "BestPluginEver",
|
||||||
|
description: "Haha funny",
|
||||||
|
authors: [{
|
||||||
|
name: "ocbwoy3",
|
||||||
|
id: 486147449703104523n
|
||||||
|
}],
|
||||||
|
|
||||||
|
start() {
|
||||||
|
addMessageAccessory(
|
||||||
|
"BigWarning",
|
||||||
|
(props: Record<string, any>) => {
|
||||||
|
return (
|
||||||
|
<BigWarning
|
||||||
|
message={props.message as Message}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
4
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
removeMessageAccessory("BigWarning");
|
||||||
|
}
|
||||||
|
});
|
||||||
135
deltaruneProphecy/index.tsx
Normal file
135
deltaruneProphecy/index.tsx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2025 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { addMessageAccessory, removeMessageAccessory } from "@api/MessageAccessories";
|
||||||
|
import { Button } from "@components/Button";
|
||||||
|
import { Logger } from "@utils/Logger";
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
import { Message } from "@vencord/discord-types";
|
||||||
|
|
||||||
|
function SealDarkFountainDecoration({
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
message: Message;
|
||||||
|
}) {
|
||||||
|
if (/dark (fountain|world)/gi.test(message.content) && /(delta(rune|goon))|prophecy/gi.test(message.content) || /^(hop|get) on deltarune/i.test(message.content.toLowerCase())) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button type="button" variant="link" onClick={a => open("steam://rungameid/1671210")}>
|
||||||
|
Seal Fountain
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "DeltaruneProphecy",
|
||||||
|
description: "The Legend of Light and Dark. More Kromer!",
|
||||||
|
authors: [{
|
||||||
|
name: "ocbwoy3",
|
||||||
|
id: 486147449703104523n
|
||||||
|
}],
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: "#{intl::LOADING_DID_YOU_KNOW}",
|
||||||
|
replacement: [
|
||||||
|
{
|
||||||
|
match: /"_loadingText".+?(?=(\i)\[.{0,10}\.random)/,
|
||||||
|
replace: "$&$self.mutateQuotes($1),"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /"_eventLoadingText".+?(?=(\i)\[.{0,10}\.random)/,
|
||||||
|
replace: "$&$self.mutateQuotes($1),",
|
||||||
|
predicate: () => true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: "data-testid\":\"app-spinner\"",
|
||||||
|
replacement: {
|
||||||
|
match: /children:\s*\w+/,
|
||||||
|
replace: `
|
||||||
|
children:[
|
||||||
|
(0,r.jsx)("source",{alt:"",src:"https://files.catbox.moe/a5xk7y.webm"},"webm")
|
||||||
|
]
|
||||||
|
`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: "let a=JSON.parse('{\"",
|
||||||
|
replacement: [
|
||||||
|
{
|
||||||
|
match: /Find or start a conversation/gi,
|
||||||
|
replace: "Find or open a Dark Fountain"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /"Active Now"/gi,
|
||||||
|
replace: "\"Sealing the Fountain right now...\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /Discord Orbs Terms/gi,
|
||||||
|
replace: "Kromer Terms"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /Discord Orbs/gi,
|
||||||
|
replace: "Kromer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /Earn through Quests/gi,
|
||||||
|
replace: "Earn by opening Dark Fountains"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /Explore Orbs Exclusives/gi,
|
||||||
|
replace: "Explore Dark World Exclusives"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /Orbs/gi,
|
||||||
|
replace: "Kromer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /Mutual Servers/gi,
|
||||||
|
replace: "Mutual Dark Worlds"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /\b(Member)(s)?\b/g,
|
||||||
|
replace: "Darkner$2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /"Mutual Friends"/g,
|
||||||
|
replace: "\"Mutual Darkners\""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
mutateQuotes(quotes: string[]) {
|
||||||
|
try {
|
||||||
|
quotes.length = 0;
|
||||||
|
quotes.push("THE LEGEND OF THIS WORLD.\n< DELTARUNE. >");
|
||||||
|
} catch (e) {
|
||||||
|
new Logger("DeltaruneProphecy").error("Failed to mutate quotes", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
start() {
|
||||||
|
addMessageAccessory(
|
||||||
|
"sealFountainButton",
|
||||||
|
(props: Record<string, any>) => {
|
||||||
|
return (
|
||||||
|
<SealDarkFountainDecoration
|
||||||
|
message={props.message as Message}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
4
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
removeMessageAccessory("sealFountainButton");
|
||||||
|
}
|
||||||
|
});
|
||||||
41
nsfwGateBypass.ts
Normal file
41
nsfwGateBypass.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a modification for Discord's desktop app
|
||||||
|
* Copyright (c) 2025 Vendicated and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Devs } from "@utils/constants";
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "NSFWGateBypass",
|
||||||
|
description: "Bypasses Age Verification",
|
||||||
|
authors: [Devs.Commandtechno],
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: ".nsfwAllowed=null",
|
||||||
|
replacement: [
|
||||||
|
{
|
||||||
|
match: /(?<=\.nsfwAllowed=)null!=.+?(?=[,;])/,
|
||||||
|
replace: "true", // true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /(?<=\.ageVerificationStatus=)null!=.+?(?=[,;])/,
|
||||||
|
replace: "3", // 3=VERIFIED_ADULT
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
20
trustMeBro.ts
Normal file
20
trustMeBro.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2025 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "TrustMeBro",
|
||||||
|
description: "Bypasses Discord’s age verification required under the UK Online Safety Act.",
|
||||||
|
authors: [{ name: "Menhera.st Team", id: 1325012503419420734n }],
|
||||||
|
|
||||||
|
start() {
|
||||||
|
const modules = Object.values((window as any).webpackChunkdiscord_app.push([[Symbol()], {}, (r: any) => r.c])) as any[];
|
||||||
|
const userStore = modules.find((x: any) => x?.exports?.default?.getCurrentUser);
|
||||||
|
const currentUser = userStore.exports.default.getCurrentUser();
|
||||||
|
currentUser.ageVerificationStatus = 3;
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user