diff --git a/index.js b/index.js index e8cc4a5..28a8eb8 100644 --- a/index.js +++ b/index.js @@ -286,15 +286,17 @@ function createClient(options) { } function onEncryptionKeyRequest(packet) { + debug("Generating 16 random bytes"); crypto.randomBytes(16, gotSharedSecret); function gotSharedSecret(err, sharedSecret) { if (err) { + debug(err); client.emit('error', err); client.end(); - return + return; } - + debug("Got mah bytes"); if (haveCredentials) { joinServerRequest(onJoinServerResponse); } else { diff --git a/lib/client.js b/lib/client.js index 562abf3..3beea37 100644 --- a/lib/client.js +++ b/lib/client.js @@ -81,6 +81,22 @@ Client.prototype.onRaw = function(type, func) { Client.prototype.setSocket = function(socket) { var self = this; + function afterParse(err, parsed) { + if (err || (parsed && parsed.error)) { + this.emit('error', err || parser.error); + this.end("ProtocolError"); + return; + } + if (! parsed) return; + packet = parsed.results; + incomingBuffer = incomingBuffer.slice(parsed.size); + + var packetName = protocol.packetNames[self.state][self.isServer ? 'toServer' : 'toClient'][packet.id]; + self.emit(packetName, packet); + self.emit('packet', packet); + self.emit('raw.' + packetName, parsed.buffer); + self.emit('raw', parsed.buffer); + } self.socket = socket; if (self.socket.setNoDelay) self.socket.setNoDelay(true); @@ -90,24 +106,10 @@ Client.prototype.setSocket = function(socket) { incomingBuffer = Buffer.concat([incomingBuffer, data]); var parsed, packet; while (true) { - if(this.compressionThreshold == -2) - parsed = parsePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse); + if(self.compressionThreshold == -2) + afterParse(null, 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); - this.end("ProtocolError"); - return; - } - packet = parsed.results; - incomingBuffer = incomingBuffer.slice(parsed.size); - - var packetName = protocol.packetNames[self.state][self.isServer ? 'toServer' : 'toClient'][packet.id]; - self.emit(packetName, packet); - self.emit('packet', packet); - self.emit('raw.' + packetName, parsed.buffer); - self.emit('raw', parsed.buffer); + parseNewStylePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse, afterParse); } }); @@ -170,7 +172,6 @@ Client.prototype.write = function(packetId, params) { var packetName = packetNames[that.state][that.isServer ? "toClient" : "toServer"][packetId]; debug("writing packetId " + that.state + "." + packetName + " (0x" + packetId.toString(16) + ")"); debug(params); - debug(buffer); var out = that.encryptionEnabled ? new Buffer(that.cipher.update(buffer), 'binary') : buffer; that.socket.write(out); return true; diff --git a/lib/protocol.js b/lib/protocol.js index 7500434..4bfeca9 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -1538,18 +1538,8 @@ 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) { + function finishParsing(buffer) { var packetIdField = readVarInt(buffer, cursor); var packetId = packetIdField.value; cursor += packetIdField.size; @@ -1557,24 +1547,24 @@ function parseNewStylePacket(buffer, state, isServer, packetsToParse, cb) { 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); + var shouldParse = (!packetsToParse.hasOwnProperty(name) || packetsToParse[name] <= 0) && + (!packetsToParse.hasOwnProperty("packet") || packetsToParse["packet"] <= 0); if (shouldParse) { - return { + cb(null, { size: length + lengthField.size, buffer: buffer, results: results - }; + }); } var packetInfo = get(packetId, state, isServer); if (packetInfo === null) { - return { + cb(null, { 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) + ")"); @@ -1598,22 +1588,40 @@ function parseNewStylePacket(buffer, state, isServer, packetsToParse, cb) { }*/ if (readResults === null) continue; if (readResults.error) { - return readResults; + cb(null, readResults); } results[fieldInfo.name] = readResults.value; cursor += readResults.size; } debug(results); - cb({ + cb(null, { size: length + lengthField.size, results: results, buffer: buffer }); }; - if(dataLengthField != 0) { + if (state == null) state = states.PLAY; + var cursor = 0; + var lengthField = readVarInt(buffer, 0); + if (!!!lengthField) return null; + var length = lengthField.value; + //console.log("Started reading compressed packet"); + cursor += lengthField.size; + if (length + lengthField.size > buffer.length) { console.log("Stopped reading"); return null }; + var buffer = buffer.slice(0, length + cursor); // fail early if too much is read. + + var dataLengthField = readVarInt(buffer, cursor); + cursor += dataLengthField.size; + if(dataLengthField.value != 0) { + /*console.log("Cursor : " + cursor); + console.log("DataLength : " + dataLengthField.value); + console.log(buffer.slice(cursor, cursor + dataLengthField.value).toString('hex')); + console.log("Buffer : " + buffer.toString('hex'));*/ + debug("Cursor : " + cursor); zlib.inflateRaw(buffer.slice(cursor, cursor + dataLengthField.value), function(err, buffer) { - cursor = 0; + if (err) console.log(err); + else console.log("Got a packet v2"); finishParsing(buffer); }); } else {