Fix audio not playing

This commit is contained in:
2025-03-01 00:32:03 +01:00
parent 7d7dd263fe
commit 87fc9a2f39
4 changed files with 372 additions and 394 deletions

View File

@ -1,12 +1,17 @@
const roomController = require('./room');
const SONGS = [
{ id: 1, title: "Black Steam", artist: "Carrot Quest GmbH", coverUrl: "https://mir-s3-cdn-cf.behance.net/project_modules/1400/fe529a64193929.5aca8500ba9ab.jpg" },
{ id: 2, title: "Sunset Dreams", artist: "Ocean Waves", coverUrl: "https://place-hold.it/500x500/" },
{ id: 3, title: "Neon Nights", artist: "Electric Avenue", coverUrl: "https://place-hold.it/500x500/" },
{ id: 4, title: "Mountain Echo", artist: "Wild Terrain", coverUrl: "https://place-hold.it/500x500/" },
{ id: 5, title: "Urban Jungle", artist: "City Dwellers", coverUrl: "https://place-hold.it/500x500/" },
{ id: 6, title: "Cosmic Journey", artist: "Stargazers", coverUrl: "https://place-hold.it/500x500/" }
{
id: 1,
title: "Black Steam",
artist: "Carrot Quest GmbH",
coverUrl: "https://mir-s3-cdn-cf.behance.net/project_modules/1400/fe529a64193929.5aca8500ba9ab.jpg"
},
{id: 2, title: "Sunset Dreams", artist: "Ocean Waves", coverUrl: "https://place-hold.it/500x500/"},
{id: 3, title: "Neon Nights", artist: "Electric Avenue", coverUrl: "https://place-hold.it/500x500/"},
{id: 4, title: "Mountain Echo", artist: "Wild Terrain", coverUrl: "https://place-hold.it/500x500/"},
{id: 5, title: "Urban Jungle", artist: "City Dwellers", coverUrl: "https://place-hold.it/500x500/"},
{id: 6, title: "Cosmic Journey", artist: "Stargazers", coverUrl: "https://place-hold.it/500x500/"}
];
const gameStates = {};
@ -35,72 +40,75 @@ const initializeGameState = (roomId) => {
gameStates[roomId].scores[user.id] = 0;
});
}
return gameStates[roomId];
};
const startNewRound = (roomId) => {
const gameState = gameStates[roomId];
if (!gameState) return false;
const users = roomController.getRoomUsers(roomId);
if (users.length < 2) return false;
gameState.round += 1;
gameState.phase = 'composing';
gameState.guessResults = {};
gameState.roundStartTime = Date.now();
const users = roomController.getRoomUsers(roomId);
if (users.length < 2) return false;
console.log(`Starting round ${gameState.round} in room ${roomId} with ${users.length} users`);
gameState.roles = {};
if (gameState.round === 1 || !gameState.currentComposer) {
const composerIndex = Math.floor(Math.random() * users.length);
gameState.currentComposer = users[composerIndex].id;
} else {
const currentIndex = users.findIndex(user => user.id === gameState.currentComposer);
if (currentIndex === -1) {
const composerIndex = Math.floor(Math.random() * users.length);
gameState.currentComposer = users[composerIndex].id;
} else {
const nextIndex = (currentIndex + 1) % users.length;
gameState.currentComposer = users[nextIndex].id;
}
}
gameState.currentComposer = determineNextComposer(roomId, gameState, users);
users.forEach(user => {
gameState.roles[user.id] = user.id === gameState.currentComposer ? 'composer' : 'guesser';
console.log(`User ${user.name} (${user.id}) assigned role: ${gameState.roles[user.id]}`);
});
selectSongAndOptions(gameState);
return true;
};
const determineNextComposer = (roomId, gameState, users) => {
if (gameState.round === 1 || !gameState.currentComposer) {
return users[Math.floor(Math.random() * users.length)].id;
}
const currentIndex = users.findIndex(user => user.id === gameState.currentComposer);
if (currentIndex === -1) {
return users[Math.floor(Math.random() * users.length)].id;
}
return users[(currentIndex + 1) % users.length].id;
};
const selectSongAndOptions = (gameState) => {
gameState.selectedSong = SONGS[Math.floor(Math.random() * SONGS.length)];
const songOptions = [...SONGS].sort(() => Math.random() - 0.5).slice(0, 5);
if (!songOptions.includes(gameState.selectedSong)) {
songOptions[Math.floor(Math.random() * songOptions.length)] = gameState.selectedSong;
}
gameState.songOptions = songOptions;
return true;
};
const getTimeRemaining = (roomId) => {
const gameState = gameStates[roomId];
if (!gameState || !gameState.roundStartTime) return 0;
const phaseDuration = gameState.phaseTimeLimit[gameState.phase] * 1000;
const timeElapsed = Date.now() - gameState.roundStartTime;
const timeRemaining = Math.max(0, phaseDuration - timeElapsed);
return Math.ceil(timeRemaining / 1000);
};
const advancePhase = (roomId) => {
const gameState = gameStates[roomId];
if (!gameState) return false;
if (gameState.phase === 'composing') {
gameState.phase = 'guessing';
gameState.roundStartTime = Date.now();
@ -111,7 +119,7 @@ const advancePhase = (roomId) => {
} else if (gameState.phase === 'results') {
return startNewRound(roomId);
}
return false;
};
@ -121,38 +129,37 @@ const updateFrequency = (roomId, frequency) => {
return true;
};
const getCurrentFrequency = (roomId) => {
return gameStates[roomId]?.lastFrequency || 440;
};
const submitGuess = (roomId, userId, songId) => {
const gameState = gameStates[roomId];
if (!gameState || gameState.phase !== 'guessing' || gameState.roles[userId] !== 'guesser') {
return false;
}
const isCorrect = gameState.selectedSong.id === songId;
gameState.guessResults[userId] = {
songId,
isCorrect,
points: isCorrect ? 10 : 0
};
const isCorrect = gameState.selectedSong.id === parseInt(songId);
const points = isCorrect ? 10 : 0;
gameState.guessResults[userId] = {songId, isCorrect, points};
if (isCorrect) {
gameState.scores[userId] = (gameState.scores[userId] || 0) + 10;
gameState.scores[userId] = (gameState.scores[userId] || 0) + points;
}
return {
isCorrect,
correctSong: gameState.selectedSong,
points: isCorrect ? 10 : 0
points
};
};
const getCurrentFrequency = (roomId) => gameStates[roomId]?.lastFrequency || 440;
const getRoles = (roomId) => gameStates[roomId]?.roles || {};
const getUserRole = (roomId, userId) => gameStates[roomId]?.roles[userId] || null;
const getSongOptions = (roomId) => gameStates[roomId]?.songOptions || [];
const getSelectedSong = (roomId) => gameStates[roomId]?.selectedSong || null;
const getRoundResults = (roomId) => {
const gameState = gameStates[roomId];
if (!gameState) return null;
if (!gameState) return {round: 0, scores: {}, guessResults: {}, selectedSong: null};
return {
round: gameState.round,
selectedSong: gameState.selectedSong,
@ -161,22 +168,6 @@ const getRoundResults = (roomId) => {
};
};
const getRoles = (roomId) => {
return gameStates[roomId]?.roles || {};
};
const getUserRole = (roomId, userId) => {
return gameStates[roomId]?.roles[userId] || null;
};
const getSongOptions = (roomId) => {
return gameStates[roomId]?.songOptions || [];
};
const getSelectedSong = (roomId) => {
return gameStates[roomId]?.selectedSong || null;
};
const cleanupGameState = (roomId) => {
delete gameStates[roomId];
};

View File

@ -4,7 +4,6 @@ const gameController = require("../controller/game");
module.exports = (io) => (socket) => {
let currentRoomId = null;
let currentUser = null;
let phaseTimers = {};
const clearRoomTimers = (roomId) => {
@ -18,62 +17,75 @@ module.exports = (io) => (socket) => {
clearRoomTimers(roomId);
const timeRemaining = gameController.getTimeRemaining(roomId) * 1000;
phaseTimers[roomId] = setTimeout(() => {
const advanced = gameController.advancePhase(roomId);
if (advanced) {
if (!advanced) return;
if (typeof advanced === 'boolean') {
handleRoundStart(roomId);
} else {
const currentPhase = advanced.phase || 'results';
if (currentPhase === 'guessing') {
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);
}
else if (currentPhase === 'results') {
const results = gameController.getRoundResults(roomId);
io.to(roomId).emit('round-results', results);
}
else if (typeof advanced === 'boolean' && advanced) {
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);
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);
if (roomId) {
socket.to(roomId).emit("user-disconnected", socket.id);
roomController.disconnectUser(socket.id);
}
});
socket.on("join-room", ({roomId, name}) => {
@ -92,7 +104,6 @@ module.exports = (io) => (socket) => {
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);
@ -104,6 +115,7 @@ module.exports = (io) => (socket) => {
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);
@ -114,51 +126,32 @@ module.exports = (io) => (socket) => {
socket.on("start-game", () => {
const roomId = roomController.getUserRoom(socket.id);
if (roomId && roomController.isUserHost(socket.id)) {
roomController.validateRoomMembers(io, roomId);
const roomUsers = roomController.getRoomUsers(roomId);
if (roomController.startGame(roomId)) {
gameController.initializeGameState(roomId);
if (gameController.startNewRound(roomId)) {
const roles = gameController.getRoles(roomId);
const selectedSong = gameController.getSelectedSong(roomId);
io.to(roomId).emit("game-started");
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: 1,
timeRemaining: gameController.getTimeRemaining(roomId)
});
startPhaseTimer(roomId);
}
} else {
socket.emit("not-authorized");
}
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);
}
if (roomId) socket.to(roomId).emit("chat-message", messageData);
});
socket.on("get-user-info", () => {
if (currentUser) {
socket.emit("user-info", currentUser);
}
if (currentUser) socket.emit("user-info", currentUser);
});
socket.on("get-room-users", () => {
@ -170,72 +163,55 @@ module.exports = (io) => (socket) => {
});
socket.on("check-host-status", () => {
const isHost = roomController.isUserHost(socket.id);
socket.emit("host-status", { isHost });
socket.emit("host-status", { isHost: roomController.isUserHost(socket.id) });
});
socket.on("get-room-code", () => {
if (currentRoomId) {
socket.emit("room-code", currentRoomId);
}
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') {
if (gameController.updateFrequency(roomId, frequency)) {
socket.to(roomId).emit("frequency-update", { frequency });
}
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);
}
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 roomUsers = roomController.getRoomUsers(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)) {
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);
handleRoundStart(roomId);
}
});
socket.on("get-current-frequency", () => {
const roomId = roomController.getUserRoom(socket.id);
if (!roomId) return;
const frequency = gameController.getCurrentFrequency(roomId);
socket.emit("current-frequency", { frequency });
if (roomId) {
socket.emit("current-frequency", {
frequency: gameController.getCurrentFrequency(roomId)
});
}
});
};