Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
4.9 kB · 147 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147import { useEffect, useCallback } from 'react';import { useWebSocket } from './useWebSocket';import { GameState, GameStateClient, Player, ServerToClientEvents, StateLobby } from '../../types';import { buildApiUrl } from '../config/api';import { sessionStorage } from '../utils/sessionStorage';
interface UseGameEventsOptions { onGameState: (gameState: GameStateClient) => void; onPlayerJoined: (data: { game: GameStateClient; player: Player }) => void; onPlayerLeft: (data: { game: GameStateClient; playerId: string }) => void; onGameCreated: (game: GameState) => void; onGameDeleted: (data: { gameId: string }) => void; onServerError: (data: { error: string }) => void; onConnect: () => void; onDisconnect: () => void; onConnectionError: (error: any) => void; gameId?: string; playerId?: string;}
export interface UseGameEventsReturn { isConnected: boolean; forceDisconnectPlayer: (gameId: string, playerId: string) => Promise<void>; connect: () => void; disconnect: () => void; authenticatePlayer: (gameId: string, playerId: string) => void; updateRuleset: (ruleset: StateLobby["ruleset"]) => void; startGame: () => void; confirmRoleAssignment: () => void; endTurn: () => void;}
const createEventHandler = <T>(eventName: string, handler: (data: T) => void) => { return (data: T) => { try { handler(data); } catch (error) { console.error(`Error handling ${eventName} event:`, error); } };};
export function useGameEvents(options: UseGameEventsOptions): UseGameEventsReturn { const { onGameState, onPlayerJoined, onPlayerLeft, onGameCreated, onGameDeleted, onServerError, onConnect, onDisconnect, onConnectionError, gameId, playerId } = options;
const { isConnected, socket, connect, disconnect, authenticatePlayer } = useWebSocket({ onConnect, onDisconnect, onConnectionError, gameId, playerId });
const updateRuleset = useCallback((ruleset: StateLobby["ruleset"]) => { if (socket && isConnected && gameId) { console.log(`Updating ruleset for game ${gameId}`, ruleset); socket.emit('updateRuleset', { gameId, ruleset }); } else { console.error('Cannot update ruleset: socket not connected or no game ID'); } }, [isConnected, socket, gameId]);
const startGame = useCallback(() => { if (socket && isConnected && gameId) { console.log(`Starting game ${gameId}`); socket.emit('startGame', { gameId }); } }, [isConnected, socket, gameId]);
const confirmRoleAssignment = useCallback(() => { if (socket && isConnected && gameId && playerId) { console.log(`Confirming role assignment for player ${playerId} in game ${gameId}`); socket.emit('confirmRoleAssignment', { gameId, playerId }); } }, [isConnected, socket, gameId, playerId]);
const endTurn = useCallback(() => { if (socket && isConnected && gameId && playerId) { console.log(`Ending turn for player ${playerId} in game ${gameId}`); socket.emit('endTurn', { gameId, playerId }); } }, [isConnected, socket, gameId, playerId]);
const forceDisconnectPlayer = useCallback(async (gameId: string, playerId: string) => { try { const response = await fetch(buildApiUrl(`api/games/${gameId}/players/${playerId}/disconnect`), { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const result = await response.json(); if (!result.success) { console.error('Failed to force disconnect player:', result.error); } } catch (error) { console.error('Error force disconnecting player:', error); } }, []);
useEffect(() => { if (!socket) return;
// The type signature require that all keys of ServerToClientEvents are specified, and nothing more const eventHandlers: Record<keyof ServerToClientEvents, any> = { gameState: createEventHandler('gameState', onGameState), playerJoined: createEventHandler('playerJoined', onPlayerJoined), playerLeft: createEventHandler('playerLeft', onPlayerLeft), gameCreated: createEventHandler('gameCreated', onGameCreated), gameDeleted: createEventHandler('gameDeleted', onGameDeleted), error: createEventHandler('error', onServerError), };
Object.entries(eventHandlers).forEach(([event, handler]) => { socket.on(event, handler); });
return () => { Object.entries(eventHandlers).forEach(([event, handler]) => { socket.off(event, handler); }); }; }, [socket, onGameState, onPlayerJoined, onPlayerLeft, onGameCreated, onGameDeleted, onServerError]);
return { isConnected, forceDisconnectPlayer, connect, disconnect, authenticatePlayer, updateRuleset, startGame, confirmRoleAssignment, endTurn, };}