Created
July 16, 2014 11:15
-
-
Save EricCat/1b48803ea1b6b2cb6072 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Game Application | |
* | |
* @author Stableflow | |
* @version 1.0-RC1 | |
* | |
*/ | |
'use strict'; | |
/** | |
* | |
* Requires(3rd) | |
* | |
*/ | |
var express = require('express.io'), | |
cookie = require('cookie'), | |
redisConnect = require('redis'), | |
async = require('async'), | |
domain = require('domain'), | |
serverDm = domain.create(), | |
cluster = require('cluster'), | |
numCPUs = require('os').cpus().length, | |
Microtime = require('microtime'), | |
RedisStore = require('connect-redis')(express); | |
/** | |
* Requires(Custom) | |
* @type {exports} | |
*/ | |
var redis = require('./app/redis.js'), | |
mysql = require('./app/mysql.js'), | |
game = require('./app/game.js'), | |
user = require('./app/user.js'), | |
conf = require('./app/conf.js'), | |
config = new conf(), | |
mysqlquery = require('./app/lib/db/mysql-query.js'), | |
redisquery = require('./app/lib/cache/redis-query.js'); | |
/** | |
* Local Global Variable -- config, app, async, client, Microtime | |
* Only for readable | |
* can't writable | |
*/ | |
Object.defineProperties(global, { | |
"config": { | |
value: config, | |
writable:false, | |
configurable:false | |
}, | |
"app": { | |
value: express().http().io() | |
}, | |
"async": { | |
value: async | |
}, | |
"client": { | |
value: redisConnect.createClient(config.redis.port,config.redis.host, { | |
connect_timeout: 5000 | |
}) | |
}, | |
"Microtime": { | |
value: Microtime | |
}, | |
"Redis": { | |
value: redis | |
}, | |
"Mysql": { | |
value: mysql | |
}, | |
"User": { | |
value: user | |
}, | |
"Game": { | |
value: game | |
}, | |
"MysqlQuery": { | |
value: mysqlquery | |
}, | |
"RedisQuery": { | |
value: redisquery | |
} | |
}); | |
/** | |
* Error handler will be triggered, rather than crashing the program. | |
*/ | |
//serverDm.on('error', function(err) { | |
// console.error('Caught error!', err); | |
//}); | |
/** | |
* Domain Module for run game, not crashing the program. | |
*/ | |
//serverDm.run(function() { | |
/** | |
* local variable | |
* | |
*/ | |
var intervals = [], cookies; | |
/** | |
* Workers - for multi-core CPUs. Need to testing before use. | |
* | |
*/ | |
// function workers() { | |
global.app.listen(config.server.port, config.server.host); | |
global.app.io.configure(function() { | |
global.app.use(express.cookieParser()); | |
global.app.use(express.session({ | |
key: 'session.sid', | |
secret: config.server.secret, | |
store: new RedisStore({ | |
client: global.client | |
}) | |
})); | |
global.app.io.set('log level', config.server.loglevel); | |
global.app.set('x-powered-by', false); | |
if (config.server.minification) { | |
global.app.io.enable('browser client minification'); | |
} | |
if (config.server.etag) { | |
global.app.io.enable('browser client etag'); | |
} | |
if (config.server.gzip) { | |
global.app.io.enable('browser client gzip'); | |
} | |
global.app.io.set('authorization', function(handshake, callback) { | |
cookies = cookie.parse( | |
decodeURIComponent(handshake.headers.cookie), | |
config.server.secret); | |
if (!cookies.PHPSESSID) { | |
return callback('PHPSESSID Empty', false); | |
} | |
return callback(null, true); | |
}); | |
}); | |
/** | |
* Redis for multi-core CPUs | |
* Used with workers off (one core CPU) | |
*/ | |
global.app.io.set('store', new express.io.RedisStore({ | |
redisPub: redisConnect.createClient( | |
config.redis.port, config.redis.host), | |
redisSub: redisConnect.createClient( | |
config.redis.port, config.redis.host), | |
redisClient: redisConnect.createClient( | |
config.redis.port, config.redis.host) | |
})); | |
/** | |
* Start Storage | |
* | |
*/ | |
global.Redis.start(); | |
global.Mysql.start(); | |
/** | |
* Interval for update online users in MySQL database | |
* | |
*/ | |
setInterval(function() { | |
global.Redis.updateOnline(); | |
}, config.game.timeUpdate * 1000); | |
/** | |
* Interval for system info | |
* | |
*/ | |
setInterval(function() { | |
global.Game.tickSystem(); | |
}, 1000); | |
/** | |
* Dummy page (can change to redirect page) | |
* | |
*/ | |
global.app.get('/', function(req, res) { | |
// res.writeHead(302, { | |
// 'Location': Config.server.schema+Config.server.host | |
// }); | |
// res.end(); | |
//console.log('get /'); | |
//res.sendfile(__dirname + '/client.html') | |
return res.send("It Work's!"); | |
}); | |
/** | |
* Listen connection event | |
* | |
*/ | |
global.app.io.sockets.on('connection', function(socket) { | |
cookies = cookie.parse(decodeURIComponent(socket.handshake.headers.cookie), config.server.secret); | |
socket.PHPSESSID = cookies.PHPSESSID; | |
global.Mysql.checkPHPSESSID(socket); | |
}); | |
/*app.io.route('connect', function(req) { | |
console.log('connect'); | |
});*/ | |
/** | |
* Listen game events | |
* | |
*/ | |
global.app.io.route('game', { | |
ready: function(req) { // Client ready to game | |
console.log('game:ready'); | |
//check user ActiveTickets for Make sure the user has tickets available to play | |
global.User.hasActiveTickets(req.socket, function(hasTickets) { | |
if(hasTickets) { | |
global.client.hget('user:' + req.socket.user_id, 'ticket', function(err, ticket) { | |
if(err) { throw err; } | |
req.socket.emit('game', {gameEvent: 'ticket', ticket: ticket}); // emit user ticket | |
}); | |
} else { | |
// Report to the player that they have no available tickets | |
req.socket.emit('no-tickets', { | |
title: 'Out of tickets', | |
message: 'Your ticket balance has reached 0. ' + | |
'To continue to play you must purchase more tickets.' | |
}); | |
console.log('User has no active tickets'); | |
} | |
}); | |
}, | |
start: function(req) { // Client started game | |
console.log('game:start'); | |
//set game round number and cash prize | |
global.Game.setRound(req.socket); | |
// Initialize the game if active tickets were found | |
global.Game.start(req.socket); | |
// Check if a user is connected | |
intervals[req.socket.id] = setInterval(function() { | |
var connected = | |
req.socket.namespace.manager.connected[req.socket.id] === true; | |
if (connected) { | |
console.log('User #' + req.socket.user_id + ' is connected'); | |
} else { | |
clearInterval(intervals[req.socket.id]); | |
console.log('User #' + req.socket.user_id + ' is no longer connected'); | |
} | |
}, (global.config.game.playerTimeout * 1000)); | |
}, | |
answer: function(req) { // Answer for question | |
// Format: JSON | |
// { question: 'question hash', answer: 'answer hash' } | |
console.log('game:answer'); | |
//check user for game | |
global.User.hasGame(req.socket, function(hasGame) { | |
if (hasGame) { | |
global.Game.checkUserAnswer(req.socket, req.data); | |
} else { | |
req.socket.emit('no-game', { | |
title: 'No Game', | |
message: 'Could not register your answer. ' + | |
'It seems like you\'re not registered to a game' | |
}); | |
console.log( | |
'No answer will be checked. User is currently not in a game' | |
); | |
} | |
}); | |
}, | |
challenge: function(req) { | |
console.log('game:challenge'); | |
}, | |
leave: function(req) { | |
console.log('game:leave'); | |
//TODO: clear rank list | |
} | |
}); | |
global.app.io.route('disconnect', function(req) { // User has been disconnected | |
console.log('Disconnect'); | |
global.client.lrange( | |
'userquestions:' + req.socket.user_id, 0, 0, | |
function(err, res) { // Check for questions exists | |
if (res.length === 0) { | |
global.Mysql.restoreTicket(req.socket); | |
} | |
}); | |
global.Redis.removeUser(req.socket); | |
}); | |
// } | |
/** | |
* Cluster - for multicore CPUs | |
* | |
*/ | |
// if (cluster.isMaster) { | |
// for (var i = 0; i < numCPUs; i++) { cluster.fork() } | |
// } else { workers() } | |
//}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment