diff --git a/index.js b/index.js index 1125639..cd6aebe 100644 --- a/index.js +++ b/index.js @@ -34,7 +34,6 @@ function createServer(options) { server.on("connection", function(client) { client.once(0xfe, onPing); client.on(0x02, onHandshake); - client.on(0x00, onKeepAlive); client.on('end', onEnd); var keepAlive = false; @@ -49,19 +48,28 @@ function createServer(options) { } function keepAliveLoop() { - if (keepAlive) { - // check if the last keepAlive was too long ago (kickTimeout) - if (lastKeepAlive) { - var elapsed = new Date() - lastKeepAlive; - if (elapsed > kickTimeout) { - client.end('KeepAliveTimeout'); - return; - } - } - client.write(0x00, { - keepAliveId: Math.floor(Math.random() * 2147483648) - }); + if (! keepAlive) return; + + // check if the last keepAlive was too long ago (kickTimeout) + var elapsed = new Date() - lastKeepAlive; + if (elapsed > kickTimeout) { + client.end('KeepAliveTimeout'); + return; } + client.write(0x00, { + keepAliveId: Math.floor(Math.random() * 2147483648) + }); + } + + function onKeepAlive(packet) { + lastKeepAlive = new Date(); + } + + function startKeepAlive() { + keepAlive = true; + lastKeepAlive = new Date(); + keepAliveTimer = setInterval(keepAliveLoop, checkTimeoutInterval); + client.on(0x00, onKeepAlive); } function onEnd() { @@ -69,14 +77,6 @@ function createServer(options) { clearTimeout(loginKickTimer); } - function onKeepAlive(packet) { - if (keepAlive) { - lastKeepAlive = new Date(); - } else { - lastKeepAlive = null; - } - } - function onPing(packet) { if (loggedIn) return; client.write(0xff, { @@ -94,12 +94,11 @@ function createServer(options) { function onHandshake(packet) { assert.ok(! onlineMode); loggedIn = true; - keepAlive = true; client.username = packet.username; + startKeepAlive(); clearTimeout(loginKickTimer); loginKickTimer = null; - keepAliveTimer = setInterval(keepAliveLoop, checkTimeoutInterval); server.emit('login', client); } @@ -115,7 +114,7 @@ function createClient(options) { var host = options.host || 'localhost'; assert.ok(options.username, "username is required"); var haveCredentials = options.email && options.password; - var keepAlive = !!options.keepAlive; + var keepAlive = options.keepAlive == null ? true : options.keepAlive; var client = new Client({ isServer: false diff --git a/test/test.js b/test/test.js index 15259af..71ec94d 100644 --- a/test/test.js +++ b/test/test.js @@ -233,7 +233,7 @@ describe("client", function() { }); }); }); -describe("server", function() { +describe("mc-server", function() { it("starts listening and shuts down cleanly", function(done) { var server = mc.createServer({ 'online-mode': false }); var listening = false; @@ -275,6 +275,36 @@ describe("server", function() { if (count <= 0) done(); } }); + it("kicks clients that do not send keepalive packets", function(done) { + var server = mc.createServer({ + 'online-mode': false, + kickTimeout: 100, + checkTimeoutInterval: 10, + }); + var count = 2; + server.on('connection', function(client) { + client.on('end', function(reason) { + assert.strictEqual(reason, "KeepAliveTimeout"); + server.close(); + }); + }); + server.on('close', function() { + resolve(); + }); + server.on('listening', function() { + var client = mc.createClient({ + username: 'superpants', + keepAlive: false, + }); + client.on('end', function() { + resolve(); + }); + }); + function resolve() { + count -= 1; + if (count <= 0) done(); + } + }); it("responds to ping requests", function(done) { var server = mc.createServer({ 'online-mode': false,