From 1eae5f63f6dbcfa18b55247782e2380b019eb985 Mon Sep 17 00:00:00 2001 From: Alec Maier Date: Mon, 2 Sep 2019 20:44:06 -0400 Subject: [PATCH] Added timer expiration end game scenario, cron job for clearing stale games --- create_game.html | 1 + package-lock.json | 21 +++++++++++++++++++++ package.json | 1 + server.js | 26 ++++++++++++++++---------- static/game.js | 10 +++++----- static/setup.js | 17 +++++++++++++++-- static/styles.css | 10 ++++++++-- 7 files changed, 67 insertions(+), 19 deletions(-) diff --git a/create_game.html b/create_game.html index 7f88328..63a3fc5 100644 --- a/create_game.html +++ b/create_game.html @@ -27,6 +27,7 @@

0 Players

+

diff --git a/package-lock.json b/package-lock.json index f345d98..5a6480e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -126,6 +126,14 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "cron": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/cron/-/cron-1.7.1.tgz", + "integrity": "sha512-gmMB/pJcqUVs/NklR1sCGlNYM7TizEw+1gebz20BMc/8bTm/r7QUp3ZPSPlG8Z5XRlvb7qhjEjq/+bdIfUCL2A==", + "requires": { + "moment-timezone": "^0.5.x" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -379,6 +387,19 @@ "mime-db": "1.40.0" } }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "moment-timezone": { + "version": "0.5.26", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.26.tgz", + "integrity": "sha512-sFP4cgEKTCymBBKgoxZjYzlSovC20Y6J7y3nanDc5RoBIXKlZhoYwBoZGe3flwU6A372AcRwScH8KiwV6zjy1g==", + "requires": { + "moment": ">= 2.9.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", diff --git a/package.json b/package.json index 898f2ed..e0a0652 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "author": "", "license": "ISC", "dependencies": { + "cron": "^1.7.1", "express": "^4.17.1", "socket.io": "^2.2.0" } diff --git a/server.js b/server.js index a7e8665..c85357d 100644 --- a/server.js +++ b/server.js @@ -6,8 +6,18 @@ const app = express(); const server = http.Server(app); const io = socketIO(server); +// cron job for periodically clearing finished games +const CronJob = require('cron').CronJob; + var activeGames = {}; +const job = new CronJob('* * 2 * * *', function() { + activeGames = activeGames.filter((game) => game.state !== "ended"); + console.log("Games pruned at: " + (new Date()).toDateString()); +}); +console.log("cron job created"); +job.start(); + app.set('port', 5000); app.use('/static', express.static(__dirname + '/static')); // Routing app.use('/assets', express.static(__dirname + '/assets')); // Routing @@ -32,16 +42,6 @@ server.listen(process.env.PORT || 5000, function() { console.log('Starting server on port 5000'); }); -function didVillageWin(game) { - let liveCount = 0; - for (const player of game.players) { - if (player.card.role === "Werewolf" && !player.dead) { - return false; - } - } - return true; -} - function teamWon(game) { let wolvesAlive = 0; let villagersAlive = 0; @@ -124,6 +124,12 @@ io.on('connection', function(socket) { game.endTime = newDate.toJSON(); io.to(code).emit('state', game); }); + socket.on("timerExpired", function(code) { + let game = activeGames[Object.keys(activeGames).find((key) => key === code)]; + game.winningTeam = "wolf"; + game.state = "ended"; + io.to(code).emit('state', game); + }); socket.on('killPlayer', function(id, code) { let game = activeGames[Object.keys(activeGames).find((key) => key === code)]; let player = game.players.find((player) => player.id === id); diff --git a/static/game.js b/static/game.js index 41988cf..8985cbb 100644 --- a/static/game.js +++ b/static/game.js @@ -187,8 +187,7 @@ function renderClock() { clearInterval(clock); } if (delta <= 0) { - clearInterval(clock); - endGame(true); + endGameDueToTimeExpired(); } else { let minutes = Math.floor((delta % (1000 * 60 * 60)) / (1000 * 60)); let seconds = Math.floor((delta % (1000 * 60)) / 1000); @@ -198,9 +197,10 @@ function renderClock() { }, 1000); } -function endGame(timeExpired) { - if (timeExpired) { - } +function endGameDueToTimeExpired() { + clearInterval(clock); + console.log("expired!"); + socket.emit("timerExpired", currentGame.accessCode); } function killPlayer() { diff --git a/static/setup.js b/static/setup.js index dff44c5..8d53297 100644 --- a/static/setup.js +++ b/static/setup.js @@ -30,7 +30,7 @@ class Game { var fullDeck = []; var gameSize = 0; -var time = null; +var atLeastOnePlayer = false; // register event listeners on buttons @@ -66,6 +66,12 @@ function updateGameSize() { gameSize += card.quantity; } document.getElementById("game-size").innerText = gameSize + " Players"; + if (gameSize > 0) { + atLeastOnePlayer = true; + } else { + atLeastOnePlayer = false; + } + return gameSize; } function resetCardQuantities() { @@ -91,7 +97,7 @@ function buildDeckFromQuantities() { } function createGame() { - if (document.getElementById("name").value.length > 0) { + if (document.getElementById("name").value.length > 0 && atLeastOnePlayer) { // generate 6 digit access code let code = ""; let charPool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; @@ -120,6 +126,13 @@ function createGame() { window.location.replace('/' + code); }); } else { + if (!atLeastOnePlayer) { + document.getElementById("game-size").classList.add("error"); + document.getElementById("size-error").innerText = "Add at least one card"; + } else { + document.getElementById("game-size").classList.remove("error"); + document.getElementById("size-error").innerText = ""; + } document.getElementById("name").classList.add("error"); document.getElementById("name-error").innerText = "Name is required."; } diff --git a/static/styles.css b/static/styles.css index 9a2b497..cb28171 100644 --- a/static/styles.css +++ b/static/styles.css @@ -127,7 +127,7 @@ button { background-color: rgba(189, 42, 42, 0.1) !important; } -#join-error, #name-error { +#join-error, #name-error, #size-error { color: #bd2a2a; font-size: 0.9em; height: 2em; @@ -256,6 +256,12 @@ button { margin: 3em 1em; } +#game-size { + border-radius: 5px; + padding: 0.3em 0.5em; + margin-right: 0.5em !important; +} + #create-game-container, #lobby-container, #join-game-container, #game-container, #launch, #message-box { animation: fadein 0.8s ease-in; } @@ -470,7 +476,7 @@ label { .killed-btn { border-radius: 5px; width: 13em; - font-size: 1.2em; + font-size: 1em; margin: 0 }