-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblocks.js
More file actions
112 lines (88 loc) · 2.99 KB
/
Copy pathblocks.js
File metadata and controls
112 lines (88 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { readdirSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import sharp from "sharp";
import { createGeneratedDir, rgbToHex } from "./utils.js";
await createGeneratedDir();
const source = join(process.cwd(), "source");
const output = join(process.cwd(), "generated", "blocks.json");
const modelsPath = join(source, "assets/minecraft/models/block");
const blockstatesPath = join(source, "assets/minecraft/blockstates");
const texturesPath = join(source, "assets/minecraft/textures/block");
const getDominantColor = (pixels, channels) => {
const counts = {};
for (let i = 0; i < pixels.length; i += channels) {
const opacity = pixels[i + 3];
if (opacity === 0) {
continue;
}
const r = pixels[i];
const g = pixels[i + 1];
const b = pixels[i + 2];
const hex = rgbToHex(r, g, b);
if (!isNaN(r) && !isNaN(g) && !isNaN(b)) {
counts[hex] = (counts[hex] || 0) + 1;
}
}
return Object.entries(counts).sort((a, b) => b[1] - a[1])[0]?.[0];
};
const getModels = (value) => {
const regex = /"model"\s*:\s*"([^"]+)"/g;
const models = [];
let match;
while ((match = regex.exec(value)) !== null) {
models.push(match[1]);
}
return models;
};
const files = readdirSync(blockstatesPath).filter((file) =>
file.endsWith(".json")
);
const result = {};
for (const file of files) {
const filePath = join(blockstatesPath, file);
const blockName = file.split(".")[0];
const models = getModels(readFileSync(filePath));
if (!models) continue;
const modelName = models[0];
if (!modelName) continue;
if (!modelName.startsWith("minecraft:block/")) continue;
const json = JSON.parse(
readFileSync(join(modelsPath, `${modelName.split("/")[1]}.json`)).toString()
);
if (!json.textures) continue;
const keys = Object.keys(json.textures);
const texture =
json.textures.top || json.textures.all || json.textures[keys[0]];
if (!texture) continue;
if (!texture.startsWith("minecraft:block/")) continue;
const textureFileName = texture.split("/")[1];
const textureFilePath = join(texturesPath, `${textureFileName}.png`);
try {
const image = sharp(textureFilePath)
.resize(10, 10, { fit: "inside" })
.ensureAlpha();
const { data, info } = await image
.raw()
.toBuffer({ resolveWithObject: true });
let dominant = getDominantColor(data, info.channels);
result[blockName] = dominant || "#000000";
} catch (err) {
console.error(`Error with ${file}:`, err.message);
}
}
result.birch_leaves = "#80A755";
result.spruce_leaves = "#619961";
result.dirt_path = "#a88b49";
result.lily_pad = "#208030";
result.bamboo = "#97d155";
result.pumpkin = "#e0881d";
result.beacon = "#80dfff";
result.composter = "#8c5000";
result.campfire = "#ad6300";
result.hopper = "#444343";
result.bell = "#fbf28b";
result.cactus = "#639632";
result.iron_bars = "##b5b5b5";
result.grind_stone = "#a3a3a3";
writeFileSync(output, JSON.stringify(result, null, 2));
console.log(`File generated: blocks.json`);