90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
import { createCanvas, loadImage } from "canvas";
|
|
import { fetchScript, extractDataFromScript, getAsset, dirname } from "./util.js";
|
|
import { writeFile } from "fs/promises";
|
|
import path from "path";
|
|
|
|
const MAKER_ID = "1904634";
|
|
|
|
await fetchScript(MAKER_ID);
|
|
const { config, commonImages, cdnRoot, partsId2Index } = await extractDataFromScript(MAKER_ID);
|
|
|
|
type UrlsList = { colorId: string, url: string };
|
|
type LayerList = { layerId: string, urls: UrlsList[] };
|
|
type ItemList = { itemId: string, layers: LayerList[] };
|
|
type LayerColorList = { layerIndex: number, cpId: string, colors: string[] };
|
|
type CategoryList = { cpId: string, pId: string, items: ItemList[], index: number };
|
|
|
|
const items: ItemList[] = [];
|
|
const categories: CategoryList[] = [];
|
|
const layerColors: LayerColorList[] = [];
|
|
|
|
for (const c in config.pList) {
|
|
const category = config.pList[c];
|
|
|
|
layerColors.push({
|
|
layerIndex: Number(c),
|
|
cpId: category.cpId,
|
|
colors: config.cpList[category.cpId].map((c) => c.cId.toString()),
|
|
});
|
|
|
|
const localItems: ItemList[] = [];
|
|
for (const item of category.items) {
|
|
const id = item.itmId;
|
|
|
|
const obj = commonImages[id];
|
|
const layers: LayerList[] = [];
|
|
|
|
for (const layer of category.lyrs) {
|
|
if (!obj[layer]) continue; // Not every entry uses all layers
|
|
const variants = Object.keys(obj[layer]);
|
|
|
|
const urls: UrlsList[] = variants.map((v) => ({
|
|
colorId: v,
|
|
url: cdnRoot + obj[layer][v].url,
|
|
}));
|
|
|
|
layers.push({ layerId: layer.toString(), urls });
|
|
}
|
|
|
|
localItems.push({ itemId: id.toString(), layers: layers });
|
|
}
|
|
|
|
items.push(...localItems);
|
|
categories.push({ cpId: category.cpId, pId: category.pId.toString(), items: localItems, index: partsId2Index[category.pId.toString()] });
|
|
}
|
|
|
|
const canvas = createCanvas(config.w, config.h);
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
console.log(categories);
|
|
|
|
const images: { layer: number, url: string }[] = [];
|
|
|
|
for (const category of categories.sort((a, b) => b.index - a.index)) {
|
|
const colors = layerColors.find((c) => c.cpId == category.cpId)!.colors;
|
|
const colorId = colors[Math.floor(Math.random() * colors.length)];
|
|
const item = category.items[Math.floor(Math.random() * category.items.length)];
|
|
|
|
for (const layer of item.layers) {
|
|
const url = (layer.urls.find((i) => i.colorId == colorId) ?? layer.urls?.[0])?.url;
|
|
|
|
if (url) {
|
|
images.push({ layer: Number(layer.layerId), url });
|
|
}
|
|
}
|
|
}
|
|
|
|
// Retains the correct order
|
|
const imgPaths = await Promise.all(
|
|
images
|
|
.sort((a, b) => config.lyrList[a.layer] - config.lyrList[b.layer])
|
|
.map((img) => getAsset(img.url))
|
|
);
|
|
|
|
for (const path of imgPaths) {
|
|
const img = await loadImage(path);
|
|
ctx.drawImage(img, 0, 0, config.w, config.h);
|
|
}
|
|
|
|
await writeFile(path.join(dirname, "..", "cache", MAKER_ID + ".png"), canvas.toBuffer());
|