feat: add native Windows broadcaster and live score modules

- streamer/windows: vash-broadcast.exe (setup/login/start/stop/status/doctor)
  with per-instance OBS, tosu and FFmpeg, a supervised worker, OCR room
  selection and OBS scene reconciliation; built and tested on Linux only
- streamer/relay.ts shared with Vash TV; Cloudflare Access proxy for dev/staging
- worker status validation and live score helpers for the site
- STREAMING_HANDOFF.md and streamer/ALPHA_TEST.md record what is unverified

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-18 22:02:25 +00:00
parent 9d5a046b40
commit 54444a77f0
45 changed files with 8168 additions and 643 deletions

View File

@@ -17,6 +17,7 @@ test('tosu tourney frames become per-player scores with map progress', () => {
beatmap: { id: 75, time: { live: 30_000, firstObject: 10_000, lastObject: 50_000 } },
tourney: {
ipcState: 3,
team: { left: 'Alpha ', right: 'Beta' },
clients: [
{
user: { id: 2, name: 'peppy' },
@@ -30,9 +31,27 @@ test('tosu tourney frames become per-player scores with map progress', () => {
ipcState: 3,
beatmapId: 75,
progress: 0.5,
teams: { left: 'Alpha', right: 'Beta' },
clients: [
{ osuId: 2, name: 'peppy', score: 123_456, accuracy: 98.5, combo: 321, failed: false }
]
});
expect(parseTosu({ beatmap: {} })).toBeNull();
});
test('tosu keeps a named spectator while its profile id is not available', () => {
const frame = parseTosu({
tourney: {
clients: [
{
user: { id: 0, name: '' },
play: { playerName: 'Ocean Player0', score: 123, accuracy: 98, combo: { current: 5 } }
},
{ user: { id: 0, name: '' }, play: { score: 0 } }
]
}
});
expect(frame?.clients).toEqual([
{ osuId: 0, name: 'Ocean Player0', score: 123, accuracy: 98, combo: 5, failed: false }
]);
});