From e8e78e29426bcf9422be9a70d1de5fdd07c78348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Buscht=C3=B6ns?= Date: Mon, 28 Jan 2013 00:56:59 +0100 Subject: [PATCH 01/10] Add latency measurement to lib/ping.js --- lib/ping.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/ping.js b/lib/ping.js index 8a495ef..17d6247 100644 --- a/lib/ping.js +++ b/lib/ping.js @@ -19,6 +19,7 @@ function ping(options, cb) { motd: parts[3], playerCount: parseInt(parts[4], 10), maxPlayers: parseInt(parts[5], 10), + latency: Date.now() - start }; } catch (err) { client.end(); @@ -34,5 +35,7 @@ function ping(options, cb) { client.on('connect', function() { client.write(0xfe, { magic: 1 }); }); + + var start = Date.now(); client.connect(port, host); } From b5516a81b3711d3b31fdc22ac06a374ff6ff947c Mon Sep 17 00:00:00 2001 From: Robin Lambertz Date: Sun, 27 Jan 2013 11:47:35 +0000 Subject: [PATCH 02/10] Fixes #20 for real this time... --- lib/server.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/server.js b/lib/server.js index fd40db2..62d1c40 100644 --- a/lib/server.js +++ b/lib/server.js @@ -24,6 +24,11 @@ Server.prototype.listen = function(port, host) { self.socketServer = net.createServer(); self.socketServer.on('connection', function(socket) { var client = new Client(true); + client._end = client.end; + client.end = function end(endReason) { + client.write(0xff, {reason: endReason}); + client._end(endReason); + } client.id = nextId++; self.clients[client.id] = client; client.on('error', function(err) { From 79e61a48901a653a529ee36153989e8de83863cd Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 27 Jan 2013 19:36:22 -0500 Subject: [PATCH 03/10] fix ping module to pass tests --- lib/ping.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ping.js b/lib/ping.js index 17d6247..859a368 100644 --- a/lib/ping.js +++ b/lib/ping.js @@ -8,7 +8,7 @@ function ping(options, cb) { var port = options.port || 25565; var client = new Client(); - client.on(0xff, function(packet) { + client.once(0xff, function(packet) { var parts = packet.reason.split('\u0000'); var results; try { From 3402260b7b0a1479b20f57d13f34033ef1977aa1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 27 Jan 2013 19:40:56 -0500 Subject: [PATCH 04/10] Release 0.6.6 --- README.md | 7 ++++++- package.json | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d9a1eb9..14ef4d9 100644 --- a/README.md +++ b/README.md @@ -230,11 +230,16 @@ correct data type. ## History +### 0.6.6 + + * ping: fix calling callback twice when server sends kick + * server: send a kick packet when kicking clients. (thanks roblabla) + * ping: include latency property (thanks Jan Buschtöns) + ### 0.6.5 * createServer: allow empty options * server: support online mode and encryption (thanks roblabla) - * server: send a kick packet when kicking clients. (thanks roblabla) ### 0.6.4 diff --git a/package.json b/package.json index 005b55d..73e9aca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minecraft-protocol", - "version": "0.6.5", + "version": "0.6.6", "description": "Parse and serialize minecraft packets, plus authentication and encryption.", "main": "index.js", "repository": { From eaa895120ae612ac2524926d821f20e832fd6b17 Mon Sep 17 00:00:00 2001 From: Robin Lambertz Date: Tue, 29 Jan 2013 00:44:00 +0000 Subject: [PATCH 05/10] Original skeleton changes. --- lib/client.js | 1 + lib/protocol.js | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/client.js b/lib/client.js index 3166a6c..1627d21 100644 --- a/lib/client.js +++ b/lib/client.js @@ -29,6 +29,7 @@ Client.prototype.setSocket = function(socket) { while (true) { parsed = parsePacket(incomingBuffer, self.isServer); if (! parsed) break; + if (typeof parsed.error !== "undefined") end(parsed.error); packet = parsed.results; incomingBuffer = incomingBuffer.slice(parsed.size); self.emit(packet.id, packet); diff --git a/lib/protocol.js b/lib/protocol.js index 6d3148c..3fab3a3 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -1163,7 +1163,9 @@ LongWriter.prototype.write = function(buffer, offset) { function get(packetId, toServer) { var packetInfo = packets[packetId]; - assert.ok(packetInfo, "unrecognized packet id: " + packetId); + if (!packetInfo) { + return null; + } return Array.isArray(packetInfo) ? packetInfo : toServer ? @@ -1175,6 +1177,7 @@ function createPacketBuffer(packetId, params, isServer) { var size = 1; var fields = [ new UByteWriter(packetId) ]; var packet = get(packetId, !isServer); + assert.notEqual(packet, null); packet.forEach(function(fieldInfo) { var value = params[fieldInfo.name]; var Writer = types[fieldInfo.type][1]; @@ -1198,14 +1201,28 @@ function parsePacket(buffer, isServer) { var size = 1; var results = { id: packetId }; var packetInfo = get(packetId, isServer); - assert.ok(packetInfo, "Unrecognized packetId: " + packetId); + if (packetInfo == null) { + return { + error: "Unrecognized packetId: " + packetId + } + } var i, fieldInfo, read, readResults; for (i = 0; i < packetInfo.length; ++i) { fieldInfo = packetInfo[i]; read = types[fieldInfo.type][0]; - assert.ok(read, "missing reader for data type: " + fieldInfo.type); + if (!read) { + return { + error: "missing reader for data type: " + fieldInfo.type; + } + } readResults = read(buffer, size); if (readResults) { + // if readResults.error is undef, error stays undef'd + if (typeof readResults.error !== "undefined") { + return { + error: readResults.error + } + } results[fieldInfo.name] = readResults.value; size += readResults.size; } else { From 5b67cec4e0edca65df3ce75af748c0df8d1162c7 Mon Sep 17 00:00:00 2001 From: Robin Lambertz Date: Tue, 29 Jan 2013 00:48:01 +0000 Subject: [PATCH 06/10] ups. Fixed a syntax error. --- lib/protocol.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/protocol.js b/lib/protocol.js index 3fab3a3..287fbb5 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -1212,7 +1212,7 @@ function parsePacket(buffer, isServer) { read = types[fieldInfo.type][0]; if (!read) { return { - error: "missing reader for data type: " + fieldInfo.type; + error: "missing reader for data type: " + fieldInfo.type } } readResults = read(buffer, size); From 529355782e45f01dbe4649d2d677db1783fa5bed Mon Sep 17 00:00:00 2001 From: Robin Lambertz Date: Tue, 29 Jan 2013 01:05:33 +0000 Subject: [PATCH 07/10] Added errors in case of wrong MetaData or wrong Chunk Data --- lib/protocol.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/protocol.js b/lib/protocol.js index 287fbb5..70733ac 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -727,9 +727,17 @@ function readEntityMetadata(buffer, offset) { type = item >> 5; typeName = entityMetadataTypes[type]; dataType = types[typeName]; - assert.ok(dataType, "unrecognized entity metadata type " + type); + if (!dataType) { + return { + error: "unrecognized entity metadata type " + type + } + } reader = dataType[0]; - assert.ok(reader, "missing reader for entity metadata type " + type); + if (!reader) { + return { + error: "missing reader for entity metadata type " + type + } + } results = reader(buffer, cursor); if (! results) return null; metadata.push({ @@ -808,7 +816,11 @@ function readMapChunkBulk (buffer, offset) { }); } - assert.strictEqual(chunkColumnCount, meta.length); + if (chunkColumnCount !== meta.length) { + return { + error: "ChunkColumnCount different from length of meta" + } + } return { value: { From 997071ef419dca3ce355dd8340a4aea040bf31fd Mon Sep 17 00:00:00 2001 From: Robin Lambertz Date: Tue, 29 Jan 2013 08:53:23 +0000 Subject: [PATCH 08/10] Changed if(typeof var === undefined) to if(var). Made errors error objects. --- lib/client.js | 2 +- lib/protocol.js | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/client.js b/lib/client.js index 1627d21..bbf7211 100644 --- a/lib/client.js +++ b/lib/client.js @@ -29,7 +29,7 @@ Client.prototype.setSocket = function(socket) { while (true) { parsed = parsePacket(incomingBuffer, self.isServer); if (! parsed) break; - if (typeof parsed.error !== "undefined") end(parsed.error); + if (parsed.error) this.end(parsed.error); packet = parsed.results; incomingBuffer = incomingBuffer.slice(parsed.size); self.emit(packet.id, packet); diff --git a/lib/protocol.js b/lib/protocol.js index 70733ac..58fd690 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -729,13 +729,13 @@ function readEntityMetadata(buffer, offset) { dataType = types[typeName]; if (!dataType) { return { - error: "unrecognized entity metadata type " + type + error: new Error("unrecognized entity metadata type " + type) } } reader = dataType[0]; if (!reader) { return { - error: "missing reader for entity metadata type " + type + error: new Error("missing reader for entity metadata type " + type) } } results = reader(buffer, cursor); @@ -818,7 +818,7 @@ function readMapChunkBulk (buffer, offset) { if (chunkColumnCount !== meta.length) { return { - error: "ChunkColumnCount different from length of meta" + error: new Error("ChunkColumnCount different from length of meta") } } @@ -1215,7 +1215,7 @@ function parsePacket(buffer, isServer) { var packetInfo = get(packetId, isServer); if (packetInfo == null) { return { - error: "Unrecognized packetId: " + packetId + error: new Error("Unrecognized packetId: " + packetId) } } var i, fieldInfo, read, readResults; @@ -1224,15 +1224,15 @@ function parsePacket(buffer, isServer) { read = types[fieldInfo.type][0]; if (!read) { return { - error: "missing reader for data type: " + fieldInfo.type + error: new Error("missing reader for data type: " + fieldInfo.type) } } readResults = read(buffer, size); if (readResults) { // if readResults.error is undef, error stays undef'd - if (typeof readResults.error !== "undefined") { + if (readResults.error) { return { - error: readResults.error + error: new Error("reader failed : " + readResults.error) } } results[fieldInfo.name] = readResults.value; From d6b3a9175160104ba3a42635df744d4dc2cb5b48 Mon Sep 17 00:00:00 2001 From: Robin Lambertz Date: Tue, 29 Jan 2013 11:05:10 +0000 Subject: [PATCH 09/10] client.end should have a string argument, not an Error object. --- lib/client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client.js b/lib/client.js index bbf7211..26c3396 100644 --- a/lib/client.js +++ b/lib/client.js @@ -29,7 +29,7 @@ Client.prototype.setSocket = function(socket) { while (true) { parsed = parsePacket(incomingBuffer, self.isServer); if (! parsed) break; - if (parsed.error) this.end(parsed.error); + if (parsed.error) this.end(parsed.error.message); packet = parsed.results; incomingBuffer = incomingBuffer.slice(parsed.size); self.emit(packet.id, packet); From fdc01db82504cd81b7467988e37e6f22b544ed50 Mon Sep 17 00:00:00 2001 From: Robin Lambertz Date: Tue, 29 Jan 2013 17:39:33 +0000 Subject: [PATCH 10/10] Pass the original error around, and emit an error event on the client --- lib/client.js | 6 +++++- lib/protocol.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/client.js b/lib/client.js index 26c3396..afa8ed0 100644 --- a/lib/client.js +++ b/lib/client.js @@ -29,7 +29,11 @@ Client.prototype.setSocket = function(socket) { while (true) { parsed = parsePacket(incomingBuffer, self.isServer); if (! parsed) break; - if (parsed.error) this.end(parsed.error.message); + if (parsed.error) { + this.emit('error', parsed.error); + this.end("ProtocolError"); + return; + } packet = parsed.results; incomingBuffer = incomingBuffer.slice(parsed.size); self.emit(packet.id, packet); diff --git a/lib/protocol.js b/lib/protocol.js index 58fd690..2c5598c 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -1232,7 +1232,7 @@ function parsePacket(buffer, isServer) { // if readResults.error is undef, error stays undef'd if (readResults.error) { return { - error: new Error("reader failed : " + readResults.error) + error: readResults.error } } results[fieldInfo.name] = readResults.value;