diff --git a/Server/src/API/setupAPI.ts b/Server/src/API/setupAPI.ts index 3dbb297..49ddcef 100644 --- a/Server/src/API/setupAPI.ts +++ b/Server/src/API/setupAPI.ts @@ -1,11 +1,11 @@ import { Express } from 'express-serve-static-core'; import { setupUpload } from './questions.js'; import { setupServerStatus } from './serverStatus.js'; -import { setupGame } from './game.js'; +import { setupTest } from './setupTest.js'; // IMPORTA TUTTE LE API DEI VARI FILE export const setupAPI = (app: Express) => { setupUpload(app); setupServerStatus(app); - setupGame(app); + setupTest(app); } diff --git a/Server/src/API/setupTest.ts b/Server/src/API/setupTest.ts new file mode 100644 index 0000000..daf91e9 --- /dev/null +++ b/Server/src/API/setupTest.ts @@ -0,0 +1,125 @@ +import { Express } from 'express-serve-static-core'; +import { Request, Response, NextFunction } from 'express'; +import { GameManager } from "../data/GameManager.js"; +import { performance, PerformanceObserver } from 'perf_hooks'; + +export function setupTest(app: Express) { + + + const authMiddleware = (req: Request, res: Response, next: NextFunction) => { + const token = req.headers['authorization']; + if (token && token === process.env.SECRET_TOKEN) { + next(); + } else { + res.status(403).json({ error: 'Accesso non autorizzato' }); + } + }; + + app.post('/api/start-test', authMiddleware, async (req, res) => { + + // Crea un osservatore per il monitoraggio delle performance + const obs = new PerformanceObserver((list) => { + for (const entry of list.getEntries()) { + console.log(`${entry.name}: ${entry.duration} ms`); + } + }); + obs.observe({ entryTypes: ['measure'] }); + + const { numGames, numPlayers, numRounds } = req.query; + + // Converti i parametri in numeri + const numGamesParsed = parseInt(numGames as string, 10); + const numPlayersParsed = parseInt(numPlayers as string, 10); + const numRoundsParsed = parseInt(numRounds as string, 10); + + try { + performance.mark('start'); + const result = await mainTest(numGamesParsed, numPlayersParsed, numRoundsParsed); + performance.mark('end'); + performance.measure('someFunction', 'start', 'end'); + res.status(200).json({ message: result }); + } catch (error) { + res.status(500).json({ error: "Errore durante l'esecuzione del test", details: error }); + } + }); +} + +function* makeId(): Generator { + let i = 0; + while (true) { + yield '' + i++; + } +} + +async function mainTest(numGames: number, numPlayers: number, numRounds: number) { + console.log('Inizio Test'); + const TestManager = new GameManager(); + + // 1. Creazione dei giochi contemporaneamente + const gameIdGenerator = makeId(); + await Promise.all( + Array.from({ length: numGames }).map(async () => { + const gameId = gameIdGenerator.next().value; + return TestManager.createGame(gameId, 'testADMIN'); + }) + ); + + // 2. Aggiunta giocatori e avvio dei giochi + await Promise.all( + TestManager.listGames().map(async (game) => { + // Aggiunge i giocatori contemporaneamente + await Promise.all( + Array.from({ length: numPlayers }).map(async (_, i) => { + const player = game.addPlayer('test' + i, 'testSocket' + i, 'img'); + player.isReadyToGame = true; + player.readyForNextQuestion = true; + }) + ); + // Avvia il gioco se tutti i giocatori sono pronti + if (game.isAllPlayersReadyToGame()) { + game.isGameStarted = true; + } + }) + ); + + // 3. Simulazione voti per ogni turno in ogni gioco + for (let round = 0; round < numRounds; round++) { + await Promise.all( + TestManager.listGames().map(async (game) => { + try { + // Votazione contemporanea dei giocatori + await Promise.all( + Object.values(game.players).map(async (player) => { + try { + player.readyForNextQuestion = false; + game.castVote(player.name, 'test0'); + player.readyForNextQuestion = true; + } catch (err) { + console.error(`Errore nella votazione per il giocatore ${player.name}:`, err); + } + }) + ); + // Se tutti i giocatori hanno votato, avanzare + if (game.didAllPlayersVote()) { + game.getMostVotedPerson(); + game.resetWhatPlayersVoted(); + } else { + } + } catch (err) { + console.error(`Errore nel ciclo di votazione per il gioco ${game.lobbyCode}:`, err); + } + }) + ); + } + + + // 4. Eliminazione dei giochi alla fine + await Promise.all( + TestManager.listGames().map(async (game) => { + TestManager.deleteGame(game.lobbyCode); + }) + ); + + console.log('Fine test'); + +} diff --git a/Server/src/data/Game.ts b/Server/src/data/Game.ts index 5248a43..13d5d8a 100644 --- a/Server/src/data/Game.ts +++ b/Server/src/data/Game.ts @@ -99,9 +99,10 @@ export class Game { * @param socketId - Socket ID of the player * @param image - URL of the player's image */ - addPlayer(playerName: string, socketId: string, image: string): void { + addPlayer(playerName: string, socketId: string, image: string): Player { if (!(playerName in this.players)) { this.players[playerName] = new Player(playerName, socketId, image); + return this.players[playerName]; } } @@ -133,7 +134,9 @@ export class Game { this.players[playerName].whatPlayerVoted = vote; // Set the player's vote // save the value inside the GAME for late state // TODO valore "duplicato" per fare prima, potenzialmente ok - this.selectedQuestions[this.currentQuestionIndex].whatPlayersVoted[playerName] = vote; + // TODO fix this nigga + if (this.selectedQuestions.length !== 0) + this.selectedQuestions[this.currentQuestionIndex].whatPlayersVoted[playerName] = vote; this.numOfVoters++; } else { console.error('Player not found.');