New modding system
This commit is contained in:
+19
-12
@@ -6,7 +6,7 @@
|
||||
import { fromFileUrl, join } from "@std/path";
|
||||
import { type Host, serve_static, start_host } from "../server/host.ts";
|
||||
|
||||
// where the project was built from: build/ and server_mods/ are bundled into the app with --include
|
||||
// where the project was built from: build/ and server_mods/ (the .bmod files) are bundled into the app with --include
|
||||
const ROOT = fromFileUrl(new URL("../", import.meta.url));
|
||||
const BUILD_DIR = join(ROOT, "build");
|
||||
|
||||
@@ -19,17 +19,16 @@ const default_server = Deno.env.get("BWORLD_SERVER") ?? config.server ?? "";
|
||||
const win = new Deno.BrowserWindow({ title: "bworld", width: 1280, height: 720 });
|
||||
|
||||
// the singleplayer game server, started the first time singleplayer connects so players who only join other servers
|
||||
// don't get a world made for them
|
||||
let host: Host | undefined;
|
||||
// don't get a world made for them. it plays the .bmod files the app was built with
|
||||
let host: Promise<Host> | undefined;
|
||||
|
||||
function singleplayer_host(): Host {
|
||||
if (!host) {
|
||||
function singleplayer_host(): Promise<Host> {
|
||||
host ??= (async () => {
|
||||
const worlds = join(data_dir(), "worlds");
|
||||
Deno.mkdirSync(worlds, { recursive: true });
|
||||
host = start_host({
|
||||
return await start_host({
|
||||
build_dir: BUILD_DIR,
|
||||
server_mods_dir: join(ROOT, "server_mods"),
|
||||
root: ROOT,
|
||||
world_file: join(worlds, "world.json"),
|
||||
on_fatal(message) {
|
||||
console.error(message);
|
||||
@@ -37,7 +36,7 @@ function singleplayer_host(): Host {
|
||||
Deno.exit(1);
|
||||
},
|
||||
});
|
||||
}
|
||||
})();
|
||||
return host;
|
||||
}
|
||||
|
||||
@@ -48,7 +47,7 @@ win.addEventListener("close", async (event) => {
|
||||
}
|
||||
event.preventDefault();
|
||||
try {
|
||||
await host.shutdown();
|
||||
await (await host).shutdown();
|
||||
} catch (e) {
|
||||
console.error((e as Error).message);
|
||||
}
|
||||
@@ -56,7 +55,7 @@ win.addEventListener("close", async (event) => {
|
||||
});
|
||||
|
||||
// deno desktop binds this to a private local address and opens the window on it, the port given here is ignored
|
||||
Deno.serve((req) => {
|
||||
Deno.serve(async (req) => {
|
||||
const url = new URL(req.url);
|
||||
if (url.pathname === "/") {
|
||||
// ?server= fills in the address field, without it the field would start with this app's own address.
|
||||
@@ -66,8 +65,16 @@ Deno.serve((req) => {
|
||||
start.searchParams.set("singleplayer", "");
|
||||
return Response.redirect(start, 302);
|
||||
}
|
||||
if (url.pathname === "/ws") {
|
||||
return singleplayer_host().handle(req);
|
||||
// the singleplayer server's socket and its .bmod downloads
|
||||
if (url.pathname === "/ws" || url.pathname.startsWith("/mods/")) {
|
||||
try {
|
||||
return (await singleplayer_host()).handle(req);
|
||||
} catch (e) {
|
||||
// its mods have problems, the title screen shows why the connection failed
|
||||
console.error((e as Error).message);
|
||||
host = undefined;
|
||||
return new Response((e as Error).message, { status: 500 });
|
||||
}
|
||||
}
|
||||
return serve_static(BUILD_DIR, req, url);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user