userinfo: nameplates

This commit is contained in:
Cynthia Foxwell 2025-07-16 16:01:11 -06:00
parent d45a3714b5
commit 96fd672ec8
Signed by: Cynosphere
SSH key fingerprint: SHA256:H3SM8ufP/uxqLwKSH7xY89TDnbR9uOHzjLoBr0tlajk
2 changed files with 94 additions and 5 deletions

View file

@ -1,3 +1,5 @@
const sharp = require("sharp");
const Command = require("#lib/command.js");
const InteractionCommand = require("#lib/interactionCommand.js");
@ -9,6 +11,7 @@ const {
BadgeURLs,
CDNEndpoints,
UserFlags,
NameplatePalettes,
} = require("#util/dconstants.js");
const {Icons} = require("#util/constants.js");
@ -69,6 +72,20 @@ async function fetchQuestData() {
questsFetch = Date.now() + 60 * 60 * 1000;
}
function nameplateBackground(color) {
return sharp(
Buffer.from(`<svg viewBox="0 0 448 84" width="448" height="84" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="nameplate">
<stop offset="0%" stop-color="${color}1A" />
<stop offset="100%" stop-color="${color}66" />
</linearGradient>
</defs>
<rect x="0" y="0" width="448" height="84" fill="url('#nameplate')"/>
</svg>`)
);
}
const userinfo = new Command("userinfo");
userinfo.category = "utility";
userinfo.helpText = "Get information on a user";
@ -346,10 +363,11 @@ userinfo.callback = async function (msg, line) {
`# ${member?.nick ? member.nick : user.global_name ?? user.username} ${
user.bot ? Icons.boat.replace(":i:", ":Bot:") : ""
}`,
`${formatUsername(user).replace("@", "")} \u2022 <@${id}>`,
];
let subline = `${formatUsername(user).replace("@", "")} \u2022 <@${id}>`;
let subline = "";
if (badges.length > 0) {
subline += "\u2007" + badges.join("");
subline += badges.join("");
}
const activityLines = [];
@ -365,7 +383,7 @@ userinfo.callback = async function (msg, line) {
}
if (icons.length > 0) {
subline += "\u2007" + icons.join("");
subline += (subline !== "" ? "\u2007" : "") + icons.join("");
}
if (anyMember.activities?.length > 0) {
@ -395,7 +413,7 @@ userinfo.callback = async function (msg, line) {
}
}
}
descLines.push(subline);
if (subline !== "") descLines.push(subline);
if (shared.length > 0) {
descLines.push(`-# ${shared.length} Bot Mutual Server${shared.length > 1 ? "s" : ""}`);
} else {
@ -481,8 +499,65 @@ userinfo.callback = async function (msg, line) {
},
};
let nameplateEmbed;
const files = [];
if (user.collectibles?.nameplate) {
const {nameplate} = user.collectibles;
const palette = NameplatePalettes[nameplate.palette];
const nameplateSku = await hf.bot.requestHandler
.request("GET", APIEndpoints.STORE_PUBLISHED_LISTING(nameplate.sku_id), true)
.catch(() => {});
const baseUrl = `https://cdn.discordapp.com/assets/collectibles/${nameplate.asset}`;
let imageUrl = baseUrl + "/static.png";
if (palette) {
try {
const static = await fetch(imageUrl)
.then((res) => res.arrayBuffer())
.then((b) => Buffer.from(b));
const bg_light = nameplateBackground(palette.lightBackground);
bg_light.composite([{input: static}]);
const bg_dark = nameplateBackground(palette.darkBackground);
bg_dark.composite([{input: static}]);
const final = sharp({create: {width: 448, height: 168, channels: 4, background: "transparent"}});
final.composite([
{input: await bg_light.toBuffer(), gravity: "north"},
{input: await bg_dark.toBuffer(), gravity: "south"},
]);
files.push({
contents: await final.png().toBuffer(),
name: "nameplate.png",
});
imageUrl = "attachment://nameplate.png";
} catch {
// noop
}
}
nameplateEmbed = {
color: palette?.lightBackground ? parseInt(palette.lightBackground.replace("#", "0x")) : embed.color,
title: nameplateSku?.sku?.name ?? "*Unknown*",
author: {name: "Nameplate"},
url: `https://discord.com/shop#itemSkuId=${nameplate.sku_id}`,
fields: [
{name: "Palette", value: nameplate.palette, inline: true},
{name: "Light Background", value: palette?.lightBackground ?? "*Unknown*", inline: true},
{name: "Dark Background", value: palette?.darkBackground ?? "*Unknown*", inline: true},
{
name: "\u200b",
value: `[PNG](${baseUrl}/static.png)\u3000[WebM](${baseUrl}/asset.webm)\u3000[APNG](${baseUrl}/img.png)`,
inline: false,
},
],
image: {url: imageUrl},
};
}
return {
embeds: [embed],
embeds: [embed, nameplateEmbed].filter((x) => !!x),
files,
};
};
hf.registerCommand(userinfo);

View file

@ -173,6 +173,20 @@ module.exports.HangStatusStrings = {
watching: "Watchin' stuff",
};
module.exports.NameplatePalettes = {
crimson: {darkBackground: "#900007", lightBackground: "#E7040F", name: "crimson"},
berry: {darkBackground: "#893A99", lightBackground: "#B11FCF", name: "berry"},
sky: {darkBackground: "#0080B7", lightBackground: "#56CCFF", name: "sky"},
teal: {darkBackground: "#086460", lightBackground: "#7DEED7", name: "teal"},
forest: {darkBackground: "#2D5401", lightBackground: "#6AA624", name: "forest"},
bubble_gum: {darkBackground: "#DC3E97", lightBackground: "#F957B3", name: "bubble_gum"},
violet: {darkBackground: "#730BC8", lightBackground: "#972FED", name: "violet"},
cobalt: {darkBackground: "#0131C2", lightBackground: "#4278FF", name: "cobalt"},
clover: {darkBackground: "#047B20", lightBackground: "#63CD5A", name: "clover"},
lemon: {darkBackground: "#F6CD12", lightBackground: "#FED400", name: "lemon"},
white: {darkBackground: "#FFFFFF", lightBackground: "#FFFFFF", name: "white"},
};
module.exports.UPLOAD_LIMIT = 26214400;
module.exports.UPLOAD_LIMIT_TIER_2 = 52428800;
module.exports.UPLOAD_LIMIT_TIER_3 = 104857600;