import { SockpuppetPlus } from "@cgg/sockpuppet"; import { serveDir, serveFile } from "@std/http/file-server"; import { BearMetalStore } from "@bearmetal/store"; import { ensureDir } from "@std/fs"; const installPath = Deno.env.get("BMP_INSTALL_DIR") || "./"; const sockpuppet = new SockpuppetPlus(); sockpuppet.addHandler(async (req: Request) => { console.log(req.url); const url = new URL(req.url); if (!url.pathname.startsWith("/images")) return; return serveFile(req, url.searchParams.get("location") as string); }); sockpuppet.addHandler((req: Request) => { if (new URL(req.url).pathname.startsWith("/api")) return; return serveDir(req, { fsRoot: installPath + "dist", }); }); sockpuppet.addHandler(async (req: Request) => { if (!new URL(req.url).pathname.startsWith("/api")) return; const store = new BearMetalStore(); const API_DIR_ROUTE = new URLPattern({ pathname: "/api/dir", }); const match = API_DIR_ROUTE.exec(req.url); if (!match) return; switch (req.method) { case "GET": { 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, }); } case "POST": { 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 }); } default: return new Response(null, { status: 405 }); } }); sockpuppet.addHandler(async (req: Request) => { if (!new URL(req.url).pathname.startsWith("/api")) return; const store = new BearMetalStore(); const API_WORLD_ROUTE = new URLPattern({ pathname: "/api/world", }); const match = API_WORLD_ROUTE.exec(req.url); if (!match) return; switch (req.method) { case "GET": { return new Response(store.get("world").split("/").pop() || "", { status: 200, }); } case "POST": { 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 }); } } });