advanced-games-library
Version:
Advanced Gaming Library for React Native - Four Complete Games with iOS Compatibility Fixes
323 lines (273 loc) • 9.81 kB
text/typescript
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,
};
};