Improve networking

This commit is contained in:
2026-09-25 00:08:01 -03:00
parent 6458bc0440
commit 2a2ccae9ce
18 changed files with 600 additions and 162 deletions
+28 -10
View File
@@ -70,7 +70,7 @@ game.onmessage = (event: MessageEvent<GameToHost>) => {
};
// what deno task build made. no index means the build failed or never ran, and the game never runs without its mods
function read_mods(): Extract<HostToGame, { type: "init" }>["mods"] {
function read_mods(): Pick<Extract<HostToGame, { type: "init" }>, "mods" | "atlas"> {
let index: ServerModIndex;
try {
index = JSON.parse(Deno.readTextFileSync(`${SERVER_MODS_DIR}/index.json`));
@@ -78,12 +78,15 @@ function read_mods(): Extract<HostToGame, { type: "init" }>["mods"] {
console.error(`No ${SERVER_MODS_DIR}/index.json, run deno task build first (it also reports mod errors)`);
Deno.exit(1);
}
return index.mods.map(({ listing, server }) => ({
listing,
data: JSON.parse(Deno.readTextFileSync(`${STATIC_ROOT}/${listing.data}`)),
server_code: server ? Deno.readTextFileSync(server) : undefined,
worldgen_code: listing.worldgen ? Deno.readTextFileSync(`${STATIC_ROOT}/${listing.worldgen}`) : undefined,
}));
return {
atlas: index.atlas,
mods: index.mods.map(({ listing, server }) => ({
listing,
data: JSON.parse(Deno.readTextFileSync(`${STATIC_ROOT}/${listing.data}`)),
server_code: server ? Deno.readTextFileSync(server) : undefined,
worldgen_code: listing.worldgen ? Deno.readTextFileSync(`${STATIC_ROOT}/${listing.worldgen}`) : undefined,
})),
};
}
game.onerror = (event) => {
@@ -91,10 +94,25 @@ game.onerror = (event) => {
Deno.exit(1);
};
const mods = read_mods();
const { mods, atlas } = read_mods();
console.log(`Mods: ${mods.map((mod) => `${mod.listing.id} ${mod.listing.version}`).join(", ") || "none"}`);
const save = read_world();
post({ type: "init", save, default_seed: Deno.env.get("SEED") ?? crypto.randomUUID(), mods });
post({ type: "init", save, default_seed: Deno.env.get("SEED") ?? crypto.randomUUID(), atlas, mods });
// mod files and the atlas are named by their hash, so they never change and pages on other origins can load them
async function serve_static(req: Request, url: URL) {
const response = await serveDir(req, { fsRoot: STATIC_ROOT, quiet: true });
const shared = url.pathname.startsWith("/mods/") || url.pathname.startsWith("/assets/");
if (shared && response.ok) {
const headers = new Headers(response.headers);
headers.set("Access-Control-Allow-Origin", "*");
if (url.pathname.startsWith("/mods/") || /^\/assets\/sprites\/textures\.[0-9a-f]+\./.test(url.pathname)) {
headers.set("Cache-Control", "public, max-age=31536000, immutable");
}
return new Response(response.body, { status: response.status, statusText: response.statusText, headers });
}
return response;
}
function handle_socket(socket: WebSocket) {
const conn = next_conn++;
@@ -147,5 +165,5 @@ Deno.serve({ port: PORT, onListen: ({ port }) => console.log(`bworld server on h
return Response.redirect(new URL("/client/", url), 302);
}
return serveDir(req, { fsRoot: STATIC_ROOT, quiet: true });
return serve_static(req, url);
});