From c427dcc0cafeee66eada38fa48f68ff5b1f756b6 Mon Sep 17 00:00:00 2001 From: Rohan Mukherjee Date: Mon, 15 Jun 2020 01:40:59 +0530 Subject: [PATCH 1/5] feat: timeHandler to handle live games --- src/sockets/timeHandler.ts | 89 ++++++++++++++++++++++++++++++++++++++ src/utils/liveGames.ts | 9 ++++ 2 files changed, 98 insertions(+) create mode 100644 src/sockets/timeHandler.ts create mode 100644 src/utils/liveGames.ts diff --git a/src/sockets/timeHandler.ts b/src/sockets/timeHandler.ts new file mode 100644 index 0000000..bfa0e99 --- /dev/null +++ b/src/sockets/timeHandler.ts @@ -0,0 +1,89 @@ +import socketio from 'socket.io'; + +import words from '../utils/words'; +import { Game } from '../models/models'; +import wordGenerator from '../utils/wordGenerator'; +import { getLiveGames, setLiveGames } 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 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'); + + await game.save(); + + io.of(namespace).in(roomId).emit('next'); + + const liveGames = getLiveGames(); + liveGames[roomId].timeout = setTimeout(() => { + timeHandler({ roomId }, io, namespace); + }, DURATION * 1000); + + setLiveGames(liveGames); +} diff --git a/src/utils/liveGames.ts b/src/utils/liveGames.ts new file mode 100644 index 0000000..7e40b1a --- /dev/null +++ b/src/utils/liveGames.ts @@ -0,0 +1,9 @@ +let liveGames: { [key: string]: { timeout: NodeJS.Timeout } }; + +export function getLiveGames() { + return liveGames; +} + +export function setLiveGames(lg: { [key: string]: { timeout: NodeJS.Timeout } }) { + liveGames = lg; +} From 95510f41c98c20017510bf0013448ebb1cd71974 Mon Sep 17 00:00:00 2001 From: Rohan Mukherjee Date: Mon, 15 Jun 2020 01:46:02 +0530 Subject: [PATCH 2/5] feat: Modified /next route --- src/routes/game.ts | 102 ++------------------------------------------- 1 file changed, 3 insertions(+), 99 deletions(-) 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, From 563659c059f7c60185e57b0d1bd926f340413610 Mon Sep 17 00:00:00 2001 From: Rohan Mukherjee Date: Mon, 15 Jun 2020 01:52:03 +0530 Subject: [PATCH 3/5] fix: Remove comment --- src/sockets/timeHandler.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sockets/timeHandler.ts b/src/sockets/timeHandler.ts index bfa0e99..196db72 100644 --- a/src/sockets/timeHandler.ts +++ b/src/sockets/timeHandler.ts @@ -60,8 +60,6 @@ export default async function timeHandler( password = password.toLowerCase(); - // const previousPassword = game.password || ''; - const date: Date = new Date(); const time = date.getTime(); From b04a9fe566d6eaab7395058c49113dcec634a399 Mon Sep 17 00:00:00 2001 From: Rohan Mukherjee Date: Mon, 15 Jun 2020 17:15:11 +0530 Subject: [PATCH 4/5] feat: LiveGames is now a class --- src/sockets/timeHandler.ts | 9 +++------ src/utils/liveGames.ts | 17 +++++++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/sockets/timeHandler.ts b/src/sockets/timeHandler.ts index 196db72..d8de740 100644 --- a/src/sockets/timeHandler.ts +++ b/src/sockets/timeHandler.ts @@ -3,7 +3,7 @@ import socketio from 'socket.io'; import words from '../utils/words'; import { Game } from '../models/models'; import wordGenerator from '../utils/wordGenerator'; -import { getLiveGames, setLiveGames } from '../utils/liveGames'; +import liveGames from '../utils/liveGames'; import getNextPasswordHolder from '../utils/getNextPasswordHolder'; const DURATION = process.env.DURATION ? Number(process.env.DURATION) : 60; @@ -78,10 +78,7 @@ export default async function timeHandler( io.of(namespace).in(roomId).emit('next'); - const liveGames = getLiveGames(); - liveGames[roomId].timeout = setTimeout(() => { + liveGames.setGame(roomId, setTimeout(() => { timeHandler({ roomId }, io, namespace); - }, DURATION * 1000); - - setLiveGames(liveGames); + }, DURATION * 1000)); } diff --git a/src/utils/liveGames.ts b/src/utils/liveGames.ts index 7e40b1a..4d8b144 100644 --- a/src/utils/liveGames.ts +++ b/src/utils/liveGames.ts @@ -1,9 +1,14 @@ -let liveGames: { [key: string]: { timeout: NodeJS.Timeout } }; +class LiveGames { + private games: { [roomId: string]: { timeout: NodeJS.Timeout } }; -export function getLiveGames() { - return liveGames; -} + getGame(roomId: string) { + return this.games[roomId]; + } -export function setLiveGames(lg: { [key: string]: { timeout: NodeJS.Timeout } }) { - liveGames = lg; + setGame(roomId: string, timeout: NodeJS.Timeout) { + this.games[roomId] = { timeout }; + } } + +const liveGames = new LiveGames(); +export default liveGames; From 2dd62b6b1ec5dba59c3b33d5c7715b922ba7cd56 Mon Sep 17 00:00:00 2001 From: Rohan Mukherjee Date: Mon, 15 Jun 2020 17:47:49 +0530 Subject: [PATCH 5/5] feat: Use timehandler --- src/sockets/game.ts | 3 +++ src/utils/liveGames.ts | 4 ++++ 2 files changed, 7 insertions(+) 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/utils/liveGames.ts b/src/utils/liveGames.ts index 4d8b144..6577754 100644 --- a/src/utils/liveGames.ts +++ b/src/utils/liveGames.ts @@ -1,6 +1,10 @@ class LiveGames { private games: { [roomId: string]: { timeout: NodeJS.Timeout } }; + constructor() { + this.games = {}; + } + getGame(roomId: string) { return this.games[roomId]; }