#!/usr/bin/env bash # --------------------------------------------------------------------------- # Fix the "joining room" / dorm-load crash on the VPS (ns.radicade.app). # # Root cause (proven from Player.log 15:59 session): # Dorm Room 2 / SubRoom 2 references DataBlob ebb4bab8-7206-41b8-8458-1db103ed22c7, # but the file is missing from the VPS CDN storage. The 2023 client 404s on # GET /room/ebb4bab8-..., loops "Data Mismatch -> Redownloading room details", # then a circuits-chain promise fires SessionManager.FatalApplicationQuit. # # Two independent fixes; EITHER ONE unblocks the join. # # MODE 1 (data, no code change) : upload a valid minimal empty room-save blob # under the exact missing name via the admin API. # Run from anywhere (your Windows Git Bash works): # BOT_SECRET='' \ # bash VPS/fix-dorm-blob.sh # or: bash VPS/fix-dorm-blob.sh '' # # MODE 2 (code, durable) : deploy the RoomUtils.cs self-heal already in # this repo (clears stale references on every room fetch) and restart # the service. Run ON the VPS, in the repo checkout: # bash VPS/fix-dorm-blob.sh --deploy # --------------------------------------------------------------------------- set -euo pipefail HOST="${HOST:-https://ns.radicade.app}" BLOB="ebb4bab8-7206-41b8-8458-1db103ed22c7" BLOB_DIR="${BLOB_DIR:-/tmp}" mode1() { local secret="${1:-${BOT_SECRET:-}}" if [ -z "$secret" ]; then echo "ERROR: no secret given." echo "Usage: BOT_SECRET='' bash $0" echo " or: bash $0 ''" exit 2 fi # Minimal valid empty room-save (same 4-byte protobuf the working template # subrooms carry): field2 varint 2, field3 empty bytes. printf '\x10\x02\x1a\x00' > "$BLOB_DIR/$BLOB" echo "[1/2] Uploading $BLOB (4 bytes) via admin API..." local code code=$(curl -sS -m 30 -o /tmp/upl-resp.txt -w "%{http_code}" -X POST \ "$HOST/admin/rooms/upload/datablob?key=$secret&name=$BLOB" \ -F "file=@$BLOB_DIR/$BLOB") || { echo "Upload request failed (network) - is the VPS backend back up?"; exit 1; } head -c 200 /tmp/upl-resp.txt 2>/dev/null; echo if [ "$code" != "200" ]; then echo "Upload failed (HTTP $code). 401 => wrong secret; 000/timeout => VPS backend still hung." exit 1 fi echo "[2/2] Verifying public fetch..." code=$(curl -sS -m 30 -o /dev/null -w "%{http_code}" "$HOST/room/$BLOB") echo "GET /room/$BLOB -> $code" if [ "$code" = "200" ]; then echo "OK: dorm blob now resolvable. Relaunch RecRoom - joining rooms should work." else echo "Verification failed (HTTP $code)"; exit 1 fi } mode2() { echo "Deploying RoomUtils self-heal (run on the VPS, in the repo checkout):" git pull origin main cd Server && dotnet publish -c Release -o publish systemctl restart radicade-server 2>/dev/null \ || echo "NOTE: restart the ASP.NET service however it is named on this host (systemctl list-units | grep -i radicade)" sleep 5 local code code=$(curl -sS -m 30 -o /dev/null -w "%{http_code}" "$HOST/ns" || echo 000) echo "GET $HOST/ns -> $code (expect 200)" echo "On the first dorm fetch, the server log should show:" echo " [RoomUtils] Cleared 1 missing DataBlob reference(s) in room 2 (files not in CDN storage)." } case "${1:-data}" in data) mode1 "${2:-}" ;; deploy) mode2 ;; *) echo "usage: $0 [data|deploy] (data mode: pass the BotSecret as \$2 or via BOT_SECRET env)"; exit 2 ;; esac