feat: Implementar sesiones persistentes y botones de salida

- Añadido sistema de sesiones con localStorage
- Nuevo hook useSessionStorage para manejar sesiones
- Botón de salir de la partida (ExitGameButton) en todas las pantallas del juego
- Botón de logout (LogoutButton) solo en el lobby
- Evento leave_game en servidor para cerrar partida cuando alguien sale
- Evento reconnect_session para reconectar jugadores después de recargar
- Actualizado GameBoard para incluir botón de salida
- Actualizado page.tsx para manejar sesiones y logout
This commit is contained in:
Resistencia Dev
2025-12-22 16:51:35 +01:00
parent be15983455
commit 53a5e3886e
9 changed files with 497 additions and 4 deletions

View File

@@ -301,7 +301,89 @@ io.on('connection', (socket) => {
}
});
// 9. DESCONEXIÓN
// 8. ABANDONAR PARTIDA (cualquier jugador)
socket.on('leave_game', ({ roomId }) => {
const game = games[roomId];
if (game) {
// Encontrar el jugador que se va
const leavingPlayer = game.state.players.find(p => p.id === socket.id);
const playerName = leavingPlayer?.name || 'Un jugador';
// Notificar a todos los jugadores
io.to(roomId).emit('player_left_game', { playerName });
io.to(roomId).emit('game_finalized');
// Eliminar la partida de la base de datos
delete games[roomId];
// Limpiar timer si existe
if (voteTimers[roomId]) {
clearTimeout(voteTimers[roomId]);
delete voteTimers[roomId];
}
// Actualizar lista de salas
io.emit('rooms_list', getRoomsList());
// Desconectar a todos de la sala
io.in(roomId).socketsLeave(roomId);
console.log(`[LEAVE_GAME] ${playerName} abandonó la partida ${roomId}. Partida eliminada.`);
}
});
// 9. RECONECTAR SESIÓN
socket.on('reconnect_session', ({ playerName, roomId }) => {
console.log(`[RECONNECT_SESSION] Intento de reconexión: ${playerName} a sala ${roomId}`);
if (roomId) {
const game = games[roomId];
if (game) {
// Buscar si el jugador existe en la partida
const existingPlayer = game.state.players.find(p => p.name === playerName);
if (existingPlayer) {
// Actualizar el socket ID del jugador
existingPlayer.id = socket.id;
// Unir al socket a la sala
socket.join(roomId);
// Enviar estado actualizado
socket.emit('game_joined', { roomId, state: game.state });
io.to(roomId).emit('game_state', game.state);
console.log(`[RECONNECT_SESSION] ${playerName} reconectado exitosamente a ${roomId}`);
} else {
console.log(`[RECONNECT_SESSION] Jugador ${playerName} no encontrado en partida ${roomId}`);
socket.emit('error', 'No se pudo reconectar a la partida');
}
} else {
console.log(`[RECONNECT_SESSION] Partida ${roomId} no existe`);
socket.emit('error', 'La partida ya no existe');
}
}
});
// 10. FINALIZAR Y EXPULSAR JUGADORES (solo host)
socket.on('finalize_game', ({ roomId }) => {
const game = games[roomId];
if (game && game.hostId === socket.id) {
// Notificar a todos los jugadores que la partida ha sido finalizada
io.to(roomId).emit('game_finalized');
// Eliminar la partida inmediatamente del registro
delete games[roomId];
// Actualizar lista de salas para todos los clientes
io.emit('rooms_list', getRoomsList());
// Desconectar a todos los jugadores de la sala
io.in(roomId).socketsLeave(roomId);
}
});
// 11. DESCONEXIÓN
socket.on('disconnect', () => {
// Buscar en qué partida estaba y sacarlo (opcional, por ahora solo notificamos)
console.log('Desconectado:', socket.id);