Improve networking
This commit is contained in:
@@ -826,25 +826,36 @@ server's atlas, which gets a hash-named URL the same way.
|
||||
```
|
||||
client server
|
||||
│ hello { name, protocol } │
|
||||
├────────────────────────────────────────►│
|
||||
│ welcome { seed, atlas, mods[] } │ mods[i] = { id, name, version, hash,
|
||||
│◄────────────────────────────────────────┤ data, client?, worldgen? } (urls)
|
||||
├────────────────────────────────────────►│ a different protocol gets rejected { reason }
|
||||
│ welcome { protocol, seed, atlas, │ mods[i] = { id, name, version, hash,
|
||||
│ mods[] } │ data, client?, worldgen?, sha256 }
|
||||
│◄────────────────────────────────────────┤ atlas = { png, json, sha256 } (paths on the server)
|
||||
│ │
|
||||
│ [cross-origin: confirm screen] │
|
||||
│ fetch data, atlas, scripts │
|
||||
│ check hashes, register data, │
|
||||
│ run client setup(), start workers │
|
||||
│ download the atlas and every mod file, │
|
||||
│ check each one's sha256, register data │
|
||||
│ in the listed order, run client │
|
||||
│ setup(), start chunk workers │
|
||||
│ │
|
||||
│ ready │
|
||||
├────────────────────────────────────────►│
|
||||
│ join { players, changes, inventory } │ player_join fires on the server here
|
||||
│ join { id, name, players, changes, │ the player is created here, player_join fires,
|
||||
│ spawn, selected_slot } │ and their inventory follows as container messages
|
||||
│◄────────────────────────────────────────┤
|
||||
```
|
||||
|
||||
- The client registers the base game, then each mod's data **in the order the server lists them**.
|
||||
- The client registers each mod's data **in the order the server lists them**.
|
||||
- Every file is checked against its SHA-256 before it's used, and scripts are imported from the checked bytes (as
|
||||
`blob:` URLs), so what runs is exactly what was checked. The client code is in `client/handshake.ts` and
|
||||
`client/mods.ts`.
|
||||
- If any download, hash check or `setup` fails, the client disconnects and shows which mod failed. It never joins with
|
||||
some mods missing.
|
||||
- The `protocol` in `hello` is the game's protocol version. A mismatch is rejected before any mod code is downloaded.
|
||||
- The `protocol` in `hello` is the game's protocol version (`PROTOCOL_VERSION` in `common/protocol.ts`). A mismatch is
|
||||
rejected before anything is downloaded.
|
||||
- Until `ready`, the connection isn't a player: other players don't see it, and anything it sends besides `ready` is
|
||||
ignored. A client that doesn't send `ready` within 60 seconds is rejected.
|
||||
- Mod files and the atlas are served with `Access-Control-Allow-Origin: *` and cached for a year, since their paths
|
||||
change whenever their content does.
|
||||
- Leaving a server reloads the page, so one server's mod code never stays loaded while playing on another.
|
||||
|
||||
## Security
|
||||
@@ -1107,8 +1118,8 @@ loading mods (the base game and the template), their scripts and worldgen, saves
|
||||
|
||||
## Implementation plan
|
||||
|
||||
Steps 1–4 are done and 5, 6 and 9 mostly, enough that a mod made from the template loads and runs. Each step keeps the
|
||||
game working:
|
||||
Steps 1–5 are done and 6 and 9 mostly, enough that a mod made from the template loads and runs. Each step keeps the game
|
||||
working:
|
||||
|
||||
1. **Game server core.** Move `client/generation.ts` to `common/` (it already only needs constants and the rng package)
|
||||
and have the server generate terrain. Move world state, chunks, tile data and player inventories into a game server
|
||||
@@ -1123,9 +1134,7 @@ game working:
|
||||
build the combined atlas (textures are currently all named `bworld:<file>`), bundle scripts per side, and write
|
||||
hashed output to `build/mods/` and `server_mods/`. _Done._
|
||||
5. **Delivery.** Split `welcome` into `welcome` / `ready` / `join`. Clients download, verify and run mods before
|
||||
joining. Add the confirm screen for cross-origin servers and CORS headers on the server. _Partly done:_ `welcome`
|
||||
lists the mods and clients download and run them before creating the world, but the server doesn't wait for `ready`
|
||||
(its messages just queue up meanwhile), hashes aren't checked, and there's no confirm screen or CORS yet.
|
||||
joining. Add the confirm screen for cross-origin servers and CORS headers on the server. _Done._
|
||||
6. **Server scripts.** Components, events, commands, system, storage and `ctx.recipes`. Move `FURNACE_RECIPES` and
|
||||
`FUEL_VALUES` into the recipe registry. _Mostly done_ (`server/game/mod_runtime.ts`). Not yet: `on_click` (clients
|
||||
don't report left clicks on blocks), item `on_use` (there's no item use action), `world.get_state` / `set_state`
|
||||
|
||||
Reference in New Issue
Block a user