diff options
Diffstat (limited to 'src/commands')
-rw-r--r-- | src/commands/moulberry-bush/neuRepo.ts | 153 |
1 files changed, 149 insertions, 4 deletions
diff --git a/src/commands/moulberry-bush/neuRepo.ts b/src/commands/moulberry-bush/neuRepo.ts index 24f83ad..9d76810 100644 --- a/src/commands/moulberry-bush/neuRepo.ts +++ b/src/commands/moulberry-bush/neuRepo.ts @@ -1,5 +1,16 @@ import { BushCommand, clientSendAndPermCheck, type ArgType, type CommandMessage, type SlashMessage } from '#lib'; -import { ApplicationCommandOptionType, AutocompleteInteraction, CacheType, PermissionFlagsBits } from 'discord.js'; +import canvas from 'canvas'; +import { + ApplicationCommandOptionType, + AttachmentBuilder, + AutocompleteInteraction, + CacheType, + PermissionFlagsBits +} from 'discord.js'; +import { dirname, join } from 'path'; +import tinycolor from 'tinycolor2'; +import { fileURLToPath } from 'url'; +import { formattingInfo, RawNeuItem } from '../../lib/common/util/Minecraft.js'; export default class NeuRepoCommand extends BushCommand { public static items: { name: string; id: string }[] = []; @@ -34,14 +45,148 @@ export default class NeuRepoCommand extends BushCommand { ], slash: true, clientPermissions: (m) => clientSendAndPermCheck(m, [PermissionFlagsBits.EmbedLinks], true), - userPermissions: [] + userPermissions: [], + ownerOnly: true }); } public override async exec( message: CommandMessage | SlashMessage, args: { item: ArgType<'string'> /* dangerous: ArgType<'flag'> */ } - ) {} + ) { + const itemPath = join(import.meta.url, '..', '..', '..', '..', '..', 'neu-item-repo-dangerous', 'items', `${args.item}.json`); + const item = (await import(itemPath, { assert: { type: 'json' } })).default as RawNeuItem; - public override async autocomplete(interaction: AutocompleteInteraction<CacheType>) {} + const toolTip = this.toolTip(item); + + return message.util.reply({ + files: [new AttachmentBuilder(toolTip, { name: `${item.internalname}.png`, description: item.displayname })] + }); + } + + public toolTip(item: RawNeuItem): Buffer { + canvas.registerFont(join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..', '..', 'assets', 'Faithful.ttf'), { + family: 'Faithful' + }); + + const background = '#100010'; + + const width = 250; + const height = 250; + const scale = 10; + + const itemRender = canvas.createCanvas(width, height), + ctx = itemRender.getContext('2d'); + + ctx.globalAlpha = 0.94; + ctx.fillStyle = background; + + // top outside + ctx.fillRect(scale, 0, width - 2 * scale, scale); + + // bottom outside + ctx.fillRect(scale, height - scale, width - 2 * scale, scale); + + // left outside + ctx.fillRect(0, scale, scale, height - 2 * scale); + + // right outside + ctx.fillRect(width - scale, scale, scale, height - 2 * scale); + + // middle + ctx.fillRect(2 * scale, 2 * scale, width - 4 * scale, height - 4 * scale); + + ctx.globalAlpha = 0.78; + + const borderColorStart = parseInt(new tinycolor(this.getPrimaryColour(item.displayname)).toHex(), 16); + const borderColorEnd = ((borderColorStart & 0xfefefe) >> 1) | (borderColorStart & 0xff000000); + + const borderColorStartStr = `#${borderColorStart.toString(16)}`; + const borderColorEndStr = `#${borderColorEnd.toString(16)}`; + + ctx.fillStyle = borderColorStartStr; + + // top highlight + ctx.fillRect(scale, scale, width - 2 * scale, scale); + + // left highlight + ctx.fillRect(scale, 2 * scale, scale, height - 3 * scale); + + // bottom highlight + { + const x = 2 * scale, + y = height - 2 * scale, + w = width - 3 * scale, + h = scale; + const gradient = ctx.createLinearGradient(x, y, x + w, y + h); + gradient.addColorStop(0, borderColorStartStr); + gradient.addColorStop(1, borderColorEndStr); + ctx.fillStyle = gradient; + + ctx.fillRect(x, y, w, h); + } + + // right highlight + { + const x = width - 2 * scale, + y = 2 * scale, + w = scale, + h = height - 4 * scale; + const gradient = ctx.createLinearGradient(x, y, x + w, y + h); + gradient.addColorStop(0, borderColorStartStr); + gradient.addColorStop(1, borderColorEndStr); + ctx.fillStyle = gradient; + + ctx.fillRect(x, y, w, h); + } + + item.displayname.split(''); + + return itemRender.toBuffer(); + } + + // stolen from NEU and modified + public getPrimaryColourCode(displayname: string): code { + let lastColourCode = -99; + let currentColour = 0; + const mostCommon = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (let i = 0; i < displayname.length; i++) { + const c = displayname.charAt(i); + if (c === '\u00A7') { + lastColourCode = i; + } else if (lastColourCode === i - 1) { + const colIndex = '0123456789abcdef'.indexOf(c); + if (colIndex >= 0) { + currentColour = colIndex; + } else { + currentColour = 0; + } + } else if ('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.indexOf(c) >= 0) { + if (currentColour > 0) { + mostCommon[currentColour] = mostCommon[currentColour]++; + } + } + } + let mostCommonCount = 0; + for (let index = 0; index < mostCommon.length; index++) { + if (mostCommon[index] > mostCommonCount) { + mostCommonCount = mostCommon[index]; + currentColour = index; + } + } + + return <code>'0123456789abcdef'.charAt(currentColour); + } + + // stolen from NEU and modified + public getPrimaryColour(displayname: string) { + const code = this.getPrimaryColourCode(displayname); + return formattingInfo[`§${code}`].foregroundDarker; + } + + public override async autocomplete(interaction: AutocompleteInteraction<CacheType>) { + return interaction.respond([{ name: 'Blazetekk™ Ham Radio', value: 'BLAZETEKK_HAM_RADIO' }]); + } } + +type code = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'; |