diff --git a/game.js b/game.js index 69afdc3..6fd8ac6 100755 --- a/game.js +++ b/game.js @@ -1,3 +1,5 @@ +var CLIENT_MSGS = ['init', 'take', 'hint', 'msg']; + var Game = function(io, hash, minPlayers) { this.io = io; this.players = [null, null, null, null, null, null, null, null]; @@ -51,10 +53,10 @@ Game.prototype.firstAvailablePlayerSlot = function() { return 0; } -Game.prototype.getPlayerIdx = function(client) { +Game.prototype.getPlayerIdx = function(socket) { for (var i = 0; i < this.players.length; i++) { if (this.players[i] !== null && - this.players[i].client.sessionId === client.sessionId) + this.players[i].socket.sessionId === socket.sessionId) return i; } return -1; @@ -74,20 +76,23 @@ Game.prototype.playerData = function() { return ret; } -Game.prototype.registerClient = function(client, sess) { +Game.prototype.registerClient = function(socket, sess) { if (this.numPlayers() >= this.players.length) return false; var self = this; - client.join(this.hash); + socket.join(this.hash); + for (var msg in CLIENT_MSGS) { + socket.on(msg, this.handleClientMessage(msg, socket)); + } for (var i = 0; i < this.players.length; i++) { var player = this.players[i]; if (player === null) continue; - if (player.client.sessionId === client.sessionId || player.sess === sess) { + if (player.socket.sessionId === socket.sessionId || player.sess === sess) { if (!player.online) { this.broadcast('rejoin', i); this.sendMsg({event: true, msg: 'Player ' + (i + 1) + ' has reconnected.'}); } player.online = true; - player.client = client; + player.socket = socket; player.sess = sess; this.updateRemaining(); return true; @@ -97,7 +102,7 @@ Game.prototype.registerClient = function(client, sess) { var playerIdx = this.firstAvailablePlayerSlot(); this.broadcast('join', playerIdx); this.sendMsg({event: true, msg: 'Player ' + (playerIdx + 1) + ' has joined.'}); - this.players[playerIdx] = new Player(client, sess); + this.players[playerIdx] = new Player(socket, sess); this.updateRemaining(); setTimeout(function() { @@ -110,8 +115,8 @@ Game.prototype.registerClient = function(client, sess) { return true; } -Game.prototype.unregisterClient = function(client, gameOver) { - var playerIdx = this.getPlayerIdx(client); +Game.prototype.unregisterClient = function(socket, gameOver) { + var playerIdx = this.getPlayerIdx(socket); if (playerIdx === -1) return; var self = this; @@ -124,6 +129,16 @@ Game.prototype.unregisterClient = function(client, gameOver) { }, 3600000); } +Game.prototype.handleClientMessage = function(message, socket) { + var func = this[message]; + var player = this.getPlayerIdx(socket); + return function(message) { + console.log('receiving ' + message + ' event with payload' + message); + if (player === -1) return; + func.call(this, player, message); + }; +} + Game.prototype.updateRemaining = function() { if (this.started) return; this.broadcast('remaining', this.minPlayers - this.numPlayers()); @@ -141,118 +156,103 @@ Game.prototype.sendMsg = function(msg) { this.broadcast('msg', msg); } -Game.prototype.message = function(client, message) { - if (!message.action) return; - var player = this.getPlayerIdx(client); - if (player === -1) return; - var self = this; - console.log('player ' + player + ' sends: '); - console.log(message); - - if (message.action === 'init') { - return client.send({ - action: 'init' - , board: this.board - , players: this.playerData() - , you: player - , msgs: this.messages - , remaining: this.started ? 0 : this.minPlayers - this.numPlayers() - }); - } - - if (message.action === 'take' && - 'selected' in message && - message.selected.length === 3) - { - if (this.checkSet(message.selected)) { - console.log('take set succeed'); - var update = {}; - if (!this.started && this.deck.length === 0) this.resetDeck(); - if (this.board.length <= 12 && this.deck.length > 0) { - message.selected.forEach( function(val) { - var c = this.deck.pop(); - update[val] = c; - this.board[val] = c; - }, this ); - } else { - var lastRow = this.board.length - 3; - var lastReplace = this.board.length - 1; - message.selected.sort( function reverse(a, b) { return b - a; } ); - message.selected.forEach( function(val) { - if (val >= lastRow) { - update[val] = false; - } else { - while (message.selected.indexOf(lastReplace) != -1) - lastReplace--; - update[val] = lastReplace--; - this.board[val] = this.board[update[val]]; - } - }, this); - this.board.splice(lastRow, 3); - } - this.players[player].score += (this.started ? 3 : 0); +Game.prototype.init = function(player) { + this.players[player].socket.emit('init', { + board: this.board + , players: this.playerData() + , you: player + , msgs: this.messages + , remaining: this.started ? 0 : this.minPlayers - this.numPlayers() + }); +} - if (this.winner === null || - !this.players[this.winner].online || - this.players[player].score > this.players[this.winner].score) { - this.winner = player; - } - - var playerUpdate = {}; - playerUpdate[player] = {score: this.players[player].score}; - this.puzzled = []; - this.hinted = null; - this.broadcast('taken', { - update: update - , player: player - , players: playerUpdate - }); - - if (this.deck.length === 0 && !this.checkSetExistence()) { - var winner = this.winner; - setTimeout(function() { self.broadcast('win', winner); }, 2000); - this.reset(); - } +Game.prototype.take = function(player, selected) { + if (selected.length !== 3) return; + if (this.checkSet(selected)) { + console.log('take set succeed'); + var update = {}; + if (!this.started && this.deck.length === 0) this.resetDeck(); + if (this.board.length <= 12 && this.deck.length > 0) { + selected.forEach( function(val) { + var c = this.deck.pop(); + update[val] = c; + this.board[val] = c; + }, this ); } else { - console.log('take set failed'); + var lastRow = this.board.length - 3; + var lastReplace = this.board.length - 1; + selected.sort( function reverse(a, b) { return b - a; } ); + selected.forEach( function(val) { + if (val >= lastRow) { + update[val] = false; + } else { + while (selected.indexOf(lastReplace) != -1) + lastReplace--; + update[val] = lastReplace--; + this.board[val] = this.board[update[val]]; + } + }, this); + this.board.splice(lastRow, 3); } - return; + this.players[player].score += (this.started ? 3 : 0); + + if (this.winner === null || + !this.players[this.winner].online || + this.players[player].score > this.players[this.winner].score) { + this.winner = player; + } + + var playerUpdate = {}; + playerUpdate[player] = {score: this.players[player].score}; + this.puzzled = []; + this.hinted = null; + this.broadcast('taken', { + update: update + , player: player + , players: playerUpdate + }); + + if (this.deck.length === 0 && !this.checkSetExistence()) { + var winner = this.winner; + var self = this; + setTimeout(function() { self.broadcast('win', winner); }, 2000); + this.reset(); + } + } else { + console.log('take set failed'); } +} - if (message.action === 'hint') { - if (this.puzzled.indexOf(player) != -1) return; - this.puzzled.push(player); - this.broadcast('puzzled', player); - var self = this; - setTimeout(function() { - console.log('hint timeout executing'); - if (self.puzzled.length < Math.ceil(self.numPlayers() * 0.51)) return; - if (!self.hinted) { - var setExists = self.checkSetExistence(); - if (setExists) { - self.hinted = setExists; - } else if (self.deck.length > 0) { - var newCards = []; - for (var i = 0; i < 3; i++) newCards.push(self.deck.pop()); - self.board = self.board.concat(newCards); - self.broadcast('add', newCards); - } - } - if (self.hinted && self.hinted.length > 0) { - self.broadcast('hint', self.hinted.pop()); +Game.prototype.hint = function(player) { + if (this.puzzled.indexOf(player) != -1) return; + this.puzzled.push(player); + this.broadcast('puzzled', player); + var self = this; + setTimeout(function() { + console.log('hint timeout executing'); + if (self.puzzled.length < Math.ceil(self.numPlayers() * 0.51)) return; + if (!self.hinted) { + var setExists = self.checkSetExistence(); + if (setExists) { + self.hinted = setExists; + } else if (self.deck.length > 0) { + var newCards = []; + for (var i = 0; i < 3; i++) newCards.push(self.deck.pop()); + self.board = self.board.concat(newCards); + self.broadcast('add', newCards); } - self.puzzled = []; - }, 1000); - return; - } + } + if (self.hinted && self.hinted.length > 0) { + self.broadcast('hint', self.hinted.pop()); + } + self.puzzled = []; + }, 1000); +} - if (message.action === 'msg' && - 'msg' in message && - message.msg.length < 1024) - { - var msg = message.msg.replace(//g, '>').replace(/\n/g, '
'); - return this.sendMsg({ player: player, msg: msg }); - } +Game.prototype.msg = function(player, msg) { + if (msg.length > 1024) return; + msg = msg.replace(//g, '>').replace(/\n/g, '
'); + return this.sendMsg({ player: player, msg: msg }); } Game.prototype.checkSetExistence = function() { @@ -304,8 +304,8 @@ function Card(idx) { this.shading = idx % 3; } -function Player(client, sess) { - this.client = client; +function Player(socket, sess) { + this.socket = socket; this.score = 0; this.sess = sess; this.online = true; diff --git a/server.js b/server.js index 1b0f98f..347fce9 100644 --- a/server.js +++ b/server.js @@ -88,6 +88,7 @@ io.sockets.on('connection', function(socket){ console.log(message); game = getGame(message.game); game.registerClient(socket, message.sess); + (game.handleClientMessage('init', socket)).call(game, message); if (message.game !== game.hash) socket.emit('setHash', game.hash); });