This commit is contained in:
Lea 2024-06-16 20:07:29 +02:00
parent b83c5eab01
commit 68b738056b
Signed by: Lea
GPG key ID: 1BAFFE8347019C42
4 changed files with 109 additions and 7 deletions

View file

@ -13,12 +13,14 @@
"author": "",
"license": "ISC",
"devDependencies": {
"@types/color": "^3.0.6",
"@types/node": "^20.14.2",
"typescript": "^5.4.5"
},
"dependencies": {
"axios": "^1.7.2",
"canvas": "^2.11.2",
"color": "^4.2.3",
"isolated-vm": "^5.0.0"
}
}

View file

@ -11,11 +11,17 @@ dependencies:
canvas:
specifier: ^2.11.2
version: 2.11.2
color:
specifier: ^4.2.3
version: 4.2.3
isolated-vm:
specifier: ^5.0.0
version: 5.0.0
devDependencies:
'@types/color':
specifier: ^3.0.6
version: 3.0.6
'@types/node':
specifier: ^20.14.2
version: 20.14.2
@ -43,6 +49,22 @@ packages:
- supports-color
dev: false
/@types/color-convert@2.0.3:
resolution: {integrity: sha512-2Q6wzrNiuEvYxVQqhh7sXM2mhIhvZR/Paq4FdsQkOMgWsCIkKvSGj8Le1/XalulrmgOzPMqNa0ix+ePY4hTrfg==}
dependencies:
'@types/color-name': 1.1.4
dev: true
/@types/color-name@1.1.4:
resolution: {integrity: sha512-hulKeREDdLFesGQjl96+4aoJSHY5b2GRjagzzcqCfIrWhe5vkCqIvrLbqzBaI1q94Vg8DNJZZqTR5ocdWmWclg==}
dev: true
/@types/color@3.0.6:
resolution: {integrity: sha512-NMiNcZFRUAiUUCCf7zkAelY8eV3aKqfbzyFQlXpPIEeoNDbsEHGpb854V3gzTsGKYj830I5zPuOwU/TP5/cW6A==}
dependencies:
'@types/color-convert': 2.0.3
dev: true
/@types/node@20.14.2:
resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==}
dependencies:
@ -146,11 +168,37 @@ packages:
engines: {node: '>=10'}
dev: false
/color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
dependencies:
color-name: 1.1.4
dev: false
/color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
dev: false
/color-string@1.9.1:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
dependencies:
color-name: 1.1.4
simple-swizzle: 0.2.2
dev: false
/color-support@1.1.3:
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
hasBin: true
dev: false
/color@4.2.3:
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
engines: {node: '>=12.5.0'}
dependencies:
color-convert: 2.0.1
color-string: 1.9.1
dev: false
/combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@ -326,6 +374,10 @@ packages:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
dev: false
/is-arrayish@0.3.2:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
dev: false
/is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
@ -573,6 +625,12 @@ packages:
simple-concat: 1.0.1
dev: false
/simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
dependencies:
is-arrayish: 0.3.2
dev: false
/string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}

View file

@ -2,6 +2,7 @@ import { createCanvas, loadImage } from "canvas";
import { fetchScript, extractDataFromScript, getAsset, dirname } from "./util.js";
import { writeFile } from "fs/promises";
import path from "path";
import Color from "color";
const MAKER_ID = "1904634";
@ -12,7 +13,11 @@ 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 };
type CategoryList = { cpId: string, pId: string, items: ItemList[], index: number, isRmv: boolean };
const exclusions: number[][] = Object.values(config.ruleList)
.filter((rule) => rule.pId == 0) // Not sure what pId is but just to be sure that this won't break something else
.map((rule) => rule.list);
const items: ItemList[] = [];
const categories: CategoryList[] = [];
@ -50,15 +55,35 @@ for (const c in config.pList) {
}
items.push(...localItems);
categories.push({ cpId: category.cpId, pId: category.pId.toString(), items: localItems, index: partsId2Index[category.pId.toString()] });
categories.push({
cpId: category.cpId,
pId: category.pId.toString(),
items: localItems,
index: partsId2Index[category.pId.toString()],
isRmv: !!category.isRmv,
});
}
const canvas = createCanvas(config.w, config.h);
const ctx = canvas.getContext('2d');
const images: { layer: number, url: string, categoryId: number }[] = [];
const images: { layer: number, url: string }[] = [];
categoryLoop: for (const category of categories.sort((a, b) => b.index - a.index)) {
const canHide = category.isRmv;
const inRuleset = exclusions.find((arr) => arr.includes(Number(category.pId)));
if (canHide) {
// If there's other things that would be blocked by this,
// it should be more likely for this one to be hidden so
// the other item appears more frequently.
if (Math.random() < (inRuleset ? 0.5 : 0.2)) continue;
}
// Check if a conflicting object already exists, and if so, skip this one
for (const rule of exclusions) {
if (rule.includes(Number(category.pId))) {
if (images.find((i) => rule.includes(i.categoryId))) continue categoryLoop;
}
}
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)];
@ -67,11 +92,19 @@ for (const category of categories.sort((a, b) => b.index - a.index)) {
const url = (layer.urls.find((i) => i.colorId == colorId) ?? layer.urls?.[0])?.url;
if (url) {
images.push({ layer: Number(layer.layerId), url });
images.push({ layer: Number(layer.layerId), url, categoryId: Number(category.pId) });
}
}
}
const canvas = createCanvas(config.w, config.h);
const ctx = canvas.getContext('2d');
// So we don't accidentally end up with a transparent background
const bgCol = Color.hsv(Math.floor(Math.random() * 360), 20, 100).hex();
ctx.fillStyle = bgCol;
ctx.fillRect(0, 0, config.w, config.h);
// Retains the correct order
const imgPaths = await Promise.all(
images

View file

@ -9,6 +9,7 @@ export type Plist = {
cpId: string, // Used to index into cpList
lyrs: number[],
defItmId: number,
isRmv: number, // 0 if not removable
items: Item[],
}[];
@ -23,10 +24,18 @@ export type Lyrlist = {
[key: number]: number;
}
export type RuleList = {
[key: number]: {
list: number[],
pId: number,
}
}
export type Config = {
pList: Plist,
cpList: Cplist,
lyrList: Lyrlist,
ruleList: RuleList,
w: number,
h: number,