From b862dc27f12a6498d03c82316024d8eb82ffd55d Mon Sep 17 00:00:00 2001 From: bgoulard Date: Sun, 11 Jan 2026 17:03:12 +0100 Subject: [PATCH] [wip] added socket shape for join game + started working on front handling of game param in url --- frontend/src/pages/pong/pong.ts | 37 +++++++++++++++++++++++++------ frontend/src/pages/pong/socket.ts | 8 +++++++ src/pong/src/socket.ts | 8 +++++++ src/pong/src/state.ts | 16 +++++++++++-- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/frontend/src/pages/pong/pong.ts b/frontend/src/pages/pong/pong.ts index 5af0e86..0c01108 100644 --- a/frontend/src/pages/pong/pong.ts +++ b/frontend/src/pages/pong/pong.ts @@ -7,7 +7,7 @@ import { } from "@app/routing"; import authHtml from "./pong.html?raw"; import io from "socket.io-client"; -import type { CSocket, GameMove, GameUpdate, TourInfo } from "./socket"; +import { JoinRes, type CSocket, type GameMove, type GameUpdate, type TourInfo } from "./socket"; import { showError, showInfo, showSuccess } from "@app/toast"; import { getUser as getSelfUser, type User } from "@app/auth"; import { isNullish } from "@app/utils"; @@ -79,12 +79,11 @@ function pongClient( ): RouteHandlerReturn { setTitle("Pong Game Page"); const urlParams = new URLSearchParams(window.location.search); - const game_req_join = urlParams.get("game"); - if (game_req_join) { - showError( - "currently not supporting the act of joining game (even as a spectator)", - ); - } + let game_req_join = urlParams.get("game"); + // todo: + // [ ] shape sock + // - [ ] joinGame (guid) -> ["ok"|"no, dont ever talk to my kid or me ever again you creep"]; + // - [ ] launch newgame evt? return { html: authHtml, @@ -240,6 +239,30 @@ function pongClient( // keys end // --- + // --- + // join game + // --- + if (game_req_join != null) { + socket.emit('joinGame', game_req_join, + (res : JoinRes) => { + switch (res) { + case JoinRes.yes : + showInfo('JoinRes = yes'); + break; + case JoinRes.no : + showInfo('JoinRes = no'); + break; + default: + showError('JoinRes switch fail:' + res); + } + } + ) + game_req_join = null; + } + // --- + // join game end + // --- + // --- // position logic (client) // --- diff --git a/frontend/src/pages/pong/socket.ts b/frontend/src/pages/pong/socket.ts index 874d749..9c419fd 100644 --- a/frontend/src/pages/pong/socket.ts +++ b/frontend/src/pages/pong/socket.ts @@ -37,6 +37,12 @@ export type TourInfo = { remainingMatches: number | null, }; +export enum JoinRes { + yes = 'yes', + no = 'dont ever talk to me or my kid ever again', + dev = 'yaaaaaaaaaaaaaaaaaaaaaaaa', +}; + export interface ClientToServer { enqueue: () => void; dequeue: () => void; @@ -46,6 +52,8 @@ export interface ClientToServer { connectedToGame: (gameId: string) => void; localGame: () => void; + joinGame: (guid : string, ack:(result:JoinRes) => void) => void; + hello: () => void; // TOURNAMENT diff --git a/src/pong/src/socket.ts b/src/pong/src/socket.ts index 435a8ca..f9dcd4f 100644 --- a/src/pong/src/socket.ts +++ b/src/pong/src/socket.ts @@ -37,6 +37,12 @@ export type TourInfo = { remainingMatches: number | null, }; +export enum JoinRes { + yes = 'yes', + no = 'dont ever talk to me or my kid ever again', + dev = 'yaaaaaaaaaaaaaaaaaaaaaaaa', +}; + export interface ClientToServer { enqueue: () => void; dequeue: () => void; @@ -46,6 +52,8 @@ export interface ClientToServer { connectedToGame: (gameId: string) => void; localGame: () => void; + joinGame: (guid : string, ack:(result:JoinRes) => void) => void; + hello: () => void; // TOURNAMENT diff --git a/src/pong/src/state.ts b/src/pong/src/state.ts index 1225e2d..00b961a 100644 --- a/src/pong/src/state.ts +++ b/src/pong/src/state.ts @@ -2,7 +2,7 @@ import { UserId } from '@shared/database/mixin/user'; import { newUUID } from '@shared/utils/uuid'; import { FastifyInstance } from 'fastify'; import { Pong } from './game'; -import { GameMove, GameUpdate, SSocket, TourInfo } from './socket'; +import { GameMove, GameUpdate, JoinRes, SSocket, TourInfo } from './socket'; import { isNullish, shuffle } from '@shared/utils'; import { PongGameId, PongGameOutcome } from '@shared/database/mixin/pong'; import { Tournament } from './tour'; @@ -385,6 +385,18 @@ class StateI { this.cleanupUser(sock); } + private tryJoinGame(g_id : string, sock : SSocket) : JoinRes { + const game_id : PongGameId = g_id as PongGameId; + let game : Pong; + + if (this.games.has(game_id) === false) + return (JoinRes.no); + game = this.games.get(game_id)!; + if (game.local || game.userLeft !== sock.authUser.id || game.userRight !== sock.authUser.id) + return (JoinRes.no); + return (JoinRes.dev); + } + public registerUser(socket: SSocket): void { this.fastify.log.info('Registering new user'); if (this.users.has(socket.authUser.id)) { @@ -415,7 +427,7 @@ class StateI { socket.on('gameMove', (e) => this.gameMove(socket, e)); socket.on('localGame', () => this.newLocalGame(socket)); - + socket.on('joinGame', (g_id, ack) => {return (ack(this.tryJoinGame(g_id, socket)));}); // todo: allow passing nickname socket.on('tourRegister', () => this.registerForTournament(socket, null),