UNPKG

advanced-games-library

Version:

Advanced Gaming Library for React Native - Four Complete Games with iOS Compatibility Fixes

323 lines (273 loc) 9.81 kB
import React, { useState, useEffect, useCallback } from 'react'; import { MultiplayerService, GameRoom, MultiplayerPlayer, MultiplayerGameState } from './MultiplayerService'; import { GameLibraryError } from '../../core/types'; /** * Hook for managing multiplayer game rooms */ export const useMultiplayerRoom = (playerId: string) => { const [currentRoom, setCurrentRoom] = useState<GameRoom | null>(null); const [connectionStatus, setConnectionStatus] = useState<'connected' | 'disconnected' | 'connecting'>('disconnected'); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState<string | null>(null); const multiplayerService = MultiplayerService.getInstance(); // Initialize service useEffect(() => { const initialize = async () => { if (connectionStatus === 'disconnected' && playerId) { setConnectionStatus('connecting'); try { await multiplayerService.initialize(playerId); setConnectionStatus('connected'); } catch (err) { setConnectionStatus('disconnected'); setError('Failed to connect to multiplayer service'); } } }; initialize(); }, [playerId]); // Set up event listeners useEffect(() => { const handleConnectionStatusChanged = (status: typeof connectionStatus) => { setConnectionStatus(status); }; const handlePlayerJoined = ({ room }: { room: GameRoom }) => { setCurrentRoom(room); }; const handleLeftRoom = () => { setCurrentRoom(null); }; multiplayerService.on('connection_status_changed', handleConnectionStatusChanged); multiplayerService.on('player_joined', handlePlayerJoined); multiplayerService.on('left_room', handleLeftRoom); return () => { multiplayerService.off('connection_status_changed', handleConnectionStatusChanged); multiplayerService.off('player_joined', handlePlayerJoined); multiplayerService.off('left_room', handleLeftRoom); }; }, []); // Create room const createRoom = useCallback(async ( gameId: string, roomName: string, maxPlayers: number = 4, isPrivate: boolean = false, password?: string ) => { setIsLoading(true); setError(null); try { const room = await multiplayerService.createRoom(gameId, roomName, maxPlayers, isPrivate, password); setCurrentRoom(room); return room; } catch (err) { const errorMessage = err instanceof GameLibraryError ? err.message : 'Failed to create room'; setError(errorMessage); throw err; } finally { setIsLoading(false); } }, []); // Join room const joinRoom = useCallback(async (roomId: string, password?: string) => { setIsLoading(true); setError(null); try { const room = await multiplayerService.joinRoom(roomId, password); setCurrentRoom(room); return room; } catch (err) { const errorMessage = err instanceof GameLibraryError ? err.message : 'Failed to join room'; setError(errorMessage); throw err; } finally { setIsLoading(false); } }, []); // Leave room const leaveRoom = useCallback(async () => { setIsLoading(true); try { await multiplayerService.leaveRoom(); setCurrentRoom(null); } catch (err) { console.warn('Error leaving room:', err); } finally { setIsLoading(false); } }, []); // Set ready status const setReady = useCallback(async (ready: boolean) => { try { await multiplayerService.setPlayerReady(ready); } catch (err) { setError('Failed to update ready status'); } }, []); // Start game (host only) const startGame = useCallback(async (gameConfig: any) => { setIsLoading(true); setError(null); try { await multiplayerService.startGame(gameConfig); } catch (err) { const errorMessage = err instanceof GameLibraryError ? err.message : 'Failed to start game'; setError(errorMessage); throw err; } finally { setIsLoading(false); } }, []); return { // State currentRoom, connectionStatus, isLoading, error, // Room info isHost: currentRoom?.hostId === playerId, isInRoom: !!currentRoom, // Methods createRoom, joinRoom, leaveRoom, setReady, startGame, // Utils clearError: () => setError(null), }; }; /** * Hook for managing multiplayer game lobby */ export const useMultiplayerLobby = () => { const [publicRooms, setPublicRooms] = useState<GameRoom[]>([]); const [isLoading, setIsLoading] = useState(false); const multiplayerService = MultiplayerService.getInstance(); // Load public rooms const loadPublicRooms = useCallback(() => { setIsLoading(true); try { const rooms = multiplayerService.getPublicRooms(); setPublicRooms(rooms); } catch (err) { console.warn('Failed to load public rooms:', err); } finally { setIsLoading(false); } }, []); // Refresh rooms periodically useEffect(() => { loadPublicRooms(); const interval = setInterval(loadPublicRooms, 5000); // Refresh every 5 seconds return () => clearInterval(interval); }, [loadPublicRooms]); return { publicRooms, isLoading, loadPublicRooms, }; }; /** * Hook for real-time multiplayer game state */ export const useMultiplayerGame = (roomId: string) => { const [gameState, setGameState] = useState<MultiplayerGameState | null>(null); const [messages, setMessages] = useState<any[]>([]); const [isConnected, setIsConnected] = useState(true); const multiplayerService = MultiplayerService.getInstance(); useEffect(() => { if (!roomId) return; const handleGameStarting = (state: MultiplayerGameState) => { setGameState(state); }; const handleGameStarted = (state: MultiplayerGameState) => { setGameState(state); }; const handleGameAction = (message: any) => { setMessages(prev => [...prev, message]); }; const handleGameStateUpdate = (update: any) => { setGameState(prev => prev ? { ...prev, gameData: { ...prev.gameData, ...update.gameData } } : null); }; const handleScoreUpdate = (update: { playerId: string; score: number }) => { setGameState(prev => prev ? { ...prev, scores: { ...prev.scores, [update.playerId]: update.score } } : null); }; const handleGameEnded = (endData: any) => { setGameState(prev => prev ? { ...prev, room: { ...prev.room, status: 'finished' } } : null); }; // Subscribe to room events multiplayerService.on(`room_${roomId}_game_starting`, handleGameStarting); multiplayerService.on(`room_${roomId}_game_started`, handleGameStarted); multiplayerService.on(`room_${roomId}_game_action`, handleGameAction); multiplayerService.on(`room_${roomId}_game_state_update`, handleGameStateUpdate); multiplayerService.on(`room_${roomId}_score_update`, handleScoreUpdate); multiplayerService.on(`room_${roomId}_game_ended`, handleGameEnded); return () => { multiplayerService.off(`room_${roomId}_game_starting`, handleGameStarting); multiplayerService.off(`room_${roomId}_game_started`, handleGameStarted); multiplayerService.off(`room_${roomId}_game_action`, handleGameAction); multiplayerService.off(`room_${roomId}_game_state_update`, handleGameStateUpdate); multiplayerService.off(`room_${roomId}_score_update`, handleScoreUpdate); multiplayerService.off(`room_${roomId}_game_ended`, handleGameEnded); }; }, [roomId]); // Send game action const sendGameAction = useCallback((action: string, data: any) => { multiplayerService.sendGameAction(action, data); }, []); // Update game state const updateGameState = useCallback((data: any) => { multiplayerService.updateGameState(data); }, []); // Update score const updateScore = useCallback((playerId: string, score: number) => { multiplayerService.updateScore(playerId, score); }, []); return { gameState, messages, isConnected, sendGameAction, updateGameState, updateScore, }; }; /** * Hook for managing game invitations */ export const useGameInvitations = (playerId: string) => { const [pendingInvitations, setPendingInvitations] = useState<any[]>([]); const [sentInvitations, setSentInvitations] = useState<any[]>([]); const multiplayerService = MultiplayerService.getInstance(); // Send invitation const sendInvitation = useCallback(async (toPlayerId: string, message?: string) => { try { const invitation = await multiplayerService.sendInvitation(toPlayerId, message); setSentInvitations(prev => [...prev, invitation]); return invitation; } catch (err) { throw err; } }, []); // Accept invitation const acceptInvitation = useCallback(async (invitationId: string) => { // Implementation would handle accepting invitation setPendingInvitations(prev => prev.filter(i => i.id !== invitationId)); }, []); // Decline invitation const declineInvitation = useCallback(async (invitationId: string) => { // Implementation would handle declining invitation setPendingInvitations(prev => prev.filter(i => i.id !== invitationId)); }, []); return { pendingInvitations, sentInvitations, sendInvitation, acceptInvitation, declineInvitation, }; };