to resume
This commit is contained in:
parent
44c1862869
commit
a8a903d581
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"dev": "deno run -A --node-modules-dir npm:vite & deno run --allow-net --allow-read --allow-write --allow-env --watch ./server/main.ts",
|
"dev": "deno run -A --node-modules-dir npm:vite & deno run -A --watch ./server/main.ts",
|
||||||
"fdev": "deno run -A --node-modules-dir npm:vite",
|
"fdev": "deno run -A --node-modules-dir npm:vite",
|
||||||
"build": "deno run -A --node-modules-dir npm:vite build",
|
"build": "deno run -A --node-modules-dir npm:vite build",
|
||||||
"preview": "deno run -A --node-modules-dir npm:vite preview",
|
"preview": "deno run -A --node-modules-dir npm:vite preview",
|
||||||
"serve": "deno run --allow-net --allow-read --allow-write --allow-env ./server/main.ts",
|
"serve": "deno run -A ./server/main.ts",
|
||||||
"bdev": "deno run --allow-net --allow-read --allow-write --allow-env --watch ./server/main.ts",
|
"bdev": "deno run -A --watch ./server/main.ts",
|
||||||
"tmux": "./session.sh"
|
"tmux": "./session.sh"
|
||||||
},
|
},
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
@ -19,6 +19,7 @@
|
|||||||
"@cgg/sockpuppet": "../sockpuppet.ts/server/mod.ts",
|
"@cgg/sockpuppet": "../sockpuppet.ts/server/mod.ts",
|
||||||
"@cgg/sockpuppet/client": "../sockpuppet.ts/client/mod.ts",
|
"@cgg/sockpuppet/client": "../sockpuppet.ts/client/mod.ts",
|
||||||
"@deno/vite-plugin": "npm:@deno/vite-plugin@^1.0.0",
|
"@deno/vite-plugin": "npm:@deno/vite-plugin@^1.0.0",
|
||||||
|
"@gfx/canvas": "jsr:@gfx/canvas@^0.5.8",
|
||||||
"@preact/preset-vite": "npm:@preact/preset-vite@^2.9.1",
|
"@preact/preset-vite": "npm:@preact/preset-vite@^2.9.1",
|
||||||
"@std/encoding": "jsr:@std/encoding@^1.0.5",
|
"@std/encoding": "jsr:@std/encoding@^1.0.5",
|
||||||
"@std/fs": "jsr:@std/fs@^1.0.4",
|
"@std/fs": "jsr:@std/fs@^1.0.4",
|
||||||
|
80
deno.lock
generated
80
deno.lock
generated
@ -2,14 +2,26 @@
|
|||||||
"version": "4",
|
"version": "4",
|
||||||
"specifiers": {
|
"specifiers": {
|
||||||
"jsr:@bearmetal/store@^0.0.5": "0.0.5",
|
"jsr:@bearmetal/store@^0.0.5": "0.0.5",
|
||||||
|
"jsr:@denosaurs/plug@1.0.5": "1.0.5",
|
||||||
|
"jsr:@gfx/canvas@~0.5.8": "0.5.8",
|
||||||
|
"jsr:@std/assert@0.214": "0.214.0",
|
||||||
|
"jsr:@std/assert@0.217": "0.217.0",
|
||||||
"jsr:@std/cli@^1.0.6": "1.0.6",
|
"jsr:@std/cli@^1.0.6": "1.0.6",
|
||||||
|
"jsr:@std/encoding@0.214": "0.214.0",
|
||||||
|
"jsr:@std/encoding@0.217.0": "0.217.0",
|
||||||
"jsr:@std/encoding@^1.0.5": "1.0.5",
|
"jsr:@std/encoding@^1.0.5": "1.0.5",
|
||||||
|
"jsr:@std/fmt@0.214": "0.214.0",
|
||||||
"jsr:@std/fmt@^1.0.2": "1.0.2",
|
"jsr:@std/fmt@^1.0.2": "1.0.2",
|
||||||
"jsr:@std/fs@*": "1.0.4",
|
"jsr:@std/fs@*": "1.0.4",
|
||||||
|
"jsr:@std/fs@0.214": "0.214.0",
|
||||||
|
"jsr:@std/fs@0.217.0": "0.217.0",
|
||||||
"jsr:@std/fs@^1.0.4": "1.0.4",
|
"jsr:@std/fs@^1.0.4": "1.0.4",
|
||||||
"jsr:@std/http@^1.0.8": "1.0.8",
|
"jsr:@std/http@^1.0.8": "1.0.8",
|
||||||
"jsr:@std/media-types@^1.0.3": "1.0.3",
|
"jsr:@std/media-types@^1.0.3": "1.0.3",
|
||||||
"jsr:@std/net@^1.0.4": "1.0.4",
|
"jsr:@std/net@^1.0.4": "1.0.4",
|
||||||
|
"jsr:@std/path@0.214": "0.214.0",
|
||||||
|
"jsr:@std/path@0.217": "0.217.0",
|
||||||
|
"jsr:@std/path@0.217.0": "0.217.0",
|
||||||
"jsr:@std/path@^1.0.6": "1.0.6",
|
"jsr:@std/path@^1.0.6": "1.0.6",
|
||||||
"jsr:@std/streams@^1.0.7": "1.0.7",
|
"jsr:@std/streams@^1.0.7": "1.0.7",
|
||||||
"npm:@babel/plugin-transform-react-jsx-development@^7.25.7": "7.25.7_@babel+core@7.25.8",
|
"npm:@babel/plugin-transform-react-jsx-development@^7.25.7": "7.25.7_@babel+core@7.25.8",
|
||||||
@ -37,30 +49,77 @@
|
|||||||
"jsr:@std/fs@^1.0.4"
|
"jsr:@std/fs@^1.0.4"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"@denosaurs/plug@1.0.5": {
|
||||||
|
"integrity": "04cd988da558adc226202d88c3a434d5fcc08146eaf4baf0cea0c2284b16d2bf",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/encoding@0.214",
|
||||||
|
"jsr:@std/fmt@0.214",
|
||||||
|
"jsr:@std/fs@0.214",
|
||||||
|
"jsr:@std/path@0.214"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@gfx/canvas@0.5.8": {
|
||||||
|
"integrity": "a61c80292528e7433d428556b494a0ea496dd8e6abd4a338b8b25fc04e46ea3e",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@denosaurs/plug",
|
||||||
|
"jsr:@std/encoding@0.217.0",
|
||||||
|
"jsr:@std/fs@0.217.0",
|
||||||
|
"jsr:@std/path@0.217.0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@std/assert@0.214.0": {
|
||||||
|
"integrity": "55d398de76a9828fd3b1aa653f4dba3eee4c6985d90c514865d2be9bd082b140"
|
||||||
|
},
|
||||||
|
"@std/assert@0.217.0": {
|
||||||
|
"integrity": "c98e279362ca6982d5285c3b89517b757c1e3477ee9f14eb2fdf80a45aaa9642"
|
||||||
|
},
|
||||||
"@std/cli@1.0.6": {
|
"@std/cli@1.0.6": {
|
||||||
"integrity": "d22d8b38c66c666d7ad1f2a66c5b122da1704f985d3c47f01129f05abb6c5d3d"
|
"integrity": "d22d8b38c66c666d7ad1f2a66c5b122da1704f985d3c47f01129f05abb6c5d3d"
|
||||||
},
|
},
|
||||||
|
"@std/encoding@0.214.0": {
|
||||||
|
"integrity": "30a8713e1db22986c7e780555ffd2fefd1d4f9374d734bb41f5970f6c3352af5"
|
||||||
|
},
|
||||||
|
"@std/encoding@0.217.0": {
|
||||||
|
"integrity": "b03e8ff94c98d6b6a02c02c5cf8e5d203400155516248964fc4559abc04669dc"
|
||||||
|
},
|
||||||
"@std/encoding@1.0.5": {
|
"@std/encoding@1.0.5": {
|
||||||
"integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04"
|
"integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04"
|
||||||
},
|
},
|
||||||
|
"@std/fmt@0.214.0": {
|
||||||
|
"integrity": "40382cff88a0783b347b4d69b94cf931ab8e549a733916718cb866c08efac4d4"
|
||||||
|
},
|
||||||
"@std/fmt@1.0.2": {
|
"@std/fmt@1.0.2": {
|
||||||
"integrity": "87e9dfcdd3ca7c066e0c3c657c1f987c82888eb8103a3a3baa62684ffeb0f7a7"
|
"integrity": "87e9dfcdd3ca7c066e0c3c657c1f987c82888eb8103a3a3baa62684ffeb0f7a7"
|
||||||
},
|
},
|
||||||
|
"@std/fs@0.214.0": {
|
||||||
|
"integrity": "bc880fea0be120cb1550b1ed7faf92fe071003d83f2456a1e129b39193d85bea",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/assert@0.214",
|
||||||
|
"jsr:@std/path@0.214"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@std/fs@0.217.0": {
|
||||||
|
"integrity": "0bfff5f3618d68c385b28b4ffbf3a15c98293a0f1186444458b62e0111ce77b2",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/assert@0.217",
|
||||||
|
"jsr:@std/path@0.217"
|
||||||
|
]
|
||||||
|
},
|
||||||
"@std/fs@1.0.4": {
|
"@std/fs@1.0.4": {
|
||||||
"integrity": "2907d32d8d1d9e540588fd5fe0ec21ee638134bd51df327ad4e443aaef07123c",
|
"integrity": "2907d32d8d1d9e540588fd5fe0ec21ee638134bd51df327ad4e443aaef07123c",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"jsr:@std/path"
|
"jsr:@std/path@^1.0.6"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"@std/http@1.0.8": {
|
"@std/http@1.0.8": {
|
||||||
"integrity": "6ea1b2e8d33929967754a3b6d6c6f399ad6647d7bbb5a466c1eaf9b294a6ebcd",
|
"integrity": "6ea1b2e8d33929967754a3b6d6c6f399ad6647d7bbb5a466c1eaf9b294a6ebcd",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"jsr:@std/cli",
|
"jsr:@std/cli",
|
||||||
"jsr:@std/encoding",
|
"jsr:@std/encoding@^1.0.5",
|
||||||
"jsr:@std/fmt",
|
"jsr:@std/fmt@^1.0.2",
|
||||||
"jsr:@std/media-types",
|
"jsr:@std/media-types",
|
||||||
"jsr:@std/net",
|
"jsr:@std/net",
|
||||||
"jsr:@std/path",
|
"jsr:@std/path@^1.0.6",
|
||||||
"jsr:@std/streams"
|
"jsr:@std/streams"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -70,6 +129,18 @@
|
|||||||
"@std/net@1.0.4": {
|
"@std/net@1.0.4": {
|
||||||
"integrity": "2f403b455ebbccf83d8a027d29c5a9e3a2452fea39bb2da7f2c04af09c8bc852"
|
"integrity": "2f403b455ebbccf83d8a027d29c5a9e3a2452fea39bb2da7f2c04af09c8bc852"
|
||||||
},
|
},
|
||||||
|
"@std/path@0.214.0": {
|
||||||
|
"integrity": "d5577c0b8d66f7e8e3586d864ebdf178bb326145a3611da5a51c961740300285",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/assert@0.214"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@std/path@0.217.0": {
|
||||||
|
"integrity": "1217cc25534bca9a2f672d7fe7c6f356e4027df400c0e85c0ef3e4343bc67d11",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/assert@0.217"
|
||||||
|
]
|
||||||
|
},
|
||||||
"@std/path@1.0.6": {
|
"@std/path@1.0.6": {
|
||||||
"integrity": "ab2c55f902b380cf28e0eec501b4906e4c1960d13f00e11cfbcd21de15f18fed"
|
"integrity": "ab2c55f902b380cf28e0eec501b4906e4c1960d13f00e11cfbcd21de15f18fed"
|
||||||
},
|
},
|
||||||
@ -1418,6 +1489,7 @@
|
|||||||
"workspace": {
|
"workspace": {
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"jsr:@bearmetal/store@^0.0.5",
|
"jsr:@bearmetal/store@^0.0.5",
|
||||||
|
"jsr:@gfx/canvas@~0.5.8",
|
||||||
"jsr:@std/encoding@^1.0.5",
|
"jsr:@std/encoding@^1.0.5",
|
||||||
"jsr:@std/fs@^1.0.4",
|
"jsr:@std/fs@^1.0.4",
|
||||||
"jsr:@std/http@^1.0.8",
|
"jsr:@std/http@^1.0.8",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { encodeBase64 } from "@std/encoding/base64";
|
import { encodeBase64 } from "@std/encoding/base64";
|
||||||
import { readDirFiles } from "../util/readDir.ts";
|
import { readDirFiles } from "../util/readDir.ts";
|
||||||
|
import { createIsometricCube } from "./renderer.ts";
|
||||||
|
|
||||||
interface BlockItem {
|
interface BlockItem {
|
||||||
name: string;
|
name: string;
|
||||||
@ -16,13 +17,287 @@ export const readBlocks = async (path: string) => {
|
|||||||
images: [],
|
images: [],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const texPath = path + "/assets/minecraft/textures/block";
|
const blockTextures = await readDirFiles(
|
||||||
for await (const image of Deno.readDir(texPath)) {
|
path + "/assets/minecraft/textures/block",
|
||||||
for (const block of blocks) {
|
);
|
||||||
if (image.name.startsWith(block.name)) {
|
|
||||||
const data = await Deno.readFile(texPath + "/" + image.name);
|
const modelPath = path + "/assets/minecraft/models/block";
|
||||||
block.images.push("image/png;base64," + encodeBase64(data));
|
for (const block of blocks) {
|
||||||
|
let name = block.name;
|
||||||
|
if (
|
||||||
|
block.name.startsWith("air") ||
|
||||||
|
block.name.startsWith("void_air") ||
|
||||||
|
block.name.startsWith("cave_air") ||
|
||||||
|
block.name.startsWith("end_gateway") ||
|
||||||
|
block.name.endsWith("_door") ||
|
||||||
|
block.name.endsWith("_trapdoor") ||
|
||||||
|
block.name.endsWith("_banner") ||
|
||||||
|
block.name.endsWith("_fence_gate") ||
|
||||||
|
block.name.endsWith("_pressure_plate") ||
|
||||||
|
block.name.endsWith("_button") ||
|
||||||
|
block.name.endsWith("lever") ||
|
||||||
|
block.name.endsWith("_sign") ||
|
||||||
|
block.name.endsWith("torch") ||
|
||||||
|
block.name.endsWith("_fence") ||
|
||||||
|
block.name.endsWith("_wall") ||
|
||||||
|
block.name.endsWith("_skull") ||
|
||||||
|
block.name.endsWith("_head") ||
|
||||||
|
block.name.includes("bubble_column") ||
|
||||||
|
block.name.includes("tripwire_hook") ||
|
||||||
|
block.name.includes("tripwire") ||
|
||||||
|
block.name == undefined ||
|
||||||
|
block.name.includes("chest") ||
|
||||||
|
block.name.includes("command")
|
||||||
|
) continue;
|
||||||
|
if (block.name.includes("water") || block.name.includes("lava")) {
|
||||||
|
const what = block.name.includes("water") ? "water" : "lava";
|
||||||
|
const itemTexLoc = path +
|
||||||
|
`/assets/minecraft/textures/block/${what}_still.png`;
|
||||||
|
const itemImage = await Deno.readFile(itemTexLoc);
|
||||||
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (block.name === "nether_portal") {
|
||||||
|
const itemTexLoc = path +
|
||||||
|
`/assets/minecraft/textures/block/nether_portal.png`;
|
||||||
|
const itemImage = await Deno.readFile(itemTexLoc);
|
||||||
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (["fire", "soul_fire"].includes(block.name)) {
|
||||||
|
const itemTexLoc = path +
|
||||||
|
`/assets/minecraft/textures/block/${block.name}_0.png`;
|
||||||
|
const itemImage = await Deno.readFile(itemTexLoc);
|
||||||
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (block.name.includes("cake")) {
|
||||||
|
const itemTexLoc = path +
|
||||||
|
`/assets/minecraft/textures/item/cake.png`;
|
||||||
|
const itemImage = await Deno.readFile(itemTexLoc);
|
||||||
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (block.name.endsWith("_bed")) {
|
||||||
|
const itemTexLoc = path + "/assets/minecraft/textures/entity/bed/" +
|
||||||
|
block.name.replace(/_bed$/, "") + ".png";
|
||||||
|
const itemImage = await Deno.readFile(itemTexLoc);
|
||||||
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (block.name === "nether_portal") {
|
||||||
|
const itemTexLoc = path +
|
||||||
|
`/assets/minecraft/textures/block/nether_portal.png`;
|
||||||
|
const itemImage = await Deno.readFile(itemTexLoc);
|
||||||
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (block.name.includes("dripleaf") && !block.name.includes("stem")) {
|
||||||
|
const itemTexLoc = path +
|
||||||
|
`/assets/minecraft/textures/block/${block.name}_top.png`;
|
||||||
|
const itemImage = await Deno.readFile(itemTexLoc);
|
||||||
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
"carrots",
|
||||||
|
"potatoes",
|
||||||
|
"wheat",
|
||||||
|
"beetroots",
|
||||||
|
"grass",
|
||||||
|
"kelp",
|
||||||
|
"light",
|
||||||
|
"bell",
|
||||||
|
"redstone_wire",
|
||||||
|
"sweet_berry_bush",
|
||||||
|
"cocoa",
|
||||||
|
"nether_wart",
|
||||||
|
"repeater",
|
||||||
|
"bamboo",
|
||||||
|
"pitcher_plant",
|
||||||
|
"campfire",
|
||||||
|
"soul_campfire",
|
||||||
|
].includes(block.name)
|
||||||
|
) {
|
||||||
|
const itemTexLoc = path + "/assets/minecraft/textures/item/" +
|
||||||
|
block.name
|
||||||
|
.replace("large_fern", "fern")
|
||||||
|
.replace("tall_seagrass", "seagrass")
|
||||||
|
.replace(/ss$/, "?")
|
||||||
|
.replace(/e?s$/, "")
|
||||||
|
.replace("?", "ss")
|
||||||
|
.replace("_bush", "")
|
||||||
|
.replace("berry", "berries")
|
||||||
|
.replace("cocoa", "cocoa_beans")
|
||||||
|
.replace("_wire", "") +
|
||||||
|
".png";
|
||||||
|
const itemImage = await Deno.readFile(itemTexLoc);
|
||||||
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
"melon_stem",
|
||||||
|
"pumpkin_stem",
|
||||||
|
"fern",
|
||||||
|
"large_fern",
|
||||||
|
"lilac",
|
||||||
|
"azure_bluet",
|
||||||
|
"red_tulip",
|
||||||
|
"orange_tulip",
|
||||||
|
"pink_tulip",
|
||||||
|
"white_tulip",
|
||||||
|
"oxeye_daisy",
|
||||||
|
"cornflower",
|
||||||
|
"lily_of_the_valley",
|
||||||
|
"wither_rose",
|
||||||
|
"rose_bush",
|
||||||
|
"peony",
|
||||||
|
"sunflower",
|
||||||
|
"torchflower_crop",
|
||||||
|
"suspicious_sand",
|
||||||
|
"suspicious_gravel",
|
||||||
|
"scaffolding",
|
||||||
|
"respawn_anchor",
|
||||||
|
"short_grass",
|
||||||
|
"tall_grass",
|
||||||
|
"seagrass",
|
||||||
|
"tall_seagrass",
|
||||||
|
"frosted_ice",
|
||||||
|
"pitcher_crop",
|
||||||
|
"iron_bars",
|
||||||
|
].includes(block.name)
|
||||||
|
) {
|
||||||
|
const textures = blockTextures.filter((t) => t.includes(block.name))
|
||||||
|
.reverse().filter((t) => !t.endsWith("mcmeta"));
|
||||||
|
const itemTexLoc = path + "/assets/minecraft/textures/block/" +
|
||||||
|
textures[0];
|
||||||
|
const itemImage = await Deno.readFile(itemTexLoc);
|
||||||
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (block.name.startsWith("waxed")) {
|
||||||
|
name = block.name.replace(/^waxed_?/, "");
|
||||||
|
}
|
||||||
|
if (block.name.startsWith("infested")) {
|
||||||
|
name = block.name.replace(/^infested_?/, "");
|
||||||
|
}
|
||||||
|
if (block.name.endsWith("_pane")) {
|
||||||
|
name = block.name.replace(/_pane$/, "");
|
||||||
|
}
|
||||||
|
if (block.name === "pink_petals") {
|
||||||
|
name = "pink_petals_4";
|
||||||
|
}
|
||||||
|
if (block.name.includes("candle")) {
|
||||||
|
const itemTexLoc = path +
|
||||||
|
`/assets/minecraft/textures/item/${block.name}.png`;
|
||||||
|
const itemImage = await Deno.readFile(itemTexLoc);
|
||||||
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (block.name.includes("cauldron")) {
|
||||||
|
const textures = blockTextures.filter((t) => t.includes("cauldron"));
|
||||||
|
for (const texture of textures) {
|
||||||
|
const texLoc = texture.replace("minecraft:", "");
|
||||||
|
const image = await Deno.readFile(
|
||||||
|
path + "/assets/minecraft/textures/block/" + texLoc,
|
||||||
|
);
|
||||||
|
const b64 = "data:image/png;base64," + encodeBase64(image);
|
||||||
|
block.images.push(await createIsometricCube(b64, b64, b64));
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (block.name === "snow") {
|
||||||
|
name = "snow_height2";
|
||||||
|
}
|
||||||
|
const data = await Deno.readTextFile(
|
||||||
|
modelPath + "/" + name + ".json",
|
||||||
|
);
|
||||||
|
const modelJson = JSON.parse(data);
|
||||||
|
if (modelJson.textures && !modelJson.elements) {
|
||||||
|
if (modelJson.textures.all) {
|
||||||
|
const texLoc = modelJson.textures.all;
|
||||||
|
const image = await Deno.readFile(
|
||||||
|
path + "/assets/minecraft/textures/" + texLoc.replace(
|
||||||
|
"minecraft:",
|
||||||
|
"",
|
||||||
|
) + ".png",
|
||||||
|
);
|
||||||
|
const b64 = "data:image/png;base64," + encodeBase64(image);
|
||||||
|
block.images.push(await createIsometricCube(b64, b64, b64));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (modelJson.textures.front) {
|
||||||
|
const frontImage = await Deno.readFile(
|
||||||
|
path + "/assets/minecraft/textures/" +
|
||||||
|
modelJson.textures.front.replace(
|
||||||
|
"minecraft:",
|
||||||
|
"",
|
||||||
|
) + ".png",
|
||||||
|
);
|
||||||
|
|
||||||
|
const frontB64 = "data:image/png;base64," + encodeBase64(frontImage);
|
||||||
|
|
||||||
|
const topImage = await Deno.readFile(
|
||||||
|
path + "/assets/minecraft/textures/" +
|
||||||
|
(modelJson.textures.top ?? modelJson.textures.side).replace(
|
||||||
|
"minecraft:",
|
||||||
|
"",
|
||||||
|
) + ".png",
|
||||||
|
);
|
||||||
|
|
||||||
|
const topB64 = "data:image/png;base64," + encodeBase64(topImage);
|
||||||
|
|
||||||
|
const sideImage = await Deno.readFile(
|
||||||
|
path + "/assets/minecraft/textures/" +
|
||||||
|
modelJson.textures.side.replace(
|
||||||
|
"minecraft:",
|
||||||
|
"",
|
||||||
|
) + ".png",
|
||||||
|
);
|
||||||
|
|
||||||
|
const sideB64 = "data:image/png;base64," + encodeBase64(sideImage);
|
||||||
|
block.images.push(await createIsometricCube(frontB64, sideB64, topB64));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (modelJson.textures.side) {
|
||||||
|
const sideImage = await Deno.readFile(
|
||||||
|
path + "/assets/minecraft/textures/" +
|
||||||
|
modelJson.textures.side.replace(
|
||||||
|
"minecraft:",
|
||||||
|
"",
|
||||||
|
) + ".png",
|
||||||
|
);
|
||||||
|
|
||||||
|
const sideB64 = "data:image/png;base64," + encodeBase64(sideImage);
|
||||||
|
|
||||||
|
const topImage = await Deno.readFile(
|
||||||
|
path + "/assets/minecraft/textures/" +
|
||||||
|
(modelJson.textures.top ?? modelJson.textures.bottom ??
|
||||||
|
modelJson.textures.side).replace(
|
||||||
|
"minecraft:",
|
||||||
|
"",
|
||||||
|
) +
|
||||||
|
".png",
|
||||||
|
);
|
||||||
|
|
||||||
|
const topB64 = "data:image/png;base64," + encodeBase64(topImage);
|
||||||
|
block.images.push(await createIsometricCube(sideB64, sideB64, topB64));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const textures = blockTextures.filter((t) =>
|
||||||
|
t.includes(block.name) && !t.includes("mcmeta")
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const texture of textures) {
|
||||||
|
const texLoc = texture.replace("minecraft:", "");
|
||||||
|
const image = await Deno.readFile(
|
||||||
|
path + "/assets/minecraft/textures/block/" + texLoc,
|
||||||
|
);
|
||||||
|
const b64 = "data:image/png;base64," + encodeBase64(image);
|
||||||
|
block.images.push(await createIsometricCube(b64, b64, b64));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return blocks;
|
return blocks;
|
||||||
@ -34,11 +309,15 @@ export const readItems = async (path: string) => {
|
|||||||
name: i.replace(".json", ""),
|
name: i.replace(".json", ""),
|
||||||
resourceLocation: "minecraft:" + i.replace(".json", ""),
|
resourceLocation: "minecraft:" + i.replace(".json", ""),
|
||||||
images: [],
|
images: [],
|
||||||
})).slice(0, 10);
|
}));
|
||||||
|
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
|
let name = item.name;
|
||||||
|
if (item.name.startsWith("air")) continue;
|
||||||
|
if (item.name.startsWith("waxed")) name = item.name.replace(/^waxed_?/, "");
|
||||||
|
|
||||||
const data = await Deno.readFile(
|
const data = await Deno.readFile(
|
||||||
path + "/assets/minecraft/models/item/" + item.name + ".json",
|
path + "/assets/minecraft/models/item/" + name + ".json",
|
||||||
);
|
);
|
||||||
const json = JSON.parse(new TextDecoder().decode(data));
|
const json = JSON.parse(new TextDecoder().decode(data));
|
||||||
const texDir = path + "/assets/minecraft/textures/";
|
const texDir = path + "/assets/minecraft/textures/";
|
||||||
@ -48,7 +327,7 @@ export const readItems = async (path: string) => {
|
|||||||
const data = await Deno.readFile(
|
const data = await Deno.readFile(
|
||||||
texDir + texLoc.replace("minecraft:", "") + ".png",
|
texDir + texLoc.replace("minecraft:", "") + ".png",
|
||||||
);
|
);
|
||||||
item.images.push("image/png;base64," + encodeBase64(data));
|
item.images.push("data:image/png;base64," + encodeBase64(data));
|
||||||
}
|
}
|
||||||
} else if (json.parent) {
|
} else if (json.parent) {
|
||||||
const parent = await Deno.readFile(
|
const parent = await Deno.readFile(
|
||||||
@ -65,7 +344,7 @@ export const readItems = async (path: string) => {
|
|||||||
const data = await Deno.readFile(
|
const data = await Deno.readFile(
|
||||||
texDir + texLoc.replace("minecraft:", "") + ".png",
|
texDir + texLoc.replace("minecraft:", "") + ".png",
|
||||||
);
|
);
|
||||||
item.images.push("image/png;base64," + encodeBase64(data));
|
item.images.push("data:image/png;base64," + encodeBase64(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
81
server/resources/renderer.ts
Normal file
81
server/resources/renderer.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import { createCanvas, Image } from "@gfx/canvas";
|
||||||
|
|
||||||
|
function loadImage(src: string): Promise<Image> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!src.startsWith("data:image/png;base64,")) {
|
||||||
|
console.log("src", src);
|
||||||
|
}
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => resolve(img);
|
||||||
|
img.onerror = () => {
|
||||||
|
console.log(src);
|
||||||
|
reject();
|
||||||
|
};
|
||||||
|
img.src = src;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createIsometricCube(
|
||||||
|
face1Src: string,
|
||||||
|
face2Src: string,
|
||||||
|
face3Src: string,
|
||||||
|
width: number = 96,
|
||||||
|
) {
|
||||||
|
const canvasWidth = width; // Set a size for the canvas
|
||||||
|
const canvasHeight = Math.ceil(width / .866);
|
||||||
|
const canvas = createCanvas(canvasWidth, canvasHeight);
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [face1, face2, face3] = await Promise.all([
|
||||||
|
loadImage(face1Src),
|
||||||
|
loadImage(face2Src),
|
||||||
|
loadImage(face3Src),
|
||||||
|
]).catch();
|
||||||
|
|
||||||
|
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
||||||
|
|
||||||
|
ctx.setTransform(
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
Math.tan(degToRad(30)),
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
canvasWidth / 3.5,
|
||||||
|
);
|
||||||
|
ctx.drawImage(face1, 0, 0, canvasWidth / 2, canvasHeight / 2);
|
||||||
|
|
||||||
|
// Face 2
|
||||||
|
ctx.setTransform(
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
-Math.tan(degToRad(30)),
|
||||||
|
1,
|
||||||
|
canvasWidth / 2,
|
||||||
|
canvasHeight / 2,
|
||||||
|
);
|
||||||
|
ctx.drawImage(face2, 0, 0, canvasWidth / 2, canvasHeight / 2);
|
||||||
|
|
||||||
|
// Face 3
|
||||||
|
ctx.setTransform(
|
||||||
|
1,
|
||||||
|
-Math.tan(degToRad(60)),
|
||||||
|
Math.tan(degToRad(30)),
|
||||||
|
1,
|
||||||
|
canvasWidth / 2,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
ctx.drawImage(face3, 0, 0, canvasWidth / 2, canvasWidth / 3.5);
|
||||||
|
|
||||||
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
} catch (e) {
|
||||||
|
// console.log("error", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
const b64 = canvas.toDataURL("png");
|
||||||
|
return b64;
|
||||||
|
}
|
||||||
|
|
||||||
|
function degToRad(deg: number) {
|
||||||
|
return deg * (Math.PI / 180);
|
||||||
|
}
|
@ -20,16 +20,27 @@ export const createResourcesRoutes = (router: Router) => {
|
|||||||
const packVersionJson = JSON.parse(packVersion);
|
const packVersionJson = JSON.parse(packVersion);
|
||||||
const mcVersion = packVersionJson.mcVersion;
|
const mcVersion = packVersionJson.mcVersion;
|
||||||
const resourceVersions = await readDirDirs("./resources");
|
const resourceVersions = await readDirDirs("./resources");
|
||||||
|
console.log("resourceVersions", resourceVersions);
|
||||||
for (const resourceVersion of resourceVersions) {
|
for (const resourceVersion of resourceVersions) {
|
||||||
if (versionCompat(resourceVersion, mcVersion)) {
|
if (versionCompat(resourceVersion, mcVersion)) {
|
||||||
const resourcePath = "./resources/" + resourceVersion;
|
const resourcePath = "./resources/" + resourceVersion;
|
||||||
const splitPath = path.split("/");
|
const splitPath = path.split("/");
|
||||||
switch (splitPath[0]) {
|
switch (splitPath[0]) {
|
||||||
|
case "block":
|
||||||
case "blocks": {
|
case "blocks": {
|
||||||
return new Response(
|
return new Response(
|
||||||
JSON.stringify(await readBlocks(resourcePath)),
|
JSON.stringify(await readBlocks(resourcePath)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case "item":
|
||||||
|
case "items": {
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify(await readBlocks(resourcePath)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return new Response("invalid path", { status: 400 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ export const versionCompat = (version: string, targetVersion: string) => {
|
|||||||
const versionSplit = version.split(".");
|
const versionSplit = version.split(".");
|
||||||
const targetVersionSplit = targetVersion.split(".");
|
const targetVersionSplit = targetVersion.split(".");
|
||||||
for (let i = 0; i < versionSplit.length; i++) {
|
for (let i = 0; i < versionSplit.length; i++) {
|
||||||
if (versionSplit[i] > targetVersionSplit[i]) {
|
if (versionSplit[i] ?? "0" > targetVersionSplit[i] ?? "0") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,4 +11,6 @@ tmux send-keys "deno task bdev" C-m
|
|||||||
tmux split-window -h
|
tmux split-window -h
|
||||||
tmux send-keys "deno task fdev" C-m
|
tmux send-keys "deno task fdev" C-m
|
||||||
|
|
||||||
|
tmux split-window -v
|
||||||
|
|
||||||
tmux attach -t $SESSION
|
tmux attach -t $SESSION
|
||||||
|
@ -25,30 +25,35 @@ function TagList() {
|
|||||||
|
|
||||||
const [showNewTagModal, setShowNewTagModal] = useState(false);
|
const [showNewTagModal, setShowNewTagModal] = useState(false);
|
||||||
|
|
||||||
if (isLoading || !data) {
|
if (isLoading) {
|
||||||
return <Loader msg="Geez, when was the last time you swept?" />;
|
return <Loader msg="Geez, when was the last time you swept?" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ul class="flex flex-col gap-2">
|
<ul>
|
||||||
<li>
|
|
||||||
<button onClick={() => setShowNewTagModal(true)}>New Tag</button>
|
|
||||||
{showNewTagModal && (
|
|
||||||
<NewTagModal
|
|
||||||
close={() => {
|
|
||||||
setShowNewTagModal(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
{data.map((tag) => (
|
|
||||||
<li class="flex gap-2">
|
|
||||||
<Link to={`/editor/tags/${tag}`}>{tag}</Link>
|
|
||||||
<button>Delete</button>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
<Resources />
|
||||||
|
{false && (
|
||||||
|
<ul class="flex flex-col gap-2">
|
||||||
|
<li>
|
||||||
|
<button onClick={() => setShowNewTagModal(true)}>New Tag</button>
|
||||||
|
{showNewTagModal && (
|
||||||
|
<NewTagModal
|
||||||
|
close={() => {
|
||||||
|
setShowNewTagModal(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
{data?.map((tag) => (
|
||||||
|
<li class="flex gap-2">
|
||||||
|
<Link to={`/editor/tags/${tag}`}>{tag}</Link>
|
||||||
|
<button>Delete</button>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -92,7 +97,8 @@ function TagEditor() {
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setTag({ ...tag, replace: (e.target as any).checked })}
|
setTag({ ...tag, replace: (e.target as any).checked })}
|
||||||
/>
|
/>
|
||||||
{tag.values.map((value, i) => (
|
{
|
||||||
|
/* {tag.values.map((value, i) => (
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@ -115,7 +121,8 @@ function TagEditor() {
|
|||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))} */
|
||||||
|
}
|
||||||
{tag.values.length === 0 && (
|
{tag.values.length === 0 && (
|
||||||
<button onClick={() => setTag({ ...tag, values: [""] })}>
|
<button onClick={() => setTag({ ...tag, values: [""] })}>
|
||||||
Add Value
|
Add Value
|
||||||
@ -125,3 +132,25 @@ function TagEditor() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Resources() {
|
||||||
|
const { data, isLoading } = useSWR<{ name: string; images: string[] }[]>(
|
||||||
|
`/api/resources/blocks?format=48`,
|
||||||
|
fetchJson,
|
||||||
|
);
|
||||||
|
if (isLoading || !data) {
|
||||||
|
return <Loader msg="Your hard drive is full of... interesting things." />;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
{data.map((resource) => (
|
||||||
|
<li>
|
||||||
|
{resource.name}
|
||||||
|
<img class="min-w-12 max-h-16" src={resource.images[0]} />
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user