The cup board asked for itself and got the gore board
The GET filter spelled its modes out as a literal `[^gzc]` character class, so `?m=u` sanitised to nothing, fell back to 'g', and the server answered the cup board's request with the gore board — which the client then printed in the cup board's words: 7121 kills as LEAGUE 7121. The filter is derived from MODES now, where the mode list has lived all along. And the client checks the answer it got: the response names the board it is, so a server that does not know a board (an old one, mid-deploy) makes the screen say THIS BOARD IS NOT UP YET instead of mislabelling another board's rows. Nothing beats something wrong on a leaderboard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
115c6089be
commit
058636fae3
2 files changed
+18
-4
No files matched your search
@@ -320,8 +320,12 @@ class Handler(SimpleHTTPRequestHandler):
|
||||
if path == '/ws':
|
||||
return self.handle_ws()
|
||||
if path == '/api/scores':
|
||||
want = re.sub(r'[^gzc]', '', (self.path.split('m=')[1].split('&')[0]
|
||||
if 'm=' in self.path else ''))[:1] or 'g'
|
||||
# DERIVED FROM MODES, never spelled out again (2026-08-31): this filter was a literal
|
||||
# `[^gzc]` character class, so the day the cup board was added the server answered its
|
||||
# requests with the GORE board — and the client printed 7121 kills as "LEAGUE 7121".
|
||||
want = (self.path.split('m=')[1].split('&')[0] if 'm=' in self.path else '')[:1]
|
||||
if want not in MODES:
|
||||
want = 'g' # an unknown board is the default one, never a new one
|
||||
with lock:
|
||||
return self.reply(200, {'m': want,
|
||||
'scores': public([r for r in load() if mode_of(r) == want])})
|
||||
|
||||
+12
-2
@@ -220,7 +220,13 @@ export function lastRun() { const r = last; last = null; return r; }
|
||||
export async function board(mode = MODE_GORE) {
|
||||
const r = await fetch(API + 'scores?m=' + mode, { cache: 'no-store' });
|
||||
if (!r.ok) throw new Error('board ' + r.status);
|
||||
return (await r.json()).scores || [];
|
||||
const d = await r.json();
|
||||
// THE SERVER NAMES THE BOARD IT ANSWERED WITH, and we check it (2026-08-31): a server that does
|
||||
// not know a board falls back to the default one, and rendering those rows here prints one
|
||||
// board's currency in another's words — gore kills as LEAGUE 7121, which is exactly what a
|
||||
// stale server did the day the cup board shipped. Nothing is better than something wrong.
|
||||
if (d.m && d.m !== mode) { const e = new Error('board not up'); e.absent = true; throw e; }
|
||||
return d.scores || [];
|
||||
}
|
||||
|
||||
// The SAME normalisation server.py's clean() applies. Both ends have to agree or nothing lines up:
|
||||
@@ -331,7 +337,11 @@ export async function drawRanks(rows, mode = MODE_GORE) {
|
||||
if (!rows) {
|
||||
el.innerHTML = '<p class="none">READING THE BOARD…</p>';
|
||||
try { rows = await board(mode); }
|
||||
catch { el.innerHTML = '<p class="none">THE BOARD IS UNREACHABLE.</p>'; return; }
|
||||
catch (e) {
|
||||
el.innerHTML = `<p class="none">${e && e.absent ? 'THIS BOARD IS NOT UP YET.'
|
||||
: 'THE BOARD IS UNREACHABLE.'}</p>`;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!rows.length) { el.innerHTML = '<p class="none">NOBODY IS ON THIS BOARD YET. BE FIRST.</p>'; return; }
|
||||
const me = savedName();
|
||||
|
||||
Reference in new issue
Block a user