const roomController = require("../controller/room"); const gameController = require("../controller/game"); module.exports = (io) => (socket) => { let currentRoomId = null; let currentUser = null; let phaseTimers = {}; const clearRoomTimers = (roomId) => { if (phaseTimers[roomId]) { clearTimeout(phaseTimers[roomId]); delete phaseTimers[roomId]; } }; const startPhaseTimer = (roomId) => { clearRoomTimers(roomId); const timeRemaining = gameController.getTimeRemaining(roomId) * 1000; phaseTimers[roomId] = setTimeout(() => { const advanced = gameController.advancePhase(roomId); if (!advanced) return; if (typeof advanced === 'boolean') { handleRoundStart(roomId); } else { const currentPhase = advanced.phase || 'results'; if (currentPhase === 'guessing') { handleGuessingPhaseStart(roomId); } else if (currentPhase === 'results') { handleResultsPhaseStart(roomId); } } }, timeRemaining); }; const handleRoundStart = (roomId) => { const roles = gameController.getRoles(roomId); const selectedSong = gameController.getSelectedSong(roomId); const timeLeft = gameController.getTimeRemaining(roomId); io.to(roomId).emit('roles-assigned', roles); Object.entries(roles).forEach(([userId, role]) => { if (role === 'composer') { io.to(userId).emit('song-selected', selectedSong); } }); io.to(roomId).emit('round-started', { round: gameController.getRoundResults(roomId).round, timeRemaining: timeLeft }); startPhaseTimer(roomId); }; const handleGuessingPhaseStart = (roomId) => { const roles = gameController.getRoles(roomId); const songOptions = gameController.getSongOptions(roomId); const timeLeft = gameController.getTimeRemaining(roomId); Object.entries(roles).forEach(([userId, role]) => { if (role === 'guesser') { io.to(userId).emit('guessing-phase-started', { timeRemaining: timeLeft, songOptions }); } }); startPhaseTimer(roomId); }; const handleResultsPhaseStart = (roomId) => { const results = gameController.getRoundResults(roomId); io.to(roomId).emit('round-results', results); }; socket.on("disconnect", () => { const roomId = roomController.getUserRoom(socket.id); if (roomId) { socket.to(roomId).emit("user-disconnected", socket.id); roomController.disconnectUser(socket.id); } }); socket.on("join-room", ({roomId, name}) => { if (currentRoomId) return socket.emit("already-in-room", currentRoomId); roomId = roomId.toString().toUpperCase(); if (roomController.roomExists(roomId)) { if (!roomController.isRoomOpen(roomId)) { return socket.emit("room-closed", roomId); } currentUser = {id: socket.id, name: name.toString()}; roomController.connectUserToRoom(roomId, currentUser); socket.join(roomId); const users = roomController.getRoomUsers(roomId); io.to(roomId).emit("room-users-update", users); socket.to(roomId).emit("user-connected", currentUser); socket.emit("room-joined", roomId); currentRoomId = roomId; } else { socket.emit("room-not-found", roomId); } }); socket.on("create-room", ({name}) => { if (!name) return socket.emit("room-name-required"); const roomId = Math.random().toString(36).substring(7).toUpperCase(); currentUser = {id: socket.id, name: name?.toString(), creator: true}; roomController.connectUserToRoom(roomId, currentUser); socket.join(roomId); socket.emit("room-created", roomId); currentRoomId = roomId; }); socket.on("start-game", () => { const roomId = roomController.getUserRoom(socket.id); if (!roomId || !roomController.isUserHost(socket.id)) { return socket.emit("not-authorized"); } roomController.validateRoomMembers(io, roomId); const users = roomController.getRoomUsers(roomId); if (users.length < 2) { return socket.emit("error", { message: "At least 2 players are required" }); } if (!roomController.startGame(roomId)) return; gameController.initializeGameState(roomId); if (!gameController.startNewRound(roomId)) return; io.to(roomId).emit("game-started"); handleRoundStart(roomId); }); socket.on("send-message", (messageData) => { const roomId = roomController.getUserRoom(socket.id); if (roomId) socket.to(roomId).emit("chat-message", messageData); }); socket.on("get-user-info", () => { if (currentUser) socket.emit("user-info", currentUser); }); socket.on("get-room-users", () => { const roomId = roomController.getUserRoom(socket.id); if (roomId) { const users = roomController.getRoomUsers(roomId); socket.emit("room-users", users); } }); socket.on("check-host-status", () => { socket.emit("host-status", { isHost: roomController.isUserHost(socket.id) }); }); socket.on("get-room-code", () => { if (currentRoomId) socket.emit("room-code", currentRoomId); }); socket.on("submit-frequency", ({ frequency }) => { const roomId = roomController.getUserRoom(socket.id); if (!roomId) return; const userRole = gameController.getUserRole(roomId, socket.id); if (userRole !== 'composer') return; if (gameController.updateFrequency(roomId, frequency)) { socket.to(roomId).emit("frequency-update", { frequency }); } }); socket.on("submit-guess", ({ songId }) => { const roomId = roomController.getUserRoom(socket.id); if (!roomId) return; const result = gameController.submitGuess(roomId, socket.id, songId); if (result) socket.emit("guess-result", result); }); socket.on("next-round", () => { const roomId = roomController.getUserRoom(socket.id); if (!roomId || !roomController.isUserHost(socket.id)) return; roomController.validateRoomMembers(io, roomId); const users = roomController.getRoomUsers(roomId); if (users.length < 2) { return socket.emit("error", { message: "At least 2 players are required" }); } if (gameController.startNewRound(roomId)) { handleRoundStart(roomId); } }); socket.on("get-current-frequency", () => { const roomId = roomController.getUserRoom(socket.id); if (roomId) { socket.emit("current-frequency", { frequency: gameController.getCurrentFrequency(roomId) }); } }); };