resource extraction and reading

This commit is contained in:
2024-10-20 13:41:03 -06:00
parent 3d9b877661
commit 44c1862869
15 changed files with 353 additions and 9 deletions

View File

@@ -0,0 +1,80 @@
import { encodeBase64 } from "@std/encoding/base64";
import { readDirFiles } from "../util/readDir.ts";
interface BlockItem {
name: string;
resourceLocation: string;
images: string[];
}
export const readBlocks = async (path: string) => {
const blocks: BlockItem[] =
(await readDirFiles(path + "/assets/minecraft/blockstates"))
.map((b) => ({
name: b.replace(".json", ""),
resourceLocation: "minecraft:" + b.replace(".json", ""),
images: [],
}));
const texPath = path + "/assets/minecraft/textures/block";
for await (const image of Deno.readDir(texPath)) {
for (const block of blocks) {
if (image.name.startsWith(block.name)) {
const data = await Deno.readFile(texPath + "/" + image.name);
block.images.push("image/png;base64," + encodeBase64(data));
}
}
}
return blocks;
};
export const readItems = async (path: string) => {
const items: BlockItem[] =
(await readDirFiles(path + "/assets/minecraft/models/item")).map((i) => ({
name: i.replace(".json", ""),
resourceLocation: "minecraft:" + i.replace(".json", ""),
images: [],
})).slice(0, 10);
for (const item of items) {
const data = await Deno.readFile(
path + "/assets/minecraft/models/item/" + item.name + ".json",
);
const json = JSON.parse(new TextDecoder().decode(data));
const texDir = path + "/assets/minecraft/textures/";
if (json.textures) {
const texLoc = json.textures.layer0;
if (texLoc) {
const data = await Deno.readFile(
texDir + texLoc.replace("minecraft:", "") + ".png",
);
item.images.push("image/png;base64," + encodeBase64(data));
}
} else if (json.parent) {
const parent = await Deno.readFile(
path + "/assets/minecraft/models/" +
json.parent.replace("minecraft:", "") + ".json",
);
const parentJson = JSON.parse(new TextDecoder().decode(parent));
if (parentJson.textures) {
let texLoc = parentJson.textures.all;
if (!texLoc) texLoc = parentJson.textures.side;
if (!texLoc) texLoc = parentJson.textures.top;
if (!texLoc) texLoc = parentJson.textures.bottom;
if (texLoc) {
const data = await Deno.readFile(
texDir + texLoc.replace("minecraft:", "") + ".png",
);
item.images.push("image/png;base64," + encodeBase64(data));
}
}
}
}
return items;
};
if (import.meta.main) {
const path = "./resources/1.21.1";
console.log(await readItems(path));
}

View File

@@ -0,0 +1,37 @@
import type { Router } from "../router.ts";
import { readDirDirs } from "../util/readDir.ts";
import { versionCompat } from "../util/versionCompat.ts";
import { readBlocks } from "./readers.ts";
export const createResourcesRoutes = (router: Router) => {
router.route("/api/resources/:path*")
.get(async (req, ctx) => {
const path = ctx.params.path;
if (!path) {
return new Response("no path provided", { status: 400 });
}
const format = ctx.url.searchParams.get("format");
if (!format) {
return new Response("no format provided", { status: 400 });
}
const packVersion = await Deno.readTextFile(
"./pack_versions/" + format + ".json",
);
const packVersionJson = JSON.parse(packVersion);
const mcVersion = packVersionJson.mcVersion;
const resourceVersions = await readDirDirs("./resources");
for (const resourceVersion of resourceVersions) {
if (versionCompat(resourceVersion, mcVersion)) {
const resourcePath = "./resources/" + resourceVersion;
const splitPath = path.split("/");
switch (splitPath[0]) {
case "blocks": {
return new Response(
JSON.stringify(await readBlocks(resourcePath)),
);
}
}
}
}
});
};

58
server/resources/unzip.ts Normal file
View File

@@ -0,0 +1,58 @@
import { BearMetalStore } from "@bearmetal/store";
import { ZipReader } from "@zip.js/zip.js";
import { ensureFile } from "@std/fs";
export async function unzipResources(mcVersion?: string) {
using store = new BearMetalStore();
mcVersion = mcVersion || await currentVersion(store);
console.log("mcVersion", mcVersion);
if (!mcVersion) return;
const blob = await Deno.open(
store.get("mcPath") + "/versions/" + mcVersion + "/" + mcVersion + ".jar",
);
const zip = new ZipReader(blob);
for (const entry of await zip.getEntries()) {
if (
entry.filename.startsWith("assets/") || entry.filename.startsWith("data/")
) {
// console.log("entry", entry);
await ensureFile(`./resources/${mcVersion}/${entry.filename}`);
const writer = await Deno.open(
`./resources/${mcVersion}/${entry.filename}`,
{ write: true },
);
await entry.getData?.(writer);
}
}
}
async function currentVersion(store: BearMetalStore) {
const mcPath = store.get("mcPath");
if (!mcPath) return;
const versions = Array.from(Deno.readDirSync(mcPath + "/versions")).filter(
(d) => d.isDirectory,
).map((d) => d.name).sort();
let version = versions.pop();
let found = false;
versionC:
while (!found) {
for await (const file of Deno.readDir(mcPath + "/versions/" + version)) {
if (file.name.endsWith(".jar")) {
found = true;
break versionC;
}
}
version = versions.pop();
}
return version;
}
if (import.meta.main) {
unzipResources();
}