From b9ea2f7258d614782440eb3ba738fd4cbe6de6b4 Mon Sep 17 00:00:00 2001 From: jing Date: Mon, 13 Jul 2026 23:11:54 +1000 Subject: [PATCH] Deploy scripts + relay edit-cap (ship-check finding) - deploy/deploy.sh: build --base=/turncraft/ -> stage -> docker cp into forum-nginx -> reload -> curl verify; syncs relay code + restarts it. - deploy/setup-relay.sh: one-time relay container on forum-nginx's docker network + the nginx location block for /turncraft/ws. - relay: MAX_EDITS=400k grief ceiling (unbounded diff map could reach ~550MB if a bot painted the whole booth). Co-Authored-By: Claude Fable 5 --- deploy/deploy.sh | 40 ++++++++++++++++++++++++++++++++++++++++ deploy/setup-relay.sh | 38 ++++++++++++++++++++++++++++++++++++++ server/relay.mjs | 7 ++++++- 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100755 deploy/deploy.sh create mode 100755 deploy/setup-relay.sh diff --git a/deploy/deploy.sh b/deploy/deploy.sh new file mode 100755 index 0000000..dfa1ce2 --- /dev/null +++ b/deploy/deploy.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# TURNCRAFT deploy — partly.party/turncraft (games VPS humanjing@100.71.119.27) +# Pattern per deploy-map: build -> rsync to /tmp staging -> docker cp into +# forum-nginx web root -> reload -> curl verify. Run from the repo root. +# +# First-time setup (relay service + nginx routes): deploy/setup-relay.sh +set -euo pipefail + +VPS="humanjing@100.71.119.27" +STAGE="/tmp/turncraft-stage" +NGINX_CONTAINER="forum-nginx" +# Web root inside forum-nginx — verify with: +# docker exec forum-nginx sh -c 'grep -R "root " /etc/nginx/conf.d | head' +WEBROOT="${TURNCRAFT_WEBROOT:-/usr/share/nginx/html}" + +echo "== build ==" +npx vite build --base=/turncraft/ + +echo "== stage on VPS ==" +ssh "$VPS" "rm -rf $STAGE && mkdir -p $STAGE" +rsync -az --delete dist/ "$VPS:$STAGE/turncraft/" + +echo "== install into $NGINX_CONTAINER:$WEBROOT/turncraft ==" +ssh "$VPS" "docker exec $NGINX_CONTAINER rm -rf $WEBROOT/turncraft \ + && docker cp $STAGE/turncraft $NGINX_CONTAINER:$WEBROOT/turncraft \ + && docker exec $NGINX_CONTAINER nginx -s reload" + +echo "== relay code sync (server/) ==" +rsync -az --delete --exclude node_modules --exclude 'booth-state.json*' \ + server/ "$VPS:/home/humanjing/turncraft-relay/" +ssh "$VPS" "docker restart turncraft-relay >/dev/null 2>&1 || echo 'relay container not running — run deploy/setup-relay.sh'" + +echo "== verify ==" +curl -fsS -o /dev/null -w "static: %{http_code}\n" "https://partly.party/turncraft/?bust=$(date +%s)" +curl -fsS -o /dev/null -w "ws-route: %{http_code}\n" \ + -H 'Connection: Upgrade' -H 'Upgrade: websocket' \ + -H 'Sec-WebSocket-Version: 13' -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \ + "https://partly.party/turncraft/ws" || true # 101/400 = route alive; 404 = missing nginx block + +echo "done. If Cloudflare serves a stale bundle, purge the cache." diff --git a/deploy/setup-relay.sh b/deploy/setup-relay.sh new file mode 100755 index 0000000..a0b892a --- /dev/null +++ b/deploy/setup-relay.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# One-time TURNCRAFT relay setup on the games VPS. +# - runs the relay as a docker container on forum-nginx's network +# - prints the nginx location blocks to add to the partly.party server conf +set -euo pipefail + +VPS="humanjing@100.71.119.27" + +rsync -az --exclude node_modules --exclude 'booth-state.json*' \ + server/ "$VPS:/home/humanjing/turncraft-relay/" + +ssh "$VPS" bash -s <<'EOF' +set -euo pipefail +NET=$(docker inspect forum-nginx --format '{{range $k, $_ := .NetworkSettings.Networks}}{{$k}}{{end}}' | head -1) +echo "forum-nginx network: $NET" +docker rm -f turncraft-relay 2>/dev/null || true +docker run -d --name turncraft-relay --restart unless-stopped \ + --network "$NET" \ + -v /home/humanjing/turncraft-relay:/app -w /app \ + -e HOST=0.0.0.0 -e PORT=8433 \ + node:22-alpine sh -c "npm ci --omit=dev && exec node relay.mjs" +sleep 3 +docker logs --tail 5 turncraft-relay +EOF + +cat <<'NGINX' + +Add to the partly.party server block (conf.d), then nginx -s reload: + + location /turncraft/ws { + proxy_pass http://turncraft-relay:8433; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Origin $http_origin; + proxy_read_timeout 300s; + } +NGINX diff --git a/server/relay.mjs b/server/relay.mjs index 6387539..b90a68e 100644 --- a/server/relay.mjs +++ b/server/relay.mjs @@ -25,6 +25,9 @@ const MAX_PEERS = 24; const MAX_FRAME_BYTES = 2048; const MAX_MSGS_PER_SEC = 40; const MAX_NAME_LEN = 24; +// Grief ceiling: the diff map must stay bounded (18M voxels × ~30B/entry +// would be ~550MB if a bot painted the whole booth). ~400k edits ≈ 25MB. +const MAX_EDITS = 400_000; const ALLOWED_ORIGINS = [ /^https:\/\/([a-z0-9-]+\.)?partly\.party$/, /^https?:\/\/localhost(:\d+)?$/, @@ -132,7 +135,9 @@ wss.on('connection', (ws) => { case 'edit': { if (!inBounds(m.x, m.y, m.z)) return; if (!isInt(m.id) || m.id < 0 || m.id > MAX_BLOCK_ID) return; - edits.set(`${m.x},${m.y},${m.z}`, m.id); + const key = `${m.x},${m.y},${m.z}`; + if (!edits.has(key) && edits.size >= MAX_EDITS) return; + edits.set(key, m.id); dirty = true; broadcast({ t: 'edit', x: m.x, y: m.y, z: m.z, id: m.id }, id); break;