Configurable rates, handle ping exceptions, Mojang service tracking
This commit is contained in:
parent
72172514b0
commit
da5dd8b026
27
app.js
27
app.js
@ -1,6 +1,7 @@
|
|||||||
var server = require('./lib/server');
|
var server = require('./lib/server');
|
||||||
var ping = require('./lib/ping');
|
var ping = require('./lib/ping');
|
||||||
var logger = require('./lib/logger');
|
var logger = require('./lib/logger');
|
||||||
|
var mojang = require('./lib/mojang_services');
|
||||||
|
|
||||||
var config = require('./config.json');
|
var config = require('./config.json');
|
||||||
|
|
||||||
@ -13,10 +14,10 @@ function pingAll() {
|
|||||||
for (var i = 0; i < servers.length; i++) {
|
for (var i = 0; i < servers.length; i++) {
|
||||||
// Make sure we lock our scope.
|
// Make sure we lock our scope.
|
||||||
(function(network) {
|
(function(network) {
|
||||||
ping.ping(network.ip, network.port, network.type, 2500, function(err, res) {
|
ping.ping(network.ip, network.port, network.type, config.rates.connectTimeout, function(err, res) {
|
||||||
// Handle our ping results, if it succeeded.
|
// Handle our ping results, if it succeeded.
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.log('error', 'Failed to ping ' + network.ip + ': ' + err);
|
logger.log('error', 'Failed to ping ' + network.ip + ': ' + JSON.stringify(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
server.io.sockets.emit('update', res);
|
server.io.sockets.emit('update', res);
|
||||||
@ -47,6 +48,23 @@ function pingAll() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start our main loop that does everything.
|
||||||
|
function startMainLoop() {
|
||||||
|
setInterval(pingAll, config.rates.pingAll);
|
||||||
|
|
||||||
|
setInterval(function() {
|
||||||
|
mojang.update(config.rates.mojangStatusTimeout);
|
||||||
|
|
||||||
|
server.io.sockets.emit('updateMojangServices', mojang.toMessage());
|
||||||
|
}, config.rates.upateMojangStatus);
|
||||||
|
|
||||||
|
// Manually fire the first round of our tasks.
|
||||||
|
mojang.update(config.rates.mojangStatusTimeout);
|
||||||
|
server.io.sockets.emit('updateMojangServices', mojang.toMessage());
|
||||||
|
|
||||||
|
pingAll();
|
||||||
|
}
|
||||||
|
|
||||||
server.start(function() {
|
server.start(function() {
|
||||||
// Track how many people are currently connected.
|
// Track how many people are currently connected.
|
||||||
server.io.on('connect', function(client) {
|
server.io.on('connect', function(client) {
|
||||||
@ -74,8 +92,5 @@ server.start(function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start our main loop that fires off pings.
|
startMainLoop();
|
||||||
setInterval(pingAll, 2500);
|
|
||||||
|
|
||||||
pingAll();
|
|
||||||
});
|
});
|
@ -30,5 +30,11 @@
|
|||||||
"site": {
|
"site": {
|
||||||
"port": 80,
|
"port": 80,
|
||||||
"ip": "0.0.0.0"
|
"ip": "0.0.0.0"
|
||||||
|
},
|
||||||
|
"rates": {
|
||||||
|
"upateMojangStatus": 5000,
|
||||||
|
"mojangStatusTimeout": 3500,
|
||||||
|
"pingAll": 2500,
|
||||||
|
"connectTimeout": 2500
|
||||||
}
|
}
|
||||||
}
|
}
|
80
lib/mojang_services.js
Normal file
80
lib/mojang_services.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
var request = require('request');
|
||||||
|
|
||||||
|
var logger = require('./logger');
|
||||||
|
|
||||||
|
var serviceNameLookup = {
|
||||||
|
'minecraft.net': 'Website',
|
||||||
|
'sessionserver.mojang.com': 'Sessions',
|
||||||
|
'authserver.mojang.com': 'Auth',
|
||||||
|
'textures.minecraft.net': 'Skins',
|
||||||
|
'api.mojang.com': 'API'
|
||||||
|
};
|
||||||
|
|
||||||
|
var serviceStates = {
|
||||||
|
// Lazy populated.
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateService(name, status) {
|
||||||
|
// Only update if we need to.
|
||||||
|
if (!(name in serviceStates) || serviceStates[name].status !== status) {
|
||||||
|
var newEntry = {
|
||||||
|
name: serviceNameLookup[name], // Send the clean name, not the URL.
|
||||||
|
status: status
|
||||||
|
};
|
||||||
|
|
||||||
|
// If it's an outage, track when it started.
|
||||||
|
if (status === 'yellow'|| status === 'red') {
|
||||||
|
newEntry.startTime = (new Date).getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a nice title from the color.
|
||||||
|
if (status === 'green') {
|
||||||
|
newEntry.title = 'Online';
|
||||||
|
} else if (status === 'yellow') {
|
||||||
|
newEntry.title = 'Unstable';
|
||||||
|
} else if (status === 'red') {
|
||||||
|
newEntry.title = 'Offline';
|
||||||
|
} else {
|
||||||
|
throw new Error('Unknown Mojang status: ' + status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wipe the old status in favor of the new one.
|
||||||
|
serviceStates[name] = newEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.update = function(timeout) {
|
||||||
|
request({
|
||||||
|
uri: 'http://status.mojang.com/check',
|
||||||
|
method: 'GET',
|
||||||
|
timeout: timeout
|
||||||
|
}, function(err, res, body) {
|
||||||
|
if (err) {
|
||||||
|
logger.log('error', 'Failed to update Mojang services: %s', JSON.stringify(err));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
body = JSON.parse(body);
|
||||||
|
|
||||||
|
for (var i = 0; i < body.length; i++) {
|
||||||
|
var service = body[i];
|
||||||
|
var name = Object.keys(service)[0]; // Because they return an array of object, we have to do this :(
|
||||||
|
|
||||||
|
// If it's not in the lookup, we don't care about it.
|
||||||
|
if (name in serviceNameLookup) {
|
||||||
|
updateService(name, service[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.log('debug', 'Updated Mojang services: %s', JSON.stringify(serviceStates));
|
||||||
|
} catch(err) {
|
||||||
|
// Catch anything weird that can happen, since things probably will.
|
||||||
|
logger.log('error', 'Failed to parse Mojang\'s response: %s', JSON.stringify(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.toMessage = function() {
|
||||||
|
// This is what we send to the clients.
|
||||||
|
return serviceStates;
|
||||||
|
};
|
70
lib/ping.js
70
lib/ping.js
@ -5,42 +5,52 @@ var mcpc_ping = require('mc-ping-updated');
|
|||||||
function pingMinecraftPC(host, port, timeout, callback) {
|
function pingMinecraftPC(host, port, timeout, callback) {
|
||||||
var milliseconds = (new Date).getTime();
|
var milliseconds = (new Date).getTime();
|
||||||
|
|
||||||
mcpc_ping(host, port, function(err, res) {
|
// Try catch incase the down stream module is bad at handling exceptions.
|
||||||
if (err) {
|
try {
|
||||||
callback(err, null);
|
mcpc_ping(host, port, function(err, res) {
|
||||||
} else {
|
if (err) {
|
||||||
// Remap our JSON into our custom structure.
|
callback(err, null);
|
||||||
callback(null, {
|
} else {
|
||||||
players: {
|
// Remap our JSON into our custom structure.
|
||||||
online: res.players.online,
|
callback(null, {
|
||||||
max: res.players.max
|
players: {
|
||||||
},
|
online: res.players.online,
|
||||||
version: res.version.protocol,
|
max: res.players.max
|
||||||
latency: (new Date).getTime() - milliseconds
|
},
|
||||||
});
|
version: res.version.protocol,
|
||||||
}
|
latency: (new Date).getTime() - milliseconds
|
||||||
}, timeout);
|
});
|
||||||
|
}
|
||||||
|
}, timeout);
|
||||||
|
} catch (err) {
|
||||||
|
callback(err, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a wrapper function for mcpe-ping, mainly used to convert the data structure of the result.
|
// This is a wrapper function for mcpe-ping, mainly used to convert the data structure of the result.
|
||||||
function pingMinecraftPE(host, port, timeout, callback) {
|
function pingMinecraftPE(host, port, timeout, callback) {
|
||||||
var milliseconds = (new Date).getTime();
|
var milliseconds = (new Date).getTime();
|
||||||
|
|
||||||
mcpe_ping(host, port || 19132, function(err, res) {
|
// Try catch incase the down stream module is bad at handling exceptions.
|
||||||
if (err) {
|
try {
|
||||||
callback(err, null);
|
mcpe_ping(host, port || 19132, function(err, res) {
|
||||||
} else {
|
if (err) {
|
||||||
// Remap our JSON into our custom structure.
|
callback(err, null);
|
||||||
callback(err, {
|
} else {
|
||||||
players: {
|
// Remap our JSON into our custom structure.
|
||||||
online: res.currentPlayers,
|
callback(err, {
|
||||||
max: res.maxPlayers
|
players: {
|
||||||
},
|
online: res.currentPlayers,
|
||||||
version: res.version,
|
max: res.maxPlayers
|
||||||
latency: (new Date).getTime() - milliseconds
|
},
|
||||||
});
|
version: res.version,
|
||||||
}
|
latency: (new Date).getTime() - milliseconds
|
||||||
}, timeout);
|
});
|
||||||
|
}
|
||||||
|
}, timeout);
|
||||||
|
} catch (err) {
|
||||||
|
callback(err, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.ping = function(host, port, type, timeout, callback) {
|
exports.ping = function(host, port, type, timeout, callback) {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
"mc-ping-updated": "0.0.6",
|
"mc-ping-updated": "0.0.6",
|
||||||
"mcpe-ping": "0.0.3",
|
"mcpe-ping": "0.0.3",
|
||||||
"mime": "^1.3.4",
|
"mime": "^1.3.4",
|
||||||
|
"request": "^2.65.0",
|
||||||
"socket.io": "^1.3.7",
|
"socket.io": "^1.3.7",
|
||||||
"winston": "^2.0.0"
|
"winston": "^2.0.0"
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user