Jason Dekarske 722e6090d1 refactor(frontend): multi-path trajectory protocol and team on throw
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-10 23:16:06 -07:00

100 lines
2.4 KiB
TypeScript

import type {
ServerGameStateMessage,
ServerStoneTrajectory,
ServerMessageTyped as ServerMessage,
Team,
} from './protocol'
const WS_URL = import.meta.env.VITE_WS_URL
function resolveWsUrl(): string {
if (WS_URL) return WS_URL
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
return `${protocol}//${window.location.hostname}:3000/ws`
}
export interface NetCallbacks {
onJoined: (room: string) => void
onWaiting: (message: string) => void
onGameState: (msg: ServerGameStateMessage) => void
onTrajectory: (paths: ServerStoneTrajectory[]) => void
onEndScored: (end: number, points: number, scoringTeam: Team | null) => void
onGameOver: (scores: number[], winner: Team | null) => void
onError: (message: string) => void
onClose: () => void
}
let socket: WebSocket | null = null
export function connect(room: string, callbacks: NetCallbacks): void {
if (socket) return
const url = `${resolveWsUrl()}?room=${encodeURIComponent(room)}`
const ws = new WebSocket(url)
ws.onopen = () => {
socket = ws
}
ws.onmessage = (event) => {
try {
const msg = JSON.parse(event.data) as ServerMessage
if (!msg || typeof msg.type !== 'string') return
switch (msg.type) {
case 'joined':
callbacks.onJoined(msg.room)
break
case 'waiting':
callbacks.onWaiting(msg.message)
break
case 'game_state':
callbacks.onGameState(msg)
break
case 'trajectory':
callbacks.onTrajectory(msg.paths)
break
case 'end_scored':
callbacks.onEndScored(msg.end, msg.points, msg.scoring_team ?? null)
break
case 'game_over':
callbacks.onGameOver(msg.scores, msg.winner)
break
case 'error':
callbacks.onError(msg.message)
break
}
} catch (err) {
console.error('Failed to parse server message', err)
}
}
ws.onclose = () => {
socket = null
callbacks.onClose()
}
ws.onerror = () => {}
}
export function sendThrow(
team: Team,
broomX: number,
broomY: number,
weight: number,
curl: number,
friction: number,
): void {
if (!socket || socket.readyState !== WebSocket.OPEN) return
socket.send(
JSON.stringify({
type: 'throw',
team,
broom_x: broomX,
broom_y: broomY,
weight,
curl,
friction,
}),
)
}