115 lines
3.5 KiB
TypeScript

import { SockpuppetPlus } from "@cgg/sockpuppet";
import { serveDir, serveFile } from "@std/http/file-server";
import { BearMetalStore } from "@bearmetal/store";
import { ensureDir } from "@std/fs";
import { Router } from "./router.ts";
const installPath = Deno.env.get("BMP_INSTALL_DIR") || "./";
const sockpuppet = new SockpuppetPlus();
sockpuppet.addHandler((req: Request) => {
const url = new URL(req.url);
if (!url.pathname.startsWith("/images")) return;
return serveFile(req, url.searchParams.get("location") as string);
});
const router = new Router();
router.route("/api/dir")
.get(async () => {
using store = new BearMetalStore();
const mcPath = store.get("mcPath") as string;
if (mcPath) {
const worlds: {
world: string;
icon: string;
path: string;
}[] = [];
try {
for await (const file of Deno.readDir(mcPath)) {
if (file.isDirectory && file.name.startsWith("saves")) {
for await (
const world of Deno.readDir(mcPath + "/" + file.name)
) {
if (world.isDirectory) {
for await (
const f of Deno.readDir(
mcPath + "/" + file.name + "/" + world.name,
)
) {
if (f.name.endsWith(".dat")) {
worlds.push({
world: world.name,
icon: Deno.realPathSync(
mcPath + "/" + file.name + "/" + world.name +
"/icon.png",
),
path: Deno.realPathSync(
mcPath + "/" + file.name + "/" + world.name,
),
});
}
}
}
}
}
}
} catch (e: any) {
store.set("mcPath", "");
return new Response(e, { status: 500 });
}
return new Response(JSON.stringify({ worlds, mcPath }), {
status: 200,
});
}
return new Response(JSON.stringify({ mcPath }), {
status: mcPath ? 200 : 500,
});
})
.post(async (req) => {
using store = new BearMetalStore();
const formData = await req.formData();
const dir = formData.get("mcPath") as string;
if (!dir) return new Response(null, { status: 400 });
store.set("mcPath", dir);
if (!store.get("mcPath")) return new Response(null, { status: 500 });
return new Response(null, { status: 200 });
});
router.route("/api/world")
.post(async (req) => {
using store = new BearMetalStore();
const worldPath = await req.text();
if (!worldPath) return new Response(null, { status: 400 });
const mcPath = store.get("mcPath") as string;
if (!mcPath) {
return new Response("Tried to set world, but MC path is not set.", {
status: 500,
});
}
const realWorldPath = Deno.realPathSync(worldPath);
store.set("world", realWorldPath);
store.set("packlocation", realWorldPath + "/datapacks/bmp_dev");
await ensureDir(store.get("packlocation") as string);
return new Response(null, { status: 200 });
})
.get((req) => {
using store = new BearMetalStore();
const worldPath = store.get("world") as string;
if (!worldPath) return new Response(null, { status: 400 });
return serveFile(req, worldPath);
});
sockpuppet.addHandler((req: Request) => {
if (new URL(req.url).pathname.startsWith("/api")) return;
return serveDir(req, {
fsRoot: installPath + "dist",
});
});
sockpuppet.addHandler(router.handle);