Skip to content

Instantly share code, notes, and snippets.

@EricCat
Created July 16, 2014 11:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EricCat/1b48803ea1b6b2cb6072 to your computer and use it in GitHub Desktop.
Save EricCat/1b48803ea1b6b2cb6072 to your computer and use it in GitHub Desktop.
/**
* 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