From 426a01249cf4c0c889476fd23aa4c3f9998e2e4e Mon Sep 17 00:00:00 2001 From: Will Franzen Date: Fri, 2 Jan 2015 11:50:54 -0600 Subject: [PATCH] Start on parsing compressed packets --- lib/client.js | 6 +++- lib/protocol.js | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/lib/client.js b/lib/client.js index da25223..562abf3 100644 --- a/lib/client.js +++ b/lib/client.js @@ -8,6 +8,7 @@ var net = require('net') , oldStylePacket = protocol.oldStylePacket , newStylePacket = protocol.newStylePacket , parsePacket = protocol.parsePacket + , parseNewStylePacket = protocol.parseNewStylePacket , packetIds = protocol.packetIds , packetNames = protocol.packetNames , states = protocol.states @@ -89,7 +90,10 @@ Client.prototype.setSocket = function(socket) { incomingBuffer = Buffer.concat([incomingBuffer, data]); var parsed, packet; while (true) { - parsed = parsePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse); + if(this.compressionThreshold == -2) + parsed = parsePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse); + else + parsed = parseNewStylePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse, function(){}); if (! parsed) break; if (parsed.error) { this.emit('error', parsed.error); diff --git a/lib/protocol.js b/lib/protocol.js index 62f64b1..7500434 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -1537,11 +1537,97 @@ function parsePacket(buffer, state, isServer, packetsToParse) { }; } +function parseNewStylePacket(buffer, state, isServer, packetsToParse, cb) { + if (state == null) state = states.PLAY; + var cursor = 0; + var lengthField = readVarInt(buffer, 0); + if (!!!lengthField) return null; + var length = lengthField.value; + cursor += lengthField.size; + if (length + lengthField.size > buffer.length) return null; + var buffer = buffer.slice(0, length + cursor); // fail early if too much is read. + + var dataLengthField = readVarInt(buffer, cursor); + + var finishParsing = function(buffer) { + var packetIdField = readVarInt(buffer, cursor); + var packetId = packetIdField.value; + cursor += packetIdField.size; + + var results = { id: packetId }; + // Only parse the packet if there is a need for it, AKA if there is a listener attached to it + var name = packetNames[state][isServer ? "toServer" : "toClient"][packetId]; + var shouldParse = (!packetsToParse.hasOwnProperty(name) || packetsToParse[name] <= 0) + && (!packetsToParse.hasOwnProperty("packet") || packetsToParse["packet"] <= 0); + if (shouldParse) { + return { + size: length + lengthField.size, + buffer: buffer, + results: results + }; + } + + var packetInfo = get(packetId, state, isServer); + if (packetInfo === null) { + return { + error: new Error("Unrecognized packetId: " + packetId + " (0x" + packetId.toString(16) + ")"), + size: length + lengthField.size, + buffer: buffer, + results: results + }; + } else { + var packetName = packetNames[state][isServer ? "toServer" : "toClient"][packetId]; + debug("read packetId " + state + "." + packetName + " (0x" + packetId.toString(16) + ")"); + } + + var i, fieldInfo, readResults; + for (i = 0; i < packetInfo.length; ++i) { + fieldInfo = packetInfo[i]; + readResults = read(buffer, cursor, fieldInfo, results); + /* A deserializer cannot return null anymore. Besides, read() returns + * null when the condition is not fulfilled. + if (!!!readResults) { + var error = new Error("A deserializer returned null"); + error.packetId = packetId; + error.fieldInfo = fieldInfo.name; + return { + size: length + lengthField.size, + error: error, + results: results + }; + }*/ + if (readResults === null) continue; + if (readResults.error) { + return readResults; + } + results[fieldInfo.name] = readResults.value; + cursor += readResults.size; + } + debug(results); + cb({ + size: length + lengthField.size, + results: results, + buffer: buffer + }); + }; + + if(dataLengthField != 0) { + zlib.inflateRaw(buffer.slice(cursor, cursor + dataLengthField.value), function(err, buffer) { + cursor = 0; + finishParsing(buffer); + }); + } else { + finishParsing(buffer); + } + +} + module.exports = { version: 47, minecraftVersion: '1.8.1', sessionVersion: 13, parsePacket: parsePacket, + parseNewStylePacket: parseNewStylePacket, createPacketBuffer: createPacketBuffer, compressPacketBuffer: compressPacketBuffer, oldStylePacket: oldStylePacket,