aboutsummaryrefslogtreecommitdiff
path: root/test.js
diff options
context:
space:
mode:
Diffstat (limited to 'test.js')
-rw-r--r--test.js365
1 files changed, 365 insertions, 0 deletions
diff --git a/test.js b/test.js
new file mode 100644
index 0000000..d0840ec
--- /dev/null
+++ b/test.js
@@ -0,0 +1,365 @@
+/* eslint-disable */
+// @ts-check
+
+import { createCanvas, registerFont } from 'canvas';
+import fs from 'fs/promises';
+import path, { dirname, join } from 'path';
+import tinycolor from 'tinycolor2';
+import { fileURLToPath } from 'url';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+registerFont(join(__dirname, 'assets', 'Faithful.ttf'), { family: 'ComplianceSans' });
+registerFont(join(dirname(fileURLToPath(import.meta.url)), 'assets', 'Roboto-Regular.ttf'), { family: 'Roboto' });
+
+/** @typedef {string} McItemId */
+/** @typedef {string} SbItemId */
+/** @typedef {string} MojangJson */
+/** @typedef {`${SbItemId}:${number}` | ''} SbRecipeItem */
+/** @typedef {{[Location in `${'A' | 'B' | 'C'}${1 | 2 | 3}`]: SbRecipeItem;}} SbRecipe */
+/** @typedef {'WIKI_URL' | ''} InfoType */
+/** @typedef {`${'WOLF' | 'BLAZE' | 'EMAN'}_${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}`} Slayer */
+/** @typedef {'0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'|'a'|'b'|'c'|'d'|'e'|'f'} code */
+/**
+ * @typedef RawNeuItem
+ * @property {McItemId} itemid
+ * @property {string} displayname
+ * @property {MojangJson} nbttag
+ * @property {number} damage
+ * @property {string[]} lore
+ * @property {SbRecipe} [recipe]
+ * @property {SbItemId} internalname
+ * @property {InfoType} infoType
+ * @property {string[]} [info]
+ * @property {string} crafttext
+ * @property {boolean} [vanilla]
+ * @property {boolean} [useneucraft]
+ * @property {Slayer} [slayer_req]
+ * @property {string} [clickcommand]
+ * @property {number} [x]
+ * @property {number} [y]
+ * @property {number} [z]
+ * @property {string} [island]
+ * @property {{ type: string; cost: any[]; result: SbItemId }[]} [recipes]
+ * @property {SbItemId} [parent]
+ * @property {boolean} [noseal]
+ */
+
+const FormattingCodes = {
+ Black: '§0',
+ DarkBlue: '§1',
+ DarkGreen: '§2',
+ DarkAqua: '§3',
+ DarkRed: '§4',
+ DarkPurple: '§5',
+ Gold: '§6',
+ Gray: '§7',
+ DarkGray: '§8',
+ Blue: '§9',
+ Green: '§a',
+ Aqua: '§b',
+ Red: '§c',
+ LightPurple: '§d',
+ Yellow: '§e',
+ White: '§f',
+
+ Obfuscated: '§k',
+ Bold: '§l',
+ Strikethrough: '§m',
+ Underline: '§n',
+ Italic: '§o',
+ Reset: '§r'
+};
+
+const formattingInfo = {
+ [FormattingCodes.Black]: {
+ foreground: 'rgb(0, 0, 0)',
+ foregroundDarker: 'rgb(0, 0, 0)',
+ background: 'rgb(0, 0, 0)',
+ backgroundDarker: 'rgb(0, 0, 0)',
+ ansi: '\u001b[0;30m'
+ },
+ [FormattingCodes.DarkBlue]: {
+ foreground: 'rgb(0, 0, 170)',
+ foregroundDarker: 'rgb(0, 0, 118)',
+ background: 'rgb(0, 0, 42)',
+ backgroundDarker: 'rgb(0, 0, 29)',
+ ansi: '\u001b[0;34m'
+ },
+ [FormattingCodes.DarkGreen]: {
+ foreground: 'rgb(0, 170, 0)',
+ foregroundDarker: 'rgb(0, 118, 0)',
+ background: 'rgb(0, 42, 0)',
+ backgroundDarker: 'rgb(0, 29, 0)',
+ ansi: '\u001b[0;32m'
+ },
+ [FormattingCodes.DarkAqua]: {
+ foreground: 'rgb(0, 170, 170)',
+ foregroundDarker: 'rgb(0, 118, 118)',
+ background: 'rgb(0, 42, 42)',
+ backgroundDarker: 'rgb(0, 29, 29)',
+ ansi: '\u001b[0;36m'
+ },
+ [FormattingCodes.DarkRed]: {
+ foreground: 'rgb(170, 0, 0)',
+ foregroundDarker: 'rgb(118, 0, 0)',
+ background: 'rgb(42, 0, 0)',
+ backgroundDarker: 'rgb(29, 0, 0)',
+ ansi: '\u001b[0;31m'
+ },
+ [FormattingCodes.DarkPurple]: {
+ foreground: 'rgb(170, 0, 170)',
+ foregroundDarker: 'rgb(118, 0, 118)',
+ background: 'rgb(42, 0, 42)',
+ backgroundDarker: 'rgb(29, 0, 29)',
+ ansi: '\u001b[0;35m'
+ },
+ [FormattingCodes.Gold]: {
+ foreground: 'rgb(255, 170, 0)',
+ foregroundDarker: 'rgb(178, 118, 0)',
+ background: 'rgb(42, 42, 0)',
+ backgroundDarker: 'rgb(29, 29, 0)',
+ ansi: '\u001b[0;33m'
+ },
+ [FormattingCodes.Gray]: {
+ foreground: 'rgb(170, 170, 170)',
+ foregroundDarker: 'rgb(118, 118, 118)',
+ background: 'rgb(42, 42, 42)',
+ backgroundDarker: 'rgb(29, 29, 29)',
+ ansi: '\u001b[0;37m'
+ },
+ [FormattingCodes.DarkGray]: {
+ foreground: 'rgb(85, 85, 85)',
+ foregroundDarker: 'rgb(59, 59, 59)',
+ background: 'rgb(21, 21, 21)',
+ backgroundDarker: 'rgb(14, 14, 14)',
+ ansi: '\u001b[0;90m'
+ },
+ [FormattingCodes.Blue]: {
+ foreground: 'rgb(85, 85, 255)',
+ foregroundDarker: 'rgb(59, 59, 178)',
+ background: 'rgb(21, 21, 63)',
+ backgroundDarker: 'rgb(14, 14, 44)',
+ ansi: '\u001b[0;94m'
+ },
+ [FormattingCodes.Green]: {
+ foreground: 'rgb(85, 255, 85)',
+ foregroundDarker: 'rgb(59, 178, 59)',
+ background: 'rgb(21, 63, 21)',
+ backgroundDarker: 'rgb(14, 44, 14)',
+ ansi: '\u001b[0;92m'
+ },
+ [FormattingCodes.Aqua]: {
+ foreground: 'rgb(85, 255, 255)',
+ foregroundDarker: 'rgb(59, 178, 178)',
+ background: 'rgb(21, 63, 63)',
+ backgroundDarker: 'rgb(14, 44, 44)',
+ ansi: '\u001b[0;96m'
+ },
+ [FormattingCodes.Red]: {
+ foreground: 'rgb(255, 85, 85)',
+ foregroundDarker: 'rgb(178, 59, 59)',
+ background: 'rgb(63, 21, 21)',
+ backgroundDarker: 'rgb(44, 14, 14)',
+ ansi: '\u001b[0;91m'
+ },
+ [FormattingCodes.LightPurple]: {
+ foreground: 'rgb(255, 85, 255)',
+ foregroundDarker: 'rgb(178, 59, 178)',
+ background: 'rgb(63, 21, 63)',
+ backgroundDarker: 'rgb(44, 14, 44)',
+ ansi: '\u001b[0;95m'
+ },
+ [FormattingCodes.Yellow]: {
+ foreground: 'rgb(255, 255, 85)',
+ foregroundDarker: 'rgb(178, 178, 59)',
+ background: 'rgb(63, 63, 21)',
+ backgroundDarker: 'rgb(44, 44, 14)',
+ ansi: '\u001b[0;93m'
+ },
+ [FormattingCodes.White]: {
+ foreground: 'rgb(255, 255, 255)',
+ foregroundDarker: 'rgb(178, 178, 178)',
+ background: 'rgb(63, 63, 63)',
+ backgroundDarker: 'rgb(44, 44, 44)',
+ ansi: '\u001b[0;97m'
+ },
+
+ [FormattingCodes.Obfuscated]: { ansi: '\u001b[8m' },
+ [FormattingCodes.Bold]: { ansi: '\u001b[1m' },
+ [FormattingCodes.Strikethrough]: { ansi: '\u001b[9m' },
+ [FormattingCodes.Underline]: { ansi: '\u001b[4m' },
+ [FormattingCodes.Italic]: { ansi: '\u001b[3m' },
+ [FormattingCodes.Reset]: { ansi: '\u001b[0m' }
+};
+
+/**
+ * stolen from NEU
+ * @param {string} displayname
+ * @returns {code}
+ */
+function getPrimaryColourCode(displayname) {
+ 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;
+ }
+ }
+
+ /** @type {code} */
+ // @ts-ignore
+ const code = '0123456789abcdef'.charAt(currentColour);
+ return code;
+}
+
+/**
+ * @param {number} decimal
+ */
+function decimalToHex(decimal) {
+ return decimal.toString(16).padStart(6, '0');
+}
+
+/**
+ * @param {RawNeuItem} item
+ * @returns {Buffer}
+ */
+function tooltip(item) {
+ const background = '#100010';
+
+ const width = 1920;
+ const height = 1080;
+ const scale = 10;
+
+ const itemRender = createCanvas(width, height),
+ ctx = itemRender.getContext('2d');
+
+ // ctx.fillStyle = '#000';
+ // ctx.fillRect(0, 0, width, height);
+
+ // 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(getPrimaryColour(item.displayname)).toHex(), 16);
+ const borderColorEnd = ((borderColorStart & 0xfefefe) >> 1) | (borderColorStart & 0xff000000);
+
+ const borderColorStartStr = `#${decimalToHex(borderColorStart)}`;
+ const borderColorEndStr = `#${decimalToHex(borderColorEnd)}`;
+
+ console.log(borderColorStartStr, borderColorEndStr);
+
+ 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);
+ }
+
+ ctx.font = `50px ComplianceSans`;
+ ctx.fillText(stripCodes(item.displayname), scale * 4, scale * 7);
+
+ for (let i = 0; i < item.lore.length; i++) {
+ const line = item.lore[i];
+
+ ctx.fillStyle = `#${decimalToHex(parseInt(new tinycolor(getPrimaryColour(line)).toHex(), 16))}`;
+ ctx.fillText(stripCodes(line), scale * 4, scale * (7 + (i + 1) * 5));
+ }
+
+ return itemRender.toBuffer('image/png');
+}
+
+/**
+ * @param {string} displayname
+ */
+function getPrimaryColour(displayname) {
+ const code = getPrimaryColourCode(displayname);
+ return formattingInfo[`§${code}`].foregroundDarker;
+}
+
+/**
+ * @param {string} str
+ * @returns {string}
+ */
+function stripCodes(str) {
+ for (const format in formattingInfo) {
+ // @ts-ignore
+ str = str.replaceAll(new RegExp(format, 'ig'), '');
+ }
+ return str;
+}
+
+const repo = path.join(__dirname, 'neu-item-repo-dangerous');
+const itemPath = path.join(repo, 'items');
+const items = await fs.readdir(itemPath);
+
+const randomItem = items[Math.floor(Math.random() * items.length)];
+/** @type {RawNeuItem} */
+const item = (await import(path.join(itemPath, randomItem), { assert: { type: 'json' } })).default;
+
+console.log(randomItem);
+fs.writeFile('./test.png', tooltip(item));