diff --git a/src/routes/game.ts b/src/routes/game.ts index 5451650..c62eea5 100644 --- a/src/routes/game.ts +++ b/src/routes/game.ts @@ -2,15 +2,11 @@ import express from 'express'; import { Game } from '../models/models'; import messages from '../utils/messages'; -import words from '../utils/words'; -import wordGenerator from '../utils/wordGenerator'; -import getNextPasswordHolder from '../utils/getNextPasswordHolder'; const router = express.Router(); const MAX_HINTS = process.env.MAX_HINTS ? Number(process.env.MAX_HINTS) : 4; const MAX_HINT_LENGTH = process.env.MAX_HINT_LENGTH ? Number(process.env.MAX_HINT_LENGTH) : 25; -const DURATION = process.env.DURATION ? Number(process.env.DURATION) : 60; router.post('/start', async (req: express.Request, res: express.Response) => { const { @@ -86,99 +82,7 @@ router.post('/next', async (req: express.Request, res: express.Response) => { res.json({ success: false, message: messages.userNotFound }); return; } - if (game.solvedBy.length !== (game.players.length - 1) - && new Date().getTime() < game.time.end) { - const previousPassword = game.usedPasswords.length > 1 ? game.usedPasswords.slice(-2)[0] : ''; - const currentPassword = username === game.passwordHolder ? game.password : ''; - - res.json({ - success: true, - message: { - players: game.players, - currentRound: game.currentRound, - rounds: game.rounds, - passwordHolder: game.passwordHolder, - passwordLength: game.password.length, - previousPassword, - currentPassword, - hints: game.hints, - roundEnd: game.time.end, - }, - }); - return; - } - - const { passwordHolder } = game; - - const { nextPasswordHolder, currentRound } = getNextPasswordHolder(passwordHolder, game); - game.currentRound = currentRound; - - if (game.currentRound > game.rounds) { - game.players = game.players.map((player) => { - const p = player; - p.points = 0; - return p; - }); - game.hasStarted = false; - game.rounds = 3; - game.currentRound = 1; - game.password = ''; - game.passwordHolder = ''; - game.usedPasswords = []; - game.time.start = new Date().getTime(); - game.time.end = new Date().getTime(); - game.markModified('usedPasswords'); - game.solvedBy = []; - game.markModified('solvedBy'); - game.hints = []; - game.markModified('hints'); - try { - await game.save(); - } catch (e) { - if (e.name === 'VersionError') { - res.json({ success: false, message: messages.versionError }); - return; - } - } - res.json({ success: false, message: messages.gameEnded }); - return; - } - - let password = wordGenerator(); - - if (words.length > game.usedPasswords.length) { - while (game.usedPasswords.includes(password)) { - password = wordGenerator(); - } - } - - password = password.toLowerCase(); - - const previousPassword = game.password || ''; - - const date: Date = new Date(); - const time = date.getTime(); - - game.time.start = time; - game.time.end = time + (DURATION * 1000); - game.password = password; - game.passwordHolder = nextPasswordHolder; - game.usedPasswords.push(password); - game.markModified('usedPasswords'); - game.solvedBy = []; - game.markModified('solvedBy'); - game.hints = []; - game.markModified('hints'); - - try { - await game.save(); - } catch (e) { - if (e.name === 'VersionError') { - res.json({ success: false, message: messages.versionError }); - return; - } - } - + const previousPassword = game.usedPasswords.length > 1 ? game.usedPasswords.slice(-2)[0] : ''; const currentPassword = username === game.passwordHolder ? game.password : ''; res.json({ @@ -187,8 +91,8 @@ router.post('/next', async (req: express.Request, res: express.Response) => { players: game.players, currentRound: game.currentRound, rounds: game.rounds, - passwordHolder: nextPasswordHolder, - passwordLength: password.length, + passwordHolder: game.passwordHolder, + passwordLength: game.password.length, previousPassword, currentPassword, hints: game.hints, diff --git a/src/sockets/game.ts b/src/sockets/game.ts index 3f6e000..42abd62 100644 --- a/src/sockets/game.ts +++ b/src/sockets/game.ts @@ -4,6 +4,7 @@ import { Game } from '../models/models'; import { PlayerInterface } from '../models/player'; import attempt from '../utils/attempt'; import messages from '../utils/messages'; +import timeHandler from './timeHandler'; export async function onStart( data: { roomId: string }, @@ -22,6 +23,8 @@ export async function onStart( return; } + timeHandler(data, io, namespace); + io.of(namespace).in(roomId).emit('start', { hasStarted: true, roomId, diff --git a/src/sockets/timeHandler.ts b/src/sockets/timeHandler.ts new file mode 100644 index 0000000..d8de740 --- /dev/null +++ b/src/sockets/timeHandler.ts @@ -0,0 +1,84 @@ +import socketio from 'socket.io'; + +import words from '../utils/words'; +import { Game } from '../models/models'; +import wordGenerator from '../utils/wordGenerator'; +import liveGames from '../utils/liveGames'; +import getNextPasswordHolder from '../utils/getNextPasswordHolder'; + +const DURATION = process.env.DURATION ? Number(process.env.DURATION) : 60; + +export default async function timeHandler( + data: { roomId: string }, + io: socketio.Server, + namespace: string, +) { + const { roomId } = data; + + const game = await Game.findOne({ roomId }); + + if (!game || !game.hasStarted) { + return; + } + + const { passwordHolder } = game; + + const { nextPasswordHolder, currentRound } = getNextPasswordHolder(passwordHolder, game); + game.currentRound = currentRound; + + if (game.currentRound > game.rounds) { + game.players = game.players.map((player) => { + const p = player; + p.points = 0; + return p; + }); + game.hasStarted = false; + game.rounds = 3; + game.currentRound = 1; + game.password = ''; + game.passwordHolder = ''; + game.usedPasswords = []; + game.time.start = new Date().getTime(); + game.time.end = new Date().getTime(); + game.markModified('usedPasswords'); + game.solvedBy = []; + game.markModified('solvedBy'); + game.hints = []; + game.markModified('hints'); + + await game.save(); + return; + } + + let password = wordGenerator(); + + if (words.length > game.usedPasswords.length) { + while (game.usedPasswords.includes(password)) { + password = wordGenerator(); + } + } + + password = password.toLowerCase(); + + const date: Date = new Date(); + const time = date.getTime(); + + game.time.start = time; + game.time.end = time + (DURATION * 1000); + game.password = password; + game.passwordHolder = nextPasswordHolder; + game.usedPasswords.push(password); + game.markModified('usedPasswords'); + game.solvedBy = []; + game.markModified('solvedBy'); + game.hints = []; + game.markModified('hints'); + + await game.save(); + + io.of(namespace).in(roomId).emit('next'); + + liveGames.setGame(roomId, setTimeout(() => { + timeHandler({ roomId }, io, namespace); + }, DURATION * 1000)); +} diff --git a/src/utils/liveGames.ts b/src/utils/liveGames.ts new file mode 100644 index 0000000..6577754 --- /dev/null +++ b/src/utils/liveGames.ts @@ -0,0 +1,18 @@ +class LiveGames { + private games: { [roomId: string]: { timeout: NodeJS.Timeout } }; + + constructor() { + this.games = {}; + } + + getGame(roomId: string) { + return this.games[roomId]; + } + + setGame(roomId: string, timeout: NodeJS.Timeout) { + this.games[roomId] = { timeout }; + } +} + +const liveGames = new LiveGames(); +export default liveGames;