It's a router, it does route things
This commit is contained in:
parent
89502213c4
commit
70b489213c
@ -12,7 +12,7 @@
|
|||||||
},
|
},
|
||||||
"imports": {
|
"imports": {
|
||||||
"@babel/plugin-transform-react-jsx-development": "npm:@babel/plugin-transform-react-jsx-development@^7.25.7",
|
"@babel/plugin-transform-react-jsx-development": "npm:@babel/plugin-transform-react-jsx-development@^7.25.7",
|
||||||
"@bearmetal/store": "jsr:@bearmetal/store@^0.0.4",
|
"@bearmetal/store": "jsr:@bearmetal/store@^0.0.5",
|
||||||
"@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",
|
||||||
|
8
deno.lock
generated
8
deno.lock
generated
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": "4",
|
"version": "4",
|
||||||
"specifiers": {
|
"specifiers": {
|
||||||
"jsr:@bearmetal/store@^0.0.4": "0.0.4",
|
"jsr:@bearmetal/store@^0.0.5": "0.0.5",
|
||||||
"jsr:@std/cli@^1.0.6": "1.0.6",
|
"jsr:@std/cli@^1.0.6": "1.0.6",
|
||||||
"jsr:@std/encoding@^1.0.5": "1.0.5",
|
"jsr:@std/encoding@^1.0.5": "1.0.5",
|
||||||
"jsr:@std/fmt@^1.0.2": "1.0.2",
|
"jsr:@std/fmt@^1.0.2": "1.0.2",
|
||||||
@ -28,8 +28,8 @@
|
|||||||
"npm:vite@^5.4.8": "5.4.9"
|
"npm:vite@^5.4.8": "5.4.9"
|
||||||
},
|
},
|
||||||
"jsr": {
|
"jsr": {
|
||||||
"@bearmetal/store@0.0.4": {
|
"@bearmetal/store@0.0.5": {
|
||||||
"integrity": "f5859476184d6f7b3957d18c7c82a37b6b89bb75e18db3186fde94ccb4253dab",
|
"integrity": "d17da24c91bcc05707deb8a55017ebdf5d8eebd2f6293dcb2bbfac57e4e3b395",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"jsr:@std/fs@^1.0.4"
|
"jsr:@std/fs@^1.0.4"
|
||||||
]
|
]
|
||||||
@ -1391,7 +1391,7 @@
|
|||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"jsr:@bearmetal/store@^0.0.4",
|
"jsr:@bearmetal/store@^0.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",
|
||||||
"npm:@babel/plugin-transform-react-jsx-development@^7.25.7",
|
"npm:@babel/plugin-transform-react-jsx-development@^7.25.7",
|
||||||
|
205
server/main.ts
205
server/main.ts
@ -2,18 +2,107 @@ import { SockpuppetPlus } from "@cgg/sockpuppet";
|
|||||||
import { serveDir, serveFile } from "@std/http/file-server";
|
import { serveDir, serveFile } from "@std/http/file-server";
|
||||||
import { BearMetalStore } from "@bearmetal/store";
|
import { BearMetalStore } from "@bearmetal/store";
|
||||||
import { ensureDir } from "@std/fs";
|
import { ensureDir } from "@std/fs";
|
||||||
|
import { Router } from "./router.ts";
|
||||||
|
|
||||||
const installPath = Deno.env.get("BMP_INSTALL_DIR") || "./";
|
const installPath = Deno.env.get("BMP_INSTALL_DIR") || "./";
|
||||||
|
|
||||||
const sockpuppet = new SockpuppetPlus();
|
const sockpuppet = new SockpuppetPlus();
|
||||||
sockpuppet.addHandler(async (req: Request) => {
|
sockpuppet.addHandler((req: Request) => {
|
||||||
console.log(req.url);
|
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
if (!url.pathname.startsWith("/images")) return;
|
if (!url.pathname.startsWith("/images")) return;
|
||||||
|
|
||||||
return serveFile(req, url.searchParams.get("location") as string);
|
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) => {
|
sockpuppet.addHandler((req: Request) => {
|
||||||
if (new URL(req.url).pathname.startsWith("/api")) return;
|
if (new URL(req.url).pathname.startsWith("/api")) return;
|
||||||
|
|
||||||
@ -22,114 +111,4 @@ sockpuppet.addHandler((req: Request) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
sockpuppet.addHandler(async (req: Request) => {
|
sockpuppet.addHandler(router.handle);
|
||||||
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<string>("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 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
68
server/router.ts
Normal file
68
server/router.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
export class Router {
|
||||||
|
private routes: Record<string, Handler[]> = {};
|
||||||
|
|
||||||
|
public route(route: string) {
|
||||||
|
const methods: Record<string, Handler> = {
|
||||||
|
get: () => undefined,
|
||||||
|
post: () => undefined,
|
||||||
|
put: () => undefined,
|
||||||
|
delete: () => undefined,
|
||||||
|
};
|
||||||
|
this.routes[route] = this.routes[route] || [];
|
||||||
|
this.routes[route].push((r, c) => {
|
||||||
|
switch (r.method) {
|
||||||
|
case "GET":
|
||||||
|
return methods.get?.(r, c);
|
||||||
|
case "POST":
|
||||||
|
return methods.post?.(r, c);
|
||||||
|
case "PUT":
|
||||||
|
return methods.put?.(r, c);
|
||||||
|
case "DELETE":
|
||||||
|
return methods.delete?.(r, c);
|
||||||
|
default:
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
get(handler: Handler) {
|
||||||
|
methods.get = handler;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
post(handler: Handler) {
|
||||||
|
methods.post = handler;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
put(handler: Handler) {
|
||||||
|
methods.put = handler;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
delete(handler: Handler) {
|
||||||
|
methods.delete = handler;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public handle = async (req: Request): Promise<Response> => {
|
||||||
|
const url = new URL(req.url);
|
||||||
|
const route = url.pathname;
|
||||||
|
if (route in this.routes) {
|
||||||
|
let res;
|
||||||
|
for (const handler of this.routes[route]) {
|
||||||
|
res = await handler(req, {
|
||||||
|
url,
|
||||||
|
state: {},
|
||||||
|
});
|
||||||
|
if (res) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Response("Not found", { status: 404 });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Handler = (
|
||||||
|
req: Request,
|
||||||
|
ctx: Context,
|
||||||
|
) => Promise<Response | undefined> | Response | undefined;
|
Loading…
x
Reference in New Issue
Block a user