const Command = require("../lib/command.js"); const CATEGORY = "utility"; // {{{ imports const sharp = require("sharp"); const { formatTime, hastebin, lookupUser, formatUsername, safeString, } = require("../lib/utils.js"); const {getNamesFromString} = require("../lib/unicode.js"); const GameData = require("../../data/games.json"); const EmojiData = require("../../data/emoji.json"); const EMOJI_NAMES = []; for (const emoji of EmojiData) { EMOJI_NAMES[emoji.char] = emoji.name.replace(/ /g, "_"); } // }}} // {{{ constants const CDN = "https://cdn.discordapp.com/"; const ICON_BASE = CDN + "icons/"; const AVATAR_BASE = CDN + "avatars/"; const SPLASH_BASE = CDN + "splashes/"; const BANNER_BASE = CDN + "banners/"; const EMOTE_BASE = CDN + "emojis/"; const CHANNEL_ICON_BASE = CDN + "channel-icons/"; const DEFAULT_GROUP_DM_AVATARS = [ "/assets/ee9275c5a437f7dc7f9430ba95f12ebd.png", "/assets/9baf45aac2a0ec2e2dab288333acb9d9.png", "/assets/7ba11ffb1900fa2b088cb31324242047.png", "/assets/f90fca70610c4898bc57b58bce92f587.png", "/assets/e2779af34b8d9126b77420e5f09213ce.png", "/assets/c6851bd0b03f1cca5a8c1e720ea6ea17.png", "/assets/f7e38ac976a2a696161c923502a8345b.png", "/assets/3cb840d03313467838d658bbec801fcd.png", ]; const CUSTOM_EMOTE_REGEX = /<(?:\u200b|&)?(a)?:(\w+):(\d+)>/; const NOWPLAYING_BAR_LENGTH = 30; const PRESENCE_ICONS = { desktop: { online: "<:desktop_online:1028887024670871552>", idle: "<:desktop_idle:1028887022938624033>", dnd: "<:desktop_dnd:1028887021848121364>", }, mobile: { online: "<:mobile_online:1028887017637036043>", idle: "<:mobile_idle:1028887019226669116>", dnd: "<:mobile_dnd:1028887020560449637>", }, web: { online: "<:web_online:1104972136730345552>", idle: "<:web_idle:1104972138735218729>", dnd: "<:web_dnd:1104972140685570150>", }, embedded: { online: "<:embedded_online:1104972131265167411>", idle: "<:embedded_idle:1104972132687024189>", dnd: "<:embedded_dnd:1104972134964543518>", }, }; const PRESENCE_TYPES = [ "Playing", "Streaming", "Listening to", "Watching", "Custom Status", "Competing in", ]; const USER_FLAGS = [ "STAFF", "PARTNER", "HYPESQUAD", "BUG_HUNTER_LEVEL_1", "MFA_SMS", "PREMIUM_PROMO_DISMISSED", "HYPESQUAD_ONLINE_HOUSE_1", "HYPESQUAD_ONLINE_HOUSE_2", "HYPESQUAD_ONLINE_HOUSE_3", "PREMIUM_EARLY_SUPPORTER", "TEAM_PSEUDO_USER", "", // leaked "SYSTEM", "HAS_UNREAD_URGENT_MESSAGES", "BUG_HUNTER_LEVEL_2", "UNDERAGE_DELETED", "VERIFIED_BOT", "VERIFIED_DEVELOPER", "CERTIFIED_MODERATOR", "BOT_HTTP_INTERACTIONS", "SPAMMER", "DISABLE_PREMIUM", "ACTIVE_DEVELOPER", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "HIGH_GLOBAL_RATE_LIMIT", // start admin panel leak aug 2022 "DELETED", "DISABLED_SUSPICIOUS_ACTIVITY", "SELF_DELETED", "PREMIUM_DISCRIMINATOR", "USED_DESKTOP_CLIENT", "USED_WEB_CLIENT", "USED_MOBILE_CLIENT", "DISABLED", undefined, "VERIFIED_EMAIL", // end admin panel leak aug 2022 "QUARANTINED", undefined, undefined, undefined, undefined, undefined, "COLLABORATOR", "RESTRICTED_COLLABORATOR", ]; // https://discord-userdoccers.vercel.app/resources/guild#guild-features const GUILD_FEATURES = { ACTIVITIES_ALPHA: {icon: "\u{1f680}"}, ACTIVITIES_EMPLOYEE: {icon: "\u{1f680}"}, ACTIVITIES_INTERNAL_DEV: {icon: "\u{1f680}"}, ANIMATED_BANNER: {icon: "\u{1f39e}"}, ANIMATED_ICON: {icon: "\u{1f39e}"}, APPLICATION_COMMAND_PERMISSIONS_V2: {icon: "\u2699\ufe0f"}, AUTO_MODERATION: {icon: "\u{1f6e1}"}, AUTOMOD_TRIGGER_KEYWORD_FILTER: {icon: "\u{1f6e1}"}, AUTOMOD_TRIGGER_ML_SPAM_FILTER: {icon: "\u{1f6e1}"}, AUTOMOD_TRIGGER_SPAM_LINK_FILTER: {icon: "\u{1f6e1}"}, AUTOMOD_TRIGGER_USER_PROFILE: {icon: "\u{1faaa}"}, BANNER: {icon: "\u{1f5bc}"}, BFG: {icon: "\u{1f388}", name: "BFG"}, BOOSTING_TIERS_EXPERIMENT_MEDIUM_GUILD: {icon: "\u{1f48e}"}, BOOSTING_TIERS_EXPERIMENT_SMALL_GUILD: {icon: "\u{1f48e}"}, BOT_DEVELOPER_EARLY_ACCESS: {icon: "\u{1f9ea}"}, BURST_REACTIONS: {icon: "\u2728", name: "Super Reactions"}, CHANNEL_BANNER: {icon: "\u{1f5bc}"}, CHANNEL_ICON_EMOJIS_GENERATED: {icon: "\u{1f603}"}, CHANNEL_HIGHLIGHTS: {icon: "\u{1f5c3}"}, CHANNEL_HIGHLIGHTS_DISABLED: {icon: "\u{1f6ab}"}, CLYDE_DISABLED: {icon: "\u{1f6ab}"}, CLYDE_ENABLED: {icon: "\u{1f916}"}, CLYDE_EXPERIMENT_ENABLED: {icon: "\u{1f9ea}"}, COMMERCE: {icon: "\u{1f6cd}"}, COMMUNITY: {icon: "\u{1f3d8}"}, COMMUNITY_CANARY: {icon: "\u{1f9ea}"}, COMMUNITY_EXP_LARGE_GATED: {icon: "\u{1f3d8}"}, COMMUNITY_EXP_LARGE_UNGATED: {icon: "\u{1f3d8}"}, COMMUNITY_EXP_MEDIUM: {icon: "\u{1f3d8}"}, CREATOR_ACCEPTED_NEW_TERMS: {icon: "\u2611\ufe0f"}, CREATOR_MONETIZABLE: {icon: "\u{1f4b0}"}, CREATOR_MONETIZABLE_DISABLED: {icon: "\u{1f6ab}"}, CREATOR_MONETIZABLE_PENDING_NEW_OWNER_ONBOARDING: {icon: "\u{1f4b1}"}, CREATOR_MONETIZABLE_PROVISIONAL: {icon: "\u{1f4b0}"}, CREATOR_MONETIZABLE_RESTRICTED: {icon: "\u26d4"}, CREATOR_MONETIZABLE_WHITEGLOVE: {icon: "\u{1f9ea}"}, CREATOR_MONETIZATION_APPLICATION_ALLOWLIST: {icon: "\u{1f4dc}"}, CREATOR_STORE_PAGE: {icon: "\u{1f6d2}"}, DEVELOPER_SUPPORT_SERVER: {icon: "\u2754"}, DISCOVERABLE: {icon: "\u{1f9ed}"}, DISCOVERABLE_DISABLED: {icon: "\u{1f6ab}"}, ENABLED_DISCOVERABLE_BEFORE: {icon: "\u{1f9ed}"}, EXPOSED_TO_ACTIVITIES_WTP_EXPERIMENT: {icon: "\u{1f9ea}"}, EXPOSED_TO_BOOSTING_TIERS_EXPERIMENT: {icon: "\u{1f9ea}"}, FEATURABLE: {icon: "\u{1f9ed}"}, FORCE_RELAY: {icon: "\u{1f4fb}"}, GUESTS_ENABLED: {icon: "\u{1f465}"}, GUILD_AUTOMOD_DEFAULT_LIST: {icon: "\u{1f6e1}"}, GUILD_COMMUNICATION_DISABLED_GUILDS: {icon: "\u{1f6d1}"}, GUILD_HOME_DEPRECATION_OVERRIDE: {icon: "\u{1f3da}"}, GUILD_HOME_OVERRIDE: {icon: "\u{1f3e0}"}, GUILD_HOME_TEST: {icon: "\u{1f9ea}"}, GUILD_MEMBER_VERIFICATION_EXPERIMENT: {icon: "\u{1f9ea}"}, GUILD_ONBOARDING: {icon: "\u{1f5f3}"}, GUILD_ONBOARDING_ADMIN_ONLY: {icon: "\u{1f5f3}"}, GUILD_ONBOARDING_EVER_ENABLED: {icon: "\u{1f5f3}"}, GUILD_ONBOARDING_HAS_PROMPTS: {icon: "\u{1f5f3}"}, GUILD_PRODUCTS: {icon: "\u{1f6cd}"}, GUILD_ROLE_SUBSCRIPTIONS: {icon: "\u{1f4b3}"}, GUILD_ROLE_SUBSCRIPTION_PURCHASE_FEEDBACK_LOOP: {icon: "\u{1f4b3}"}, GUILD_ROLE_SUBSCRIPTION_TIER_TEMPLATE: {icon: "\u{1f4b3}"}, GUILD_ROLE_SUBSCRIPTION_TRIALS: {icon: "\u{1f4b3}"}, GUILD_SERVER_GUIDE: {icon: "\u{1f9ae}"}, GUILD_WEB_PAGE_VANITY_URL: {icon: "\u{1f4c4}"}, HAD_EARLY_ACTIVITIES_ACCESS: {icon: "\u{1f680}"}, HAS_DIRECTORY_ENTRY: {icon: "\u{1faa7}"}, HIDE_FROM_EXPERIMENT_UI: {icon: "\u{1f9ea}"}, HUB: {icon: "\u{1f3eb}"}, INCREASED_THREAD_LIMIT: {icon: "\u{1f9f5}"}, INTERNAL_EMPLOYEE_ONLY: {icon: "\u{1f6e0}"}, INVITE_SPLASH: {icon: "\u{1f5bc}"}, INVITES_DISABLED: {icon: "\u26d4"}, LINKED_TO_HUB: {icon: "\u{1f3eb}"}, LURKABLE: {icon: "\u{1f441}"}, MARKETPLACES_CONNECTION_ROLES: {icon: "\u{1f517}"}, MEDIA_CHANNEL_ALPHA: {icon: "\u{1f5bc}"}, MEMBER_LIST_DISABLED: {icon: "\u{1f6ab}"}, MEMBER_PROFILES: {icon: "\u{1faaa}"}, MEMBER_SAFETY_PAGE_ROLLOUT: {icon: "\u{1f6e1}"}, MEMBER_VERIFICATION_GATE_ENABLED: {icon: "\u{1f6e1}"}, MEMBER_VERIFICATION_MANUAL_APPROVAL: {icon: "\u2705"}, MOBILE_WEB_ROLE_SUBSCRIPTION_PURCHASE_PAGE: {icon: "\u{1f4b3}"}, MONETIZATION_ENABLED: {icon: "\u{1f4b0}"}, MORE_EMOJI: {icon: "\u{1f603}"}, MORE_STICKERS: {icon: "\u{1f5bc}"}, NEWS: {icon: "\u{1f4f0}"}, NEW_THREAD_PERMISSIONS: {icon: "\u{1f9f5}"}, NON_COMMUNITY_RAID_ALERTS: {icon: "\u{1f6a8}"}, PARTNERED: {icon: "\u267e\ufe0f"}, PREMIUM_TIER_3_OVERRIDE: {icon: "\u{1f48e}"}, PREVIEW_ENABLED: {icon: "\u{1f441}"}, PRIVATE_THREADS: {icon: "\u{1f9f5}"}, PRODUCTS_AVAILABLE_FOR_PURCHASE: {icon: "\u{1f6cd}"}, PUBLIC: {icon: "\u{1f9ed}"}, PUBLIC_DISABLED: {icon: "\u{1f6ab}"}, RAID_ALERTS_DISABLED: {icon: "\u{1f6ab}"}, RAID_ALERTS_ENABLED: {icon: "\u{1f6a8}"}, RELAY_ENABLED: {icon: "\u{1f4fb}"}, RESTRICT_SPAM_RISK_GUILDS: {icon: "\u{1f6d1}"}, ROLE_ICONS: {icon: "\u{1f3f7}"}, ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE: {icon: "\u{1f4b3}"}, ROLE_SUBSCRIPTIONS_ENABLED: {icon: "\u{1f4b3}"}, ROLE_SUBSCRIPTIONS_ENABLED_FOR_PURCHASE: {icon: "\u{1f4b3}"}, SEVEN_DAY_THREAD_ARCHIVE: {icon: "\u{1f9f5}"}, SHARD: {icon: "\u{1f4a0}"}, SHARED_CANVAS_FRIENDS_AND_FAMILY_TEST: {icon: "\u{1f58c}"}, SOUNDBOARD: {icon: "\u{1f50a}"}, SUMMARIES_ENABLED: {icon: "\u{1f4da}"}, SUMMARIES_ENABLED_GA: { icon: "\u{1f4da}", name: "Summaries Enabled (General Access)", }, SUMMARIES_DISABLED_BY_USER: {icon: "\u26d4"}, SUMMARIES_ENABLED_BY_USER: {icon: "\u{1f4da}"}, SUMMARIES_LONG_LOOKBACK: {icon: "\u{1f5c2}"}, STAFF_LEVEL_COLLABORATOR_REQUIRED: {icon: "\u{1f6e0}"}, STAFF_LEVEL_RESTRICTED_COLLABORATOR_REQUIRED: {icon: "\u{1f6e0}"}, TEXT_IN_STAGE_ENABLED: {icon: "\u{1f5e8}"}, TEXT_IN_VOICE_ENABLED: {icon: "\u{1f5e8}"}, THREADS_ENABLED_TESTING: {icon: "\u{1f9f5}"}, THREADS_ENABLED: {icon: "\u{1f9f5}"}, THREAD_DEFAULT_AUTO_ARCHIVE_DURATION: {icon: "\u{1f9f5}"}, THREADS_ONLY_CHANNEL: {icon: "\u{1f5e8}", name: "Forum Channels"}, THREE_DAY_THREAD_ARCHIVE: {icon: "\u{1f9f5}"}, TICKETED_EVENTS_ENABLED: {icon: "\u{1f39f}"}, TICKETING_ENABLED: {icon: "\u{1f39f}"}, VANITY_URL: {icon: "\u{1f517}"}, VERIFIED: {icon: "\u2b50"}, VIP_REGIONS: {icon: "\u{1f399}"}, VOICE_CHANNEL_EFFECTS: {icon: "\u2728"}, VOICE_IN_THREADS: {icon: "\u{1f399}"}, WELCOME_SCREEN_ENABLED: {icon: "\u{1f44b}"}, }; const EMOJI_SETS = { blobs: { prefix: "https://cdn.jsdelivr.net/gh/googlefonts/noto-emoji@e456654119cc3a5f9bebb7bbd00512456f983d2d/svg/emoji_u", sep: "_", suffix: ".svg", }, noto: { prefix: "https://gitcdn.xyz/repo/googlefonts/noto-emoji/master/svg/emoji_u", sep: "_", suffix: ".svg", }, twemoji: { prefix: "https://twemoji.maxcdn.com/v/latest/svg/", sep: "-", suffix: ".svg", }, mustd: { prefix: "https://cdn.jsdelivr.net/gh/Mstrodl/mutant-standard-mirror@0435227d9d8c0d6a346c8ae4c12b08a5cdc37041/emoji/", sep: "-", suffix: ".svg", }, apple: { prefix: "https://intrnl.github.io/assetsEmoji/AppleColor/emoji_u", sep: "_", suffix: ".png", }, facebook: { prefix: "https://intrnl.github.io/assetsEmoji/facebook/emoji_u", sep: "_", suffix: ".png", }, }; EMOJI_SETS["noto-old"] = EMOJI_SETS.blobs; EMOJI_SETS.mutant = EMOJI_SETS.mustd; EMOJI_SETS.mutstd = EMOJI_SETS.mustd; EMOJI_SETS.ms = EMOJI_SETS.mustd; EMOJI_SETS.twitter = EMOJI_SETS.twemoji; EMOJI_SETS.fb = EMOJI_SETS.facebook; // }}} // {{{ commands const avatar = new Command("avatar"); avatar.category = CATEGORY; avatar.helpText = "Get avatar of a user"; avatar.usage = ""; avatar.callback = async function (msg, line, [user], {server, guild}) { if (server || guild) { if (!msg.guildID) { return "`--server/--guild` can only be used within guilds."; } else { const guild = msg.channel.guild || hf.bot.guilds.get(msg.guildID); const url = `${ICON_BASE}${guild.id}/${guild.icon}.${ guild.icon.startsWith("a_") ? "gif?size=1024&_=.gif" : "png?size=1024" }`; return { embeds: [ { title: "Server Icon", url, image: { url, }, }, ], }; } } else if (user) { const lookup = await lookupUser(msg, user); if ( lookup == "No results" || lookup == "Canceled" || lookup == "Request timed out" ) { return lookup; } else { let member = lookup; const guild = msg.channel.guild || hf.bot.guilds.get(msg.guildID); if (guild) { if (guild.members.has(lookup.id)) { member = guild.members.get(lookup.id); } else { const fetched = await guild.fetchMembers({ userIDs: [lookup.id], }); member = fetched[0]; } } const baseEmbed = { title: `Avatar for \`${formatUsername(member)}\``, }; const normalAvatar = member.user.avatar; const guildAvatar = member.avatar; const normalUrl = AVATAR_BASE + member.id + "/" + normalAvatar + "." + (normalAvatar.startsWith("a_") ? "gif?size=1024&_=.gif" : "png?size=1024"); const guildUrl = guildAvatar && "https://cdn.discordapp.com/guilds/" + guild.id + "/users/" + member.id + "/avatars/" + guildAvatar + "." + (guildAvatar.startsWith("a_") ? "gif?size=1024&_=.gif" : "png?size=1024"); baseEmbed.description = `[Normal avatar](${normalUrl})` + (guild && guildAvatar ? `\n[Guild avatar](${guildUrl})` : ""); baseEmbed.url = normalUrl; const guildEmbed = {...baseEmbed}; baseEmbed.image = {url: normalUrl}; guildEmbed.image = {url: guildUrl}; return { embeds: [baseEmbed, guildAvatar && guildEmbed].filter((x) => x != null), }; } } else { const guild = msg.channel.guild || hf.bot.guilds.get(msg.guildID); const baseEmbed = { title: `Avatar for \`${formatUsername(msg.author)}\``, }; const normalAvatar = msg.author.avatar; const guildAvatar = msg.member?.avatar; const normalUrl = AVATAR_BASE + msg.author.id + "/" + normalAvatar + "." + (normalAvatar.startsWith("a_") ? "gif?size=1024&_=.gif" : "png?size=1024"); const guildUrl = guildAvatar && "https://cdn.discordapp.com/guilds/" + guild.id + "/users/" + msg.author.id + "/avatars/" + guildAvatar + "." + (guildAvatar.startsWith("a_") ? "gif?size=1024&_=.gif" : "png?size=1024"); baseEmbed.description = `[Normal avatar](${normalUrl})` + (guild && guildAvatar ? `\n[Guild avatar](${guildUrl})` : ""); baseEmbed.url = normalUrl; const guildEmbed = {...baseEmbed}; baseEmbed.image = {url: normalUrl}; guildEmbed.image = {url: guildUrl}; return { embeds: [baseEmbed, guildAvatar && guildEmbed].filter((x) => x != null), }; } }; hf.registerCommand(avatar); const banner = new Command("banner"); banner.category = CATEGORY; banner.helpText = "Get banner of a user"; banner.usage = ""; banner.callback = async function (msg, line, [user], {server, guild}) { let id = msg.author.id; if (server || guild) { if (!msg.guildID) { return "`--server/--guild` can only be used within guilds."; } else { const guild = msg.channel.guild || hf.bot.guilds.get(msg.guildID); if (!guild.banner) return "This guild does not have a banner."; const url = `${BANNER_BASE}${guild.id}/${guild.banner}.${ guild.banner.startsWith("a_") ? "gif?size=1024&_=.gif" : "png?size=1024" }`; return { embeds: [ { title: "Server Banner", url, image: { url, }, }, ], }; } } else if (user) { const lookup = await lookupUser(msg, user); if ( lookup == "No results" || lookup == "Canceled" || lookup == "Request timed out" ) { return lookup; } else { id = lookup.id; } } const userObj = await hf.bot.requestHandler.request( "GET", "/users/" + id, true ); if (!userObj.banner) return "This user does not have a banner."; const url = `${BANNER_BASE}${userObj.id}/${userObj.banner}.${ userObj.banner.startsWith("a_") ? "gif?size=1024&_=.gif" : "png?size=1024" }`; return { embeds: [ { title: `Banner for \`${formatUsername(userObj)}\``, url, image: { url, }, }, ], }; }; hf.registerCommand(banner); const lookupinvite = new Command("lookupinvite"); lookupinvite.category = CATEGORY; lookupinvite.helpText = "Lookup an invite"; lookupinvite.usage = ""; lookupinvite.addAlias("linvite"); lookupinvite.callback = async function (msg, line) { if (!line || line == "") { return "No arguments passed."; } line = line.replace(/(https?:\/\/)?discord\.gg\//, ""); let bail = false; let error; let invite; try { invite = await hf.bot.requestHandler.request( "GET", `/invites/${line}?with_counts=true&with_expiration=true` ); } catch (err) { bail = true; error = err; } if (bail && error) { if (error.message.includes("Unknown Invite")) { return "Invite provided is not valid."; } else { return `:warning: Got error \`${safeString(error)}\``; } } if (!invite) return ":warning: No data returned."; if (invite.message) { if (invite.message == "Unknown Invite") { return "Invite provided is not valid."; } else { return `:warning: Got error \`${invite.code}: "${invite.message}"\``; } } else { const embed = { title: `Invite Info: \`${invite.code}\``, description: invite.description, fields: [], }; const expires = { name: "Expires", value: invite.expires_at == null ? "Never" : ``, inline: true, }; const inviter = invite.inviter ? { name: "Inviter", value: `**${formatUsername(invite.inviter)}** (${invite.inviter.id})`, inline: false, } : null; const features = invite.guild.features.sort().map( (feature) => (GUILD_FEATURES[feature]?.icon ?? "\u2753") + " " + (GUILD_FEATURES[feature]?.name ?? feature .split("_") .map((x) => x[0] + x.substring(1).toLowerCase()) .join(" ")) ); if (invite.type == 0) { embed.fields.push( ...[ { name: "Guild", value: `**${invite.guild.name}** (${invite.guild.id})`, inline: true, }, { name: "Channel", value: `**${invite.channel.name}** (${invite.channel.id})`, inline: true, }, { name: "Boosts", value: invite.guild.premium_subscription_count ?? 0, inline: true, }, expires, { name: "Member Count", value: `<:online:1152111668856361010>${invite.approximate_presence_count} online\t\t<:offline:1152111682886316042>${invite.approximate_member_count} members`, inline: false, }, inviter, invite.guild.welcome_screen && { name: "Welcome Screen", value: `"${ invite.guild.welcome_screen.description }"\n${invite.guild.welcome_screen.welcome_channels .map( (c) => `${ c.emoji_id ? `[:${c.emoji_name}:](${EMOTE_BASE}${c.emoji_id}.webp)` : c.emoji_name } ${c.description} \`(${c.channel_id})\`` ) .join("\n")}`, inline: false, }, { name: "Features", value: features.length > 0 ? features.slice(0, Math.ceil(features.length / 2)).join("\n") : "None", inline: true, }, features.length > 1 ? { name: "\u200b", value: features .slice(Math.ceil(features.length / 2), features.length) .join("\n"), inline: true, } : null, ].filter((x) => !!x) ); embed.thumbnail = { url: invite.guild.icon && `${ICON_BASE}${invite.guild.id}/${invite.guild.icon}.${ invite.guild.icon.startsWith("a_") ? "gif?size=1024&_=.gif" : "png?size=1024" }`, }; if ( invite.guild && (invite.guild.icon || invite.guild.splash || invite.guild.banner) ) { embed.fields.push({ name: "\u200b", value: `${ invite.guild.icon ? `[Icon](${ICON_BASE}${invite.guild.id}/${invite.guild.icon}.${ invite.guild.icon.startsWith("a_") ? "gif?size=1024" : "png?size=1024" })` : "" }${ invite.guild.splash ? `${invite.guild.icon ? " | " : ""}[Splash](${SPLASH_BASE}${ invite.guild.id }/${invite.guild.splash}.png?size=2048)` : "" }${ invite.guild.banner ? `${ invite.guild.icon || invite.guild.splash ? " | " : "" }[Banner](${BANNER_BASE}${invite.guild.id}/${ invite.guild.banner }.${ invite.guild.banner.startsWith("a_") ? "gif?size=1024" : "png?size=1024" })` : "" }`, inline: false, }); } if (invite.guild?.splash) { embed.image = { url: `${SPLASH_BASE}${invite.guild.id}/${invite.guild.splash}.png?size=256`, }; } } else if (invite.type == 1) { embed.title += " (Group DM)"; embed.fields.push( ...[ { name: "Channel", value: `**${ invite.channel.name ?? invite.channel.recipients .map((member) => member.username) .join(", ") }** (${invite.channel.id})`, inline: false, }, { name: "Member Count", value: `<:offline:1152111682886316042>${invite.approximate_member_count} members`, inline: true, }, expires, invite.channel.name != null && { name: "Recipients", value: invite.channel.recipients .map((member) => member.username) .join(", "), inline: false, }, inviter, ].filter((x) => !!x) ); const groupIcon = invite.channel.icon ? `${CHANNEL_ICON_BASE}${invite.channel.id}/${invite.channel.icon}.${ invite.channel.icon.startsWith("a_") ? "gif?size=1024&_=.gif" : "png?size=1024" }` : "https://discord.com" + DEFAULT_GROUP_DM_AVATARS[ (Math.floor(Number(invite.channel.id) / Math.pow(2, 22)) + 1420070400000) % DEFAULT_GROUP_DM_AVATARS.length ]; embed.thumbnail = { url: groupIcon, }; embed.fields.push({ name: "\u200b", value: `[Icon](${groupIcon})`, inline: false, }); } else if (invite.type == 2) { embed.title += " (Friend)"; embed.fields.push(expires, inviter); const avatarURL = invite.inviter?.avatar && `${AVATAR_BASE}${invite.inviter.id}/${invite.inviter.avatar}.${ invite.inviter.avatar.startsWith("a_") ? "gif?size=1024&_=.gif" : "png?size=1024" }`; if (avatarURL) { embed.thumbnail = { url: avatarURL, }; embed.fields.push({ name: "\u200b", value: `[Avatar](${avatarURL})`, inline: false, }); } } else { return `Unhandled invite type: \`${invite.type}\``; } return {embed}; } }; hf.registerCommand(lookupinvite); const snowflake = new Command("snowflake"); snowflake.category = CATEGORY; snowflake.helpText = "Converts a snowflake ID into readable time."; snowflake.usage = "<--twitter> [snowflake]"; snowflake.callback = function (msg, line, [snowflake], {twitter}) { const num = parseInt(snowflake); if (!isNaN(num)) { let binary = num.toString(2); binary = "0".repeat(64 - binary.length) + binary; const timestamp = parseInt(binary.substr(0, 42), 2) + (twitter ? 1288834974657 : 1420070400000); return `The timestamp for \`${snowflake}\` is `; } else { return "Argument provided is not a number."; } }; hf.registerCommand(snowflake); function flagFromInt(int) { const bits = int.toString(2); const splitBits = bits.split("").reverse(); const reassignedBits = {}; for (const shift in splitBits) { reassignedBits[shift] = splitBits[shift]; } const flags = Object.keys(reassignedBits).filter( (bit) => reassignedBits[bit] == 1 ); let out = ""; for (const flag of flags) { out += (USER_FLAGS[flag] || "") + ` (1 << ${flag}, ${1n << BigInt(flag)})\n`; } return out; } const flagdump = new Command("flagdump"); flagdump.category = CATEGORY; flagdump.helpText = "Dumps Discord user flags."; flagdump.usage = "[flags or user mention]"; flagdump.callback = async function (msg, line, [numOrMention], {id, list}) { const num = Number(numOrMention); if (list) { let allFlags = 0n; for (const index in USER_FLAGS) { if (USER_FLAGS[index] == undefined) continue; allFlags += 1n << BigInt(index); } return `All flags:\n\`\`\`${flagFromInt(allFlags)}\`\`\``; } else if (/<@!?(\d+)>/.test(numOrMention) || !isNaN(id)) { const targetId = id || numOrMention.match(/<@!?(\d+)>/)?.[1]; if (!targetId) return "Got null ID."; const guild = msg.channel.guild || hf.bot.guilds.get(msg.guildID); let user = guild && (await guild.fetchMembers({userIDs: [targetId]})); if (!user || !user[0]) { user = hf.bot.users.get(id); } else { user = user[0].user; } if (!user) { return "User not cached."; } else { return `\`${formatUsername(user)}\`'s public flags:\n\`\`\`${flagFromInt( user.publicFlags )}\`\`\``; } } else if (!isNaN(num)) { return `\`\`\`\n${flagFromInt(num)}\`\`\``; } else { return `\`${formatUsername( msg.author )}\`'s public flags:\n\`\`\`${flagFromInt(msg.author.publicFlags)}\`\`\``; } }; hf.registerCommand(flagdump); const jumbo = new Command("jumbo"); jumbo.category = CATEGORY; jumbo.helpText = "Gets the raw image of an emoji."; jumbo.usage = ""; jumbo.addAlias("e"); jumbo.addAlias("emote"); jumbo.addAlias("emoji"); jumbo.callback = async function (msg, line) { if (CUSTOM_EMOTE_REGEX.test(line)) { const [_, animatedFlag, name, id] = line.match(CUSTOM_EMOTE_REGEX); const animated = animatedFlag === "a"; return { embeds: [ { title: `:${name}: - \`${id}\``, url: `${EMOTE_BASE}${id}.${animated ? "gif" : "png"}?v=1`, image: { url: `${EMOTE_BASE}${id}.${animated ? "gif" : "png"}?v=1`, }, }, ], }; } else { let setName = "twemoji"; for (const set in EMOJI_SETS) { if (line.startsWith(`--${set} `)) { setName = set; line = line.replace(`--${set} `, ""); } } const set = EMOJI_SETS[setName]; const emoji = Array.from(line) .map((char) => char.codePointAt().toString(16)) .join(set.sep); const url = set.prefix + emoji + set.suffix; const name = EMOJI_NAMES[line] ? `\\:${EMOJI_NAMES[line]}\\:` : await getNamesFromString(line).then((name) => name.map((x) => x[1]).join(", ") ); const emojiFound = await fetch(url, {method: "HEAD"}).then((res) => res.ok); if (emojiFound) { return "Emoji not found. The emoji set chosen might not have this emote as an image."; } if (set.suffix == ".svg") { const svg = await fetch(url) .then((res) => res.arrayBuffer()) .then((b) => Buffer.from(b)); const converted = await sharp(svg, {density: 2400}) .resize(1024) .toBuffer(); return { embeds: [ { title: `${name} (${emoji.toUpperCase().replace(/[-_]/g, ", ")})`, url, image: { url: "attachment://emoji.png", }, }, ], file: { file: converted, name: "emoji.png", }, }; } else { return { embeds: [ { title: `${name} (${emoji.toUpperCase().replace(/[-_]/g, ", ")})`, url, image: { url, }, }, ], }; } } }; hf.registerCommand(jumbo); const charinfo = new Command("charinfo"); charinfo.category = CATEGORY; charinfo.helpText = "Get information about a set of characters."; charinfo.usage = "[characters]"; charinfo.addAlias("char"); charinfo.callback = async function (msg, line) { const names = await getNamesFromString(line); const chars = [...line]; const lines = names .map( ([code, name], index) => `\`\\u${code}\`: ${name} - ${chars[index]} - ` ) .join("\n"); if (lines.length > 2000) { return "Output too long: " + (await hastebin(lines)); } else { return lines; } }; hf.registerCommand(charinfo); const presence = new Command("presence"); presence.category = CATEGORY; presence.helpText = "Get presences of a user."; presence.usage = ""; presence.addAlias("status"); presence.callback = async function (msg, line) { if (!msg.guildID) return "Can only be used in guilds."; let target; if (line) { const user = await lookupUser(msg, line); if ( user == "No results" || user == "Canceled" || user == "Request timed out" ) { return user; } else { let member = user; const guild = msg.channel.guild || hf.bot.guilds.get(msg.guildID); if (guild) { if (guild.members.has(user.id)) { member = guild.members.get(user.id); } else { const fetched = await guild.fetchMembers({ userIDs: [user.id], }); member = fetched[0]; } target = member; } } } else { target = msg.member; } if (target) { if (!target.clientStatus) return `**${formatUsername(target)}** is offline.`; const icons = []; for (const platform of Object.keys(target.clientStatus)) { const status = target.clientStatus[platform]; if (status == "offline") continue; icons.push(PRESENCE_ICONS[platform][status]); } const embeds = []; const files = []; for (const index in target.activities) { const activity = target.activities[index]; if (activity.type == 4) { const embed = {}; if (activity.emoji) { if (activity.emoji.id) { const url = `${EMOTE_BASE}${activity.emoji.id}.${ activity.emoji.animated ? "gif" : "png" }`; embed.author = { url, icon_url: url, name: activity.state ?? "\u200b", }; } else { embed.title = `${activity.emoji.name} ${activity.state ?? ""}`; } } else { embed.title = activity.state ?? ""; } embeds.push(embed); } else { const embed = { title: `${PRESENCE_TYPES[activity.type]} **${activity.name}**`, fields: [], }; const descLines = []; if (activity.type == 2) { if (activity.details) { let details = activity.details; if (activity.name == "Spotify" && activity.sync_id) { details = `[${details}](https://open.spotify.com/track/${activity.sync_id})`; } descLines.push(`**${details}**`); } if (activity.state) descLines.push(activity.state); if (activity.assets?.large_text) descLines.push(activity.assets.large_text); } else { if (activity.details) descLines.push(activity.details); if (activity.state) { let stateLine = activity.state; if (activity.party?.size) { stateLine += ` (${activity.party.size[0]} of ${activity.party.size[1]})`; } descLines.push(stateLine); } } if (activity.timestamps) { if (activity.timestamps.start && !activity.timestamps.end) { descLines.push( formatTime(Date.now() - activity.timestamps.start) + " elapsed" ); } else if (!activity.timestamps.start && activity.timestamps.end) { descLines.push( formatTime(activity.timestamps.end - Date.now()) + " remaining" ); } else if ( activity.timestamps.start != null && activity.timestamps.end != null ) { const position = Date.now() - activity.timestamps.start; const length = activity.timestamps.end - activity.timestamps.start; const timeEnd = formatTime(length); const timePos = formatTime(position); const progress = position >= length ? 1 : position / length; const barLength = Math.round(progress * NOWPLAYING_BAR_LENGTH); const bar = `\`[${"=".repeat(barLength)}${" ".repeat( NOWPLAYING_BAR_LENGTH - barLength )}]\``; const time = `\`${timePos}${" ".repeat( NOWPLAYING_BAR_LENGTH + 2 - timePos.length - timeEnd.length )}${timeEnd}\``; descLines.push(bar); descLines.push(time); } } if (activity.assets?.large_text && activity.type != 2) { embed.fields.push({ name: "Large Text", value: activity.assets.large_text, }); } if (activity.assets?.small_text) { embed.fields.push({ name: "Small Text", value: activity.assets.small_text, }); } embed.description = descLines.join("\n"); if (activity.assets) { if (activity.assets.large_image != null) { let largeUrl; if (activity.assets.large_image.startsWith("mp:")) { largeUrl = activity.assets.large_image.replace( "mp:", "https://media.discordapp.net/" ); } else if (activity.assets.large_image.startsWith("spotify:")) { largeUrl = activity.assets.large_image.replace( "spotify:", "https://i.scdn.co/image/" ); } else { largeUrl = `https://cdn.discordapp.com/app-assets/${activity.application_id}/${activity.assets.large_image}.png`; } let smallUrl; if (activity.assets.small_image != null) { if (activity.assets.small_image.startsWith("mp:")) { smallUrl = activity.assets.small_image.replace( "mp:", "https://media.discordapp.net/" ); } else { smallUrl = `https://cdn.discordapp.com/app-assets/${activity.application_id}/${activity.assets.small_image}.png`; } } const largeImage = await fetch(largeUrl) .then((res) => res.arrayBuffer()) .then((b) => Buffer.from(b)); const presenceImage = sharp(largeImage).resize(60, 60); if (smallUrl) { const smallImage = await fetch(smallUrl) .then((res) => res.arrayBuffer()) .then((b) => Buffer.from(b)); const smallImageBuffer = await sharp(smallImage) .resize(20, 20) .toBuffer(); presenceImage.composite([ { input: smallImageBuffer, gravity: "southeast", }, ]); } files.push({ contents: await presenceImage.toBuffer(), name: `${index}.png`, }); embed.thumbnail = { url: `attachment://${index}.png`, }; } else if ( !activity.assets.large_image && activity.assets.small_image != null ) { let smallUrl; if (activity.assets.small_image.startsWith("mp:")) { smallUrl = activity.assets.small_image.replace( "mp:", "https://media.discordapp.net/" ); } else { smallUrl = `https://cdn.discordapp.com/app-assets/${activity.application_id}/${activity.assets.small_image}.png`; } const smallImage = await fetch(smallUrl) .then((res) => res.arrayBuffer()) .then((b) => Buffer.from(b)); const presenceImage = await sharp(smallImage) .resize(60, 60) .toBuffer(); files.push({ contents: presenceImage, name: `${index}.png`, }); embed.thumbnail = { url: `attachment://${index}.png`, }; } } if ( activity.application_id && !activity.assets?.large_image && !activity.assets?.small_image ) { const game = GameData.find( (game) => game.id == activity.application_id ); if (game?.icon) { embed.thumbnail = { url: `https://cdn.discordapp.com/app-icons/${game.id}/${game.icon}.png?size=40&keep_aspect_ratio=false`, }; } } embeds.push(embed); } } return { content: `Presence for **${formatUsername(target)}**: ${icons.join(" ")}`, embeds, files, }; } else { return ":warning: Could not get user???"; } }; hf.registerCommand(presence); const POMELO_REGEX = /^[a-z0-9._]{1,32}$/; const pomelo = new Command("pomelo"); pomelo.category = CATEGORY; pomelo.helpText = "Check to see if a username is taken or not"; pomelo.usage = "[username] <...username>"; pomelo.callback = async function (msg, line) { if (!line || line === "") return "Arguments required."; const usernames = line.toLowerCase().split(" "); if (usernames.length == 1) { const name = usernames[0]; if (name.length > 32 || !POMELO_REGEX.test(name)) return {reaction: "\u{1f6ab}"}; const res = await hf.bot.requestHandler.request( "POST", "/unique-username/username-attempt-unauthed", false, {username: name} ); return {reaction: res.taken ? "\u274c" : "\u2705"}; } else { const lines = []; for (const name of usernames) { if (name.length > 32 || !POMELO_REGEX.test(name)) { lines.push(`\u{1f6ab} \`${name}\``); } else { try { const res = await hf.bot.requestHandler.request( "POST", "/unique-username/username-attempt-unauthed", false, {username: name} ); lines.push(`${res.taken ? "\u274c" : "\u2705"} \`${name}\``); } catch { lines.push(`\u26a0\ufe0f \`${name}\``); } } } return lines.join("\n"); } }; hf.registerCommand(pomelo); // }}}