123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- var express = require('express')
- , favicon = require('serve-favicon')
- , bodyParser = require('body-parser')
- , logger = require('morgan')
- , cookieParser = require('cookie-parser')
- , session = require('express-session')
- , methodOverride = require('express-method-override')
- , errorhandler = require('errorhandler')
- , path = require('path')
- , crypto = require('crypto')
- , http = require('http')
- , winston = require('winston')
- , fs = require('fs');
- var app = express();
- app.set('port', process.env.OPENSHIFT_NODEJS_PORT || 8181);
- app.set('views', __dirname + '/views');
- app.set('view engine', 'jade');
- //app.use(favicon());
- //app.use(logger('dev'));
- app.use(bodyParser());
- app.use(methodOverride());
- app.use(cookieParser('45710b553b5b7293753d03bd3601f70a'));
- app.use(session());
- //app.use(app.router);
- app.use(express.static(path.join(__dirname, 'public')));
-
- //app.use(errorHandler());
- app.get('/', function(req, res) {
- res.render('index');
- });
- app.get('/about', function(req, res) {
- res.render('about');
- });
- app.get('/play/:token/:time/:increment', function(req, res) {
- res.render('play', {
- 'token': req.params.token,
- 'time': req.params.time,
- 'increment': req.params.increment
- });
- });
- app.get('/logs', function(req, res) {
- fs.readFile(__dirname + '/logs/games.log', function (err, data) {
- if (err) {
- res.redirect('/');
- }
- res.set('Content-Type', 'text/plain');
- res.send(data);
- });
- });
- var server = http.createServer(app).listen(app.get('port'), app.get('ipaddress'), function() {
- console.log("Express server listening on port " + app.get('port'));
- });
- var games = {};
- var timer;
- /**
- * Sockets
- */
- var io = require('socket.io').listen(server, {log: false});
- if (process.env.OPENSHIFT_NODEJS_IP) {
- io.configure(function(){
- io.set('transports', ['websocket']);
- });
- }
- io.sockets.on('connection', function (socket) {
-
- socket.on('start', function (data) {
- var token;
- var b = new Buffer(Math.random() + new Date().getTime() + socket.id);
- token = b.toString('base64').slice(12, 32);
- //token is valid for 5 minutes
- var timeout = setTimeout(function () {
- if (games[token].players.length === 0) {
- delete games[token];
- socket.emit('token-expired');
- }
- }, 5 * 60 * 1000);
- games[token] = {
- 'creator': socket,
- 'players': [],
- 'interval': null,
- 'timeout': timeout
- };
- socket.emit('created', {
- 'token': token
- });
- });
- socket.on('join', function (data) {
- var game, color, time = data.time;
- if (!(data.token in games)) {
- socket.emit('token-invalid');
- return;
- }
- clearTimeout(games[data.token].timeout);
- game = games[data.token];
- if (game.players.length >= 2) {
- socket.emit('full');
- return;
- } else if (game.players.length === 1) {
- if (game.players[0].color === 'black') {
- color = 'white';
- } else {
- color = 'black';
- }
- winston.log('info', 'Number of currently running games', { '#': Object.keys(games).length });
- } else {
- var colors = ['black', 'white'];
- color = colors[Math.floor(Math.random() * 2)];
- }
- //join room
- socket.join(data.token);
- games[data.token].players.push({
- 'id': socket.id,
- 'socket': socket,
- 'color': color,
- 'time': data.time - data.increment + 1,
- 'increment': data.increment
- });
- game.creator.emit('ready', {});
- socket.emit('joined', {
- 'color': color
- });
- });
- socket.on('timer-white', function (data) {
- runTimer('white', data.token, socket);
- });
- socket.on('timer-black', function (data) {
- runTimer('black', data.token, socket);
- });
- socket.on('timer-clear-interval', function (data) {
- if (data.token in games) {
- clearInterval(games[data.token].interval);
- }
- });
- socket.on('new-move', function (data) {
- var opponent;
- if (data.token in games) {
- opponent = getOpponent(data.token, socket);
- if (opponent) {
- opponent.socket.emit('move', {
- 'move': data.move
- });
- }
- }
- });
- socket.on('resign', function (data) {
- if (data.token in games) {
- clearInterval(games[data.token].interval);
- io.sockets.in(data.token).emit('player-resigned', {
- 'color': data.color
- });
- }
- });
- socket.on('rematch-offer', function (data) {
- var opponent;
-
- if (data.token in games) {
- opponent = getOpponent(data.token, socket);
- if (opponent) {
- opponent.socket.emit('rematch-offered');
- }
- }
- });
- socket.on('rematch-decline', function (data) {
- var opponent;
- if (data.token in games) {
- opponent = getOpponent(data.token, socket);
- if (opponent) {
- opponent.socket.emit('rematch-declined');
- }
- }
- });
- socket.on('rematch-confirm', function (data) {
- var opponent;
- if (data.token in games) {
- for(var j in games[data.token].players) {
- games[data.token].players[j].time = data.time - data.increment + 1;
- games[data.token].players[j].increment = data.increment;
- games[data.token].players[j].color = games[data.token].players[j].color === 'black' ? 'white' : 'black';
- }
- opponent = getOpponent(data.token, socket);
- if (opponent) {
- io.sockets.in(data.token).emit('rematch-confirmed');
- }
- }
- })
- socket.on('disconnect', function (data) {
- var player, opponent, game;
- for (var token in games) {
- game = games[token];
- for (var j in game.players) {
- player = game.players[j];
- if (player.socket === socket) {
- opponent = game.players[Math.abs(j - 1)];
- if (opponent) {
- opponent.socket.emit('opponent-disconnected');
- }
- clearInterval(games[token].interval);
- delete games[token];
- }
- }
- }
- });
- socket.on('send-message', function (data) {
- if (data.token in games) {
- var opponent = getOpponent(data.token, socket);
- if (opponent) {
- opponent.socket.emit('receive-message', data);
- }
- }
- });
- });
- function runTimer(color, token, socket) {
- var player, time_left, game = games[token];
- if (!game) return;
- for (var i in game.players) {
- player = game.players[i];
- if (player.socket === socket && player.color === color) {
- clearInterval(games[token].interval);
- games[token].players[i].time += games[token].players[i].increment;
- return games[token].interval = setInterval(function() {
- games[token].players[i].time -= 1;
- time_left = games[token].players[i].time;
- if (time_left >= 0) {
- io.sockets.in(token).emit('countdown', {
- 'time': time_left,
- 'color': color
- });
- } else {
- io.sockets.in(token).emit('countdown-gameover', {
- 'color': color
- });
- clearInterval(games[token].interval);
- }
- }, 1000);
- }
- }
- }
- function getOpponent(token, socket) {
- var player, game = games[token];
- for (var j in game.players) {
- player = game.players[j];
- if (player.socket === socket) {
- var opponent = game.players[Math.abs(j - 1)];
- return opponent;
- }
- }
- }
|