Record phase 4 website, ArcViewer and Caddy results in the plan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+72
-4
@@ -625,6 +625,68 @@ on the profile.
|
||||
|
||||
### Phase 4: Website, viewer, Caddy
|
||||
|
||||
**Steps 1–2 done and both checks passed 2026-11-08**, on a dev stand-in for
|
||||
the vhost: the importer into `.data/plebleader/dev/db/`, the API on 8042
|
||||
(`PublicBaseUrl=http://127.0.0.1:8890`), and an ad-hoc `nix shell
|
||||
nixpkgs#caddy` on `http://127.0.0.1:8890` with the routes below
|
||||
(`.data/plebleader/dev/{run-api.sh,Caddyfile}`). Use `127.0.0.1`, not
|
||||
`localhost`: the website sends `localhost` to the real upstream API. Commits:
|
||||
server `7cc964a`, website `f5194ee3`, `9ebe84ea`, `8d540642`, all local
|
||||
(not pushed yet). Step 3 (nix-pleb) is still open.
|
||||
|
||||
- **Phase 3 check passed.** `/u/pleb`: 11,608.35pp, #3,861 global, US #1,643,
|
||||
672 ranked and 3,565 total scores, unranked difficulties with stars (8.33★
|
||||
on the Phase 1 test map), the skill triangle with monthly history. The
|
||||
leaderboard page and `/score/{id}` (accuracy graphs from local score stats)
|
||||
work too.
|
||||
- **Server fix:** the profile page calls `GET /v2/player/{id}/hydrate`, which
|
||||
the live API has and the public source doesn't (404, "Player not found").
|
||||
`Controllers/MirrorHydrateController.cs` rebuilds it from
|
||||
`PlayerController.Get` plus the `profile` object that the website's
|
||||
`process-hydrate.js` reads.
|
||||
- **Server run note:** `dotnet build` doesn't copy `wwwroot/` into `bin/`.
|
||||
Without it `PreviewController`'s constructor throws on `/images/Star.png`,
|
||||
and any controller that depends on it (`/user`, `/user/config`) returns 500.
|
||||
The dev run passes `--webroot <src>/wwwroot`; the Nix package uses `dotnet
|
||||
publish`, which copies it.
|
||||
- **Website, as built:** `IS_MIRROR` in `api-queue.js` is true when the API
|
||||
resolves to `/cors/blapi/`. In that case `BL_REPLAYS_URL` is `/watch/` and
|
||||
score stats come from `/cdn/scorestats/`. Every hardcoded
|
||||
`allpoland.github.io/ArcViewer/` link points at `/watch/` (except the clan
|
||||
page's embed). `public/watch/index.html` takes BL replay-viewer or ArcViewer
|
||||
parameters (`link`, `replayURL`, `scoreId`, `id`, optional `hash`) and
|
||||
redirects to `/arcviewer/?replayURL=…&url=/cdn/maps/<hash>.zip&noProxy=true`.
|
||||
It reads the hash from the replay filename
|
||||
(`<score>-<player>-<diff>-<mode>-<HASH>.bsor`); for `scoreId` it first asks
|
||||
`/cors/blapi/score/{id}` for the replay URL. Phase 5 can pass `hash=` for
|
||||
`.dat` replays. The analyzer icons are off by default (an upstream Patreon
|
||||
service). Clans, events, the socket page and the star-rating graph are still
|
||||
visible; they just show nothing.
|
||||
- **ArcViewer facts:** without `noProxy=true` it routes every non-whitelisted
|
||||
URL through `cors.bsmg.dev`, which can't reach a LAN host. When both `id`
|
||||
and `url` are given, `id` wins, so never send both. With no map parameter
|
||||
it looks up the replay's own hash on BeatSaver. The `deploy` build ships
|
||||
uncompressed `Build/` files, so no `Content-Encoding` headers are needed.
|
||||
Its own calls to `api.beatleader.com` (player card, leaderboard info) fail
|
||||
from this origin, so the player card stays blank; fixing that needs a Unity
|
||||
build, so it's left as is.
|
||||
- **Map zips:** BeatSaver's CDN serves `https://r2cdn.beatsaver.com/<hash>.zip`
|
||||
with `Access-Control-Allow-Origin: *` (it rejects HEAD, use GET). Caddy
|
||||
redirects to it when the archive has no zip, so the website always links
|
||||
the local path and the ~630 older maps outside `--maps-since` still play.
|
||||
- **Nix:** the website fork's `flake.nix` builds `packages.default` (yarn
|
||||
v1 offline, ~16 s; deps hash `sha256-ThGvMJfU…`). Its `postPatch` turns the
|
||||
themes' Google Fonts `@import url(...)` into `@import (css) url(...)`,
|
||||
because less would fetch them at build time. ArcViewer `deploy` at
|
||||
`c776256497b66f7c91a74162cfcd943b0f45ee2e` is
|
||||
`sha256-4A+aVnFrKyWQjFnH2N/CwoVIlwrcgV2fYYrtaOiodo0=` for `fetchFromGitHub`.
|
||||
|
||||
Still open for step 3: push both forks to Gitea, add the website flake as a
|
||||
nix-pleb input (nix-pleb currently has an uncommitted, staged `flake.lock`
|
||||
change that isn't ours), and give Caddy read access to the state dir
|
||||
(`StateDirectoryMode=0750` and `caddy` in group `plebleader`, phase 7). The
|
||||
vhost below is the tested version.
|
||||
|
||||
1. In the website fork, point `BL_REPLAYS_URL` (and the "watch replay" links)
|
||||
at `/arcviewer/?replayURL=<encoded local replay url>&url=<encoded /cdn/maps/<hash>.zip>`.
|
||||
Fall back to `id=<bsr>` only for hashes that have no local zip. Hide or stub
|
||||
@@ -645,20 +707,26 @@ on the profile.
|
||||
@plebleader_allowed remote_ip 127.0.0.1/32 ::1/128 192.168.1.36/32 192.168.254.21/32
|
||||
handle @plebleader_allowed {
|
||||
handle_path /cors/blapi/* { reverse_proxy http://127.0.0.1:8042 }
|
||||
handle_path /cdn/maps/* { root * /var/lib/plebleader/archive/beatsaver/zips; file_server }
|
||||
handle_path /cdn/maps/* {
|
||||
root * /var/lib/plebleader/archive/beatsaver/zips
|
||||
@nozip not file
|
||||
redir @nozip https://r2cdn.beatsaver.com{path} 302
|
||||
file_server
|
||||
}
|
||||
handle_path /cdn/* { root * /var/lib/plebleader/storage; file_server }
|
||||
handle_path /arcviewer/* { root * ${arcviewer}; file_server }
|
||||
handle_path /cors/cdn-assets-bl/* { reverse_proxy https://cdn.assets.beatleader.com { header_up Host {upstream_hostport} } }
|
||||
handle_path /cors/cdnbeatsaver/* { reverse_proxy https://cdn.beatsaver.com { header_up Host {upstream_hostport} } }
|
||||
handle { root * ${plebleader-website}; try_files {path} /index.html; file_server }
|
||||
# {path}/index.html serves /watch/; without it the SPA's 404 answers
|
||||
handle { root * ${plebleader-website}; try_files {path} {path}/index.html /index.html; file_server }
|
||||
}
|
||||
handle { respond "Forbidden" 403 }
|
||||
'';
|
||||
};
|
||||
```
|
||||
|
||||
ArcViewer's WebGL build may need `Content-Encoding` headers for `.br`/`.gz`
|
||||
files in `Build/`. Check which ones the `deploy` branch ships.
|
||||
Checked: the `deploy` branch ships uncompressed `Build/` files, so no
|
||||
`Content-Encoding` headers are needed.
|
||||
|
||||
**Check:** in Chromium, `https://incineroar.brenise.dev:4442/u/pleb` shows the
|
||||
profile and scores, and a replay opens in ArcViewer.
|
||||
|
||||
Reference in New Issue
Block a user