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:
@@ -12,7 +12,7 @@ interface Word {
|
||||
h: number;
|
||||
}
|
||||
|
||||
const plain = (value: string) =>
|
||||
export const plain = (value: string) =>
|
||||
value
|
||||
.normalize('NFKD')
|
||||
.toLowerCase()
|
||||
@@ -49,15 +49,19 @@ export function findRoom(tsv: string, roomName: string): { x: number; y: number
|
||||
return null;
|
||||
}
|
||||
|
||||
function tournamentConfig(existing: string, teamSize: number, height: number) {
|
||||
/** tournament.cfg with our keys replaced and anything else osu! wrote kept. */
|
||||
export function tournamentConfig(
|
||||
existing: string,
|
||||
options: { teamSize: number; height: number; acronym?: string }
|
||||
) {
|
||||
const lines = existing
|
||||
.split(/\r?\n/)
|
||||
.filter((line) => !/^\s*(TeamSize|acronym|Height)\s*=/i.test(line));
|
||||
return [
|
||||
...lines.filter(Boolean),
|
||||
`TeamSize = ${teamSize}`,
|
||||
'acronym = VASH',
|
||||
`Height = ${height}`,
|
||||
`TeamSize = ${options.teamSize}`,
|
||||
`acronym = ${options.acronym ?? 'VASH'}`,
|
||||
`Height = ${options.height}`,
|
||||
''
|
||||
].join('\n');
|
||||
}
|
||||
@@ -93,7 +97,7 @@ export class Tourney {
|
||||
}
|
||||
const configPath = join(this.directory, 'tournament.cfg');
|
||||
const existing = await readFile(configPath, 'utf8').catch(() => '');
|
||||
await writeFile(configPath, tournamentConfig(existing, teamSize, this.height));
|
||||
await writeFile(configPath, tournamentConfig(existing, { teamSize, height: this.height }));
|
||||
this.process = Bun.spawn(['wine', this.exe], {
|
||||
cwd: this.directory,
|
||||
env: { ...process.env, DISPLAY: this.display },
|
||||
|
||||
Reference in New Issue
Block a user