const youtubeService = require('../services/youtubeService'); let cleanupGameState; const setCleanupGameState = (cleanupFunction) => { cleanupGameState = cleanupFunction; }; let rooms = {}; module.exports.roomExists = (roomId) => rooms[roomId] !== undefined; module.exports.isRoomOpen = (roomId) => rooms[roomId] && rooms[roomId].state === 'waiting'; const initializeRoom = async (roomId, user) => { try { const randomPlaylists = await youtubeService.getRandomPlaylists(3); rooms[roomId] = { members: [{...user, creator: true}], settings: {}, state: 'waiting', playlistVotes: {}, selectedPlaylist: null, availablePlaylists: randomPlaylists }; } catch (error) { console.error("Error initializing room playlists:", error); rooms[roomId] = { members: [{...user, creator: true}], settings: {}, state: 'waiting', playlistVotes: {}, selectedPlaylist: null, availablePlaylists: { seventies: youtubeService.PLAYLISTS.seventies } }; } }; module.exports.connectUserToRoom = async (roomId, user) => { roomId = roomId.toUpperCase(); if (rooms[roomId]) { rooms[roomId].members.push({...user, creator: false}); } else { await initializeRoom(roomId, user); } console.log(`User ${user.name} connected to room ${roomId}`); }; module.exports.getUserRoom = (userId) => { for (const roomId in rooms) { const room = rooms[roomId]; const memberIndex = room.members.findIndex(member => member.id === userId); if (memberIndex !== -1) return roomId; } return null; } module.exports.getRoomUsers = (roomId) => { if (rooms[roomId]) { return rooms[roomId].members; } return []; } module.exports.getRoomCreator = (roomId) => { if (rooms[roomId]) { return rooms[roomId].members.find(member => member.creator); } return null; } module.exports.isUserHost = (userId) => { for (const roomId in rooms) { const room = rooms[roomId]; const member = room.members.find(m => m.id === userId); if (member && member.creator) { return true; } } return false; } module.exports.startGame = (roomId) => { if (rooms[roomId]) { rooms[roomId].state = 'playing'; console.log(`Game started in room ${roomId}`); return true; } return false; } module.exports.getRoomState = (roomId) => { if (rooms[roomId]) { return rooms[roomId].state; } return null; } module.exports.disconnectUser = (userId) => { for (const roomId in rooms) { const room = rooms[roomId]; const memberIndex = room.members.findIndex(member => member.id === userId); if (memberIndex !== -1) { if (room.members[memberIndex].creator && room.members.length > 1) { room.members[1].creator = true; } room.members.splice(memberIndex, 1); console.log(`User ${userId} disconnected from room ${roomId}`); if (room.members.length === 0) { if (cleanupGameState) { cleanupGameState(roomId); } delete rooms[roomId]; console.log(`Room ${roomId} deleted because it's empty`); } break; } } } module.exports.validateRoomMembers = (io, roomId) => { if (!rooms[roomId]) return []; const validMembers = []; const connectedSockets = io.sockets.adapter.rooms.get(roomId) || new Set(); rooms[roomId].members = rooms[roomId].members.filter(member => { const stillConnected = connectedSockets.has(member.id); if (stillConnected) { validMembers.push(member); } else { console.log(`Removing disconnected user ${member.name} (${member.id}) from room ${roomId}`); } return stillConnected; }); return validMembers; } module.exports.setCleanupGameState = setCleanupGameState; module.exports.getUserName = (userId) => { for (const roomId in rooms) { const room = rooms[roomId]; const member = room.members.find(m => m.id === userId); if (member) { return member.name; } } return null; }; module.exports.voteForPlaylist = (roomId, userId, playlistId) => { if (!rooms[roomId]) return false; const room = rooms[roomId]; if (room.state !== 'waiting') return false; if (!room.playlistVotes) { room.playlistVotes = {}; } Object.entries(room.playlistVotes).forEach(([pid, voters]) => { room.playlistVotes[pid] = voters.filter(id => id !== userId); }); if (!room.playlistVotes[playlistId]) { room.playlistVotes[playlistId] = []; } room.playlistVotes[playlistId].push(userId); console.log(`Updated votes for room ${roomId}:`, room.playlistVotes); return true; }; module.exports.getPlaylistVotes = (roomId) => { return rooms[roomId]?.playlistVotes || {}; }; module.exports.getWinningPlaylist = (roomId) => { const room = rooms[roomId]; if (!room || !room.playlistVotes) { console.log(`No votes found for room ${roomId}, using default playlist`); return room.availablePlaylists[Object.keys(room.availablePlaylists)[0]]; } let maxVotes = 0; let winningPlaylist = null; console.log(`Calculating winning playlist for room ${roomId}`); console.log('Current votes:', room.playlistVotes); Object.entries(room.playlistVotes).forEach(([playlistId, voters]) => { console.log(`Playlist ${playlistId} has ${voters.length} votes`); if (voters.length > maxVotes) { maxVotes = voters.length; winningPlaylist = playlistId; } }); if (!winningPlaylist) { console.log('No winning playlist found, using first available'); winningPlaylist = room.availablePlaylists[Object.keys(room.availablePlaylists)[0]]; } console.log(`Selected winning playlist: ${winningPlaylist}`); return winningPlaylist; }; module.exports.getAvailablePlaylists = (roomId) => { return rooms[roomId]?.availablePlaylists || {}; }; module.exports.updateAvailablePlaylists = (roomId, newPlaylists) => { if (rooms[roomId]) { rooms[roomId].availablePlaylists = newPlaylists; rooms[roomId].playlistVotes = {}; return true; } return false; };