:3c
This commit is contained in:
parent
b83c5eab01
commit
68b738056b
|
@ -13,12 +13,14 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/color": "^3.0.6",
|
||||||
"@types/node": "^20.14.2",
|
"@types/node": "^20.14.2",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"canvas": "^2.11.2",
|
"canvas": "^2.11.2",
|
||||||
|
"color": "^4.2.3",
|
||||||
"isolated-vm": "^5.0.0"
|
"isolated-vm": "^5.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,17 @@ dependencies:
|
||||||
canvas:
|
canvas:
|
||||||
specifier: ^2.11.2
|
specifier: ^2.11.2
|
||||||
version: 2.11.2
|
version: 2.11.2
|
||||||
|
color:
|
||||||
|
specifier: ^4.2.3
|
||||||
|
version: 4.2.3
|
||||||
isolated-vm:
|
isolated-vm:
|
||||||
specifier: ^5.0.0
|
specifier: ^5.0.0
|
||||||
version: 5.0.0
|
version: 5.0.0
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@types/color':
|
||||||
|
specifier: ^3.0.6
|
||||||
|
version: 3.0.6
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^20.14.2
|
specifier: ^20.14.2
|
||||||
version: 20.14.2
|
version: 20.14.2
|
||||||
|
@ -43,6 +49,22 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
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:
|
/@types/node@20.14.2:
|
||||||
resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==}
|
resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -146,11 +168,37 @@ packages:
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: false
|
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:
|
/color-support@1.1.3:
|
||||||
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
|
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: false
|
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:
|
/combined-stream@1.0.8:
|
||||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
@ -326,6 +374,10 @@ packages:
|
||||||
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
|
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/is-arrayish@0.3.2:
|
||||||
|
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/is-fullwidth-code-point@3.0.0:
|
/is-fullwidth-code-point@3.0.0:
|
||||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -573,6 +625,12 @@ packages:
|
||||||
simple-concat: 1.0.1
|
simple-concat: 1.0.1
|
||||||
dev: false
|
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:
|
/string-width@4.2.3:
|
||||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
47
src/index.ts
47
src/index.ts
|
@ -2,6 +2,7 @@ import { createCanvas, loadImage } from "canvas";
|
||||||
import { fetchScript, extractDataFromScript, getAsset, dirname } from "./util.js";
|
import { fetchScript, extractDataFromScript, getAsset, dirname } from "./util.js";
|
||||||
import { writeFile } from "fs/promises";
|
import { writeFile } from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import Color from "color";
|
||||||
|
|
||||||
const MAKER_ID = "1904634";
|
const MAKER_ID = "1904634";
|
||||||
|
|
||||||
|
@ -12,7 +13,11 @@ type UrlsList = { colorId: string, url: string };
|
||||||
type LayerList = { layerId: string, urls: UrlsList[] };
|
type LayerList = { layerId: string, urls: UrlsList[] };
|
||||||
type ItemList = { itemId: string, layers: LayerList[] };
|
type ItemList = { itemId: string, layers: LayerList[] };
|
||||||
type LayerColorList = { layerIndex: number, cpId: string, colors: string[] };
|
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 items: ItemList[] = [];
|
||||||
const categories: CategoryList[] = [];
|
const categories: CategoryList[] = [];
|
||||||
|
@ -50,15 +55,35 @@ for (const c in config.pList) {
|
||||||
}
|
}
|
||||||
|
|
||||||
items.push(...localItems);
|
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 images: { layer: number, url: string, categoryId: number }[] = [];
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
|
|
||||||
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 colors = layerColors.find((c) => c.cpId == category.cpId)!.colors;
|
||||||
const colorId = colors[Math.floor(Math.random() * colors.length)];
|
const colorId = colors[Math.floor(Math.random() * colors.length)];
|
||||||
const item = category.items[Math.floor(Math.random() * category.items.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;
|
const url = (layer.urls.find((i) => i.colorId == colorId) ?? layer.urls?.[0])?.url;
|
||||||
|
|
||||||
if (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
|
// Retains the correct order
|
||||||
const imgPaths = await Promise.all(
|
const imgPaths = await Promise.all(
|
||||||
images
|
images
|
||||||
|
|
|
@ -9,6 +9,7 @@ export type Plist = {
|
||||||
cpId: string, // Used to index into cpList
|
cpId: string, // Used to index into cpList
|
||||||
lyrs: number[],
|
lyrs: number[],
|
||||||
defItmId: number,
|
defItmId: number,
|
||||||
|
isRmv: number, // 0 if not removable
|
||||||
items: Item[],
|
items: Item[],
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
|
@ -23,10 +24,18 @@ export type Lyrlist = {
|
||||||
[key: number]: number;
|
[key: number]: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type RuleList = {
|
||||||
|
[key: number]: {
|
||||||
|
list: number[],
|
||||||
|
pId: number,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type Config = {
|
export type Config = {
|
||||||
pList: Plist,
|
pList: Plist,
|
||||||
cpList: Cplist,
|
cpList: Cplist,
|
||||||
lyrList: Lyrlist,
|
lyrList: Lyrlist,
|
||||||
|
ruleList: RuleList,
|
||||||
w: number,
|
w: number,
|
||||||
h: number,
|
h: number,
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue