add test, ping, and 2 API changes

* passing test: responds to ping requests
 * `mc.ping` - ping a server for info
 * `createServer`: `options.timeout` -> `options.checkTimeoutInterval`
 * `Client` emits `connect` event
This commit is contained in:
Andrew Kelley 2013-01-04 21:33:19 -05:00
parent 1661ef3b4b
commit 38194ee9b4
4 changed files with 90 additions and 12 deletions

View file

@ -9,10 +9,13 @@ var EventEmitter = require('events').EventEmitter
, Client = require('./lib/client')
, Server = require('./lib/server')
exports.createClient = createClient;
exports.createServer = createServer;
exports.Client = Client;
exports.Server = Server;
module.exports = {
createClient: createClient,
createServer: createServer,
Client: Client,
Server: Server,
ping: require('./lib/ping'),
};
function createServer(options) {
var port = options.port != null ?
@ -21,8 +24,8 @@ function createServer(options) {
options['server-port'] :
25565 ;
var host = options.host || '0.0.0.0';
var timeout = options.timeout || 10 * 1000;
var kickTimeout = options.kickTimeout || 4 * 1000;
var kickTimeout = options.kickTimeout || 10 * 1000;
var checkTimeoutInterval = options.checkTimeoutInterval || 4 * 1000;
var motd = options.motd || "A Minecraft server";
var onlineMode = options['online-mode'] == null ? true : options['online-mode'];
assert.ok(! onlineMode, "online mode for servers is not yet supported");
@ -47,10 +50,10 @@ function createServer(options) {
function keepAliveLoop() {
if (keepAlive) {
// check if the last keepAlive was too long ago (timeout)
// check if the last keepAlive was too long ago (kickTimeout)
if (lastKeepAlive) {
var elapsed = new Date() - lastKeepAlive;
if (elapsed > timeout) {
if (elapsed > kickTimeout) {
client.end('KeepAliveTimeout');
return;
}
@ -96,7 +99,7 @@ function createServer(options) {
clearTimeout(loginKickTimer);
loginKickTimer = null;
keepAliveTimer = setInterval(keepAliveLoop, kickTimeout);
keepAliveTimer = setInterval(keepAliveLoop, checkTimeoutInterval);
server.emit('login', client);
}

View file

@ -44,6 +44,10 @@ Client.prototype.setSocket = function(socket) {
self.socket.on('close', function() {
self.emit('end', self._endReason);
});
self.socket.on('connect', function() {
self.emit('connect');
});
};
Client.prototype.connect = function(port, host) {

38
lib/ping.js Normal file
View file

@ -0,0 +1,38 @@
var net = require('net')
, Client = require('./client')
module.exports = ping;
function ping(options, cb) {
var host = options.host || 'localhost';
var port = options.port || 25565;
var client = new Client();
client.on(0xff, function(packet) {
var parts = packet.reason.split('\u0000');
var results;
try {
results = {
prefix: parts[0],
protocol: parseInt(parts[1], 10),
version: parts[2],
motd: parts[3],
playerCount: parseInt(parts[4], 10),
maxPlayers: parseInt(parts[5], 10),
};
} catch (err) {
client.end();
cb(err);
return;
}
client.end();
cb(null, results);
});
client.on('error', function(err) {
cb(err);
});
client.on('connect', function() {
client.write(0xfe, { magic: 1 });
});
client.connect(port, host);
}

View file

@ -1,4 +1,5 @@
var mc = require('../')
, protocol = require('../lib/protocol')
, spawn = require('child_process').spawn
, path = require('path')
, fs = require('fs')
@ -108,6 +109,7 @@ describe("client", function() {
after(function(done) {
rimraf(MC_SERVER_PATH, done);
});
it("pings the server");
it("connects successfully - online mode", function(done) {
startServer({ 'online-mode': 'true' }, function() {
var client = mc.createClient({
@ -229,22 +231,53 @@ describe("server", function() {
it("kicks clients that do not log in", function(done) {
var server = mc.createServer({
'online-mode': false,
kickTimeout: 500,
kickTimeout: 100,
checkTimeoutInterval: 10,
});
var count = 2;
server.on('connection', function(client) {
client.on('end', function(reason) {
assert.strictEqual(reason, "LoginTimeout");
server.close();
});
});
server.on('close', function() {
resolve();
});
server.on('listening', function() {
var client = new mc.Client();
client.on('end', function() {
done();
resolve();
});
client.connect(25565, 'localhost');
});
function resolve() {
count -= 1;
if (count <= 0) done();
}
});
it("responds to ping requests", function(done) {
var server = mc.createServer({
'online-mode': false,
motd: 'test1234',
'max-players': 120,
});
server.on('listening', function() {
mc.ping({}, function(err, results) {
if (err) return done(err);
assert.deepEqual(results, {
prefix: "§1",
protocol: protocol.version,
version: protocol.minecraftVersion,
motd: 'test1234',
playerCount: 0,
maxPlayers: 120
});
done();
});
});
});
it("responds to ping requests");
it("clients can log in and chat");
it("gives correct reason for kicking clients when shutting down");
});