diff --git a/lib/client.js b/lib/client.js index 15805fb..7e276ef 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 + , parsePacketData = protocol.parsePacketData , parseNewStylePacket = protocol.parseNewStylePacket , packetIds = protocol.packetIds , packetNames = protocol.packetNames @@ -89,7 +90,7 @@ Client.prototype.setSocket = function(socket) { } if (! parsed) { return; } var packet = parsed.results; - incomingBuffer = incomingBuffer.slice(parsed.size); + //incomingBuffer = incomingBuffer.slice(parsed.size); TODO: Already removed in prepare var packetName = protocol.packetNames[self.state][self.isServer ? 'toServer' : 'toClient'][packet.id]; self.emit(packetName, packet); @@ -100,10 +101,19 @@ Client.prototype.setSocket = function(socket) { } function prepareParse() { - if(self.compressionThreshold == -2) - afterParse(null, parsePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse)); - else - parseNewStylePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse, afterParse); + var packetLengthField = protocol.types["varint"][0](incomingBuffer, 0); + if (packetLengthField && packetLengthField.size + packetLengthField.value <= incomingBuffer.length) + { + var buf = incomingBuffer.slice(packetLengthField.size, packetLengthField.size + packetLengthField.value); + // TODO : Slice as early as possible to avoid processing same data twice. + incomingBuffer = incomingBuffer.slice(packetLengthField.size + packetLengthField.value); + if (self.compressionThreshold == -2) + { + afterParse(null, parsePacketData(buf, self.state, self.isServer, self.packetsToParse)); + } else { + parseNewStylePacket(buf, self.state, self.isServer, self.packetsToParse, afterParse); + } + } } self.socket = socket; @@ -171,7 +181,12 @@ Client.prototype.write = function(packetId, params) { packetId = packetIds[this.state][this.isServer ? "toClient" : "toServer"][packetId]; var that = this; - var finishWriting = function(buffer) { + var finishWriting = function(err, buffer) { + if (err) + { + console.log(err); + throw err; // TODO : Handle errors gracefully, if possible + } var packetName = packetNames[that.state][that.isServer ? "toClient" : "toServer"][packetId]; debug("writing packetId " + that.state + "." + packetName + " (0x" + packetId.toString(16) + ")"); debug(params); @@ -186,10 +201,10 @@ Client.prototype.write = function(packetId, params) { compressPacketBuffer(buffer, finishWriting); } else if (this.compressionThreshold >= -1) { debug("New-styling packet"); - finishWriting(newStylePacket(buffer)); + newStylePacket(buffer, finishWriting); } else { debug("Old-styling packet"); - finishWriting(oldStylePacket(buffer)); + oldStylePacket(buffer, finishWriting); } }; diff --git a/lib/protocol.js b/lib/protocol.js index 46d0eed..05c6f1f 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -1434,32 +1434,30 @@ function createPacketBuffer(packetId, state, params, isServer) { function compressPacketBuffer(buffer, callback) { var dataLength = buffer.size; - zlib.deflate(buffer, function(compressedBuffer) { - var packetLength = sizeOfVarInt(dataLength) + compressedBuffer.length; - var size = sizeOfVarInt(packetLength) + packetLength; - var packetBuffer = new Buffer(size); - var offset = writeVarInt(packetLength, packetBuffer, 0); - offset = writeVarInt(dataLength, packetBuffer, offset); - writeBuffer(compressedBuffer, packetBuffer, offset); - callback(packetBuffer); + zlib.deflate(buffer, function(err, buf) { + if (err) + callback(err); + else + newStylePacket(buffer, callback); }); } -function oldStylePacket(buffer) { +function oldStylePacket(buffer, callback) { var packet = new Buffer(sizeOfVarInt(buffer.length) + buffer.length); var cursor = writeVarInt(buffer.length, packet, 0); writeBuffer(buffer, packet, cursor); - return packet; + callback(null, packet); } -function newStylePacket(buffer) { - var sizeOfO = sizeOfVarInt(0); - var size = sizeOfVarInt(buffer.length + sizeOfO) + sizeOfO + buffer.length; +function newStylePacket(buffer, callback) { + var sizeOfDataLength = sizeOfVarInt(0); + var sizeOfLength = sizeOfVarInt(buffer.length + sizeOfDataLength); + var size = sizeOfLength + sizeOfDataLength + buffer.length; var packet = new Buffer(size); - var cursor = writeVarInt(buffer.length, packet, 0); + var cursor = writeVarInt(size - sizeOfLength, packet, 0); cursor = writeVarInt(0, packet, cursor); writeBuffer(buffer, packet, cursor); - return packet; + callback(null, packet); } function parsePacketData(buffer, state, isServer, packetsToParse) { @@ -1536,29 +1534,19 @@ 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 >= buffer.length - cursor) { return null }; - var dataLengthField = readVarInt(buffer, cursor); - cursor += dataLengthField.size; + var dataLengthField = readVarInt(buffer, 0); + var buf = buffer.slice(dataLengthField.size); if(dataLengthField.value != 0) { - var bufToDecompress = buffer.slice(cursor); - zlib.inflate(bufToDecompress, function(err, newbuf) { + zlib.inflate(buf, function(err, newbuf) { if (err) { console.log(err); cb(err); } else { - var result = parsePacketData(newbuf, state, isServer, packetsToParse); - result.size = lengthField.size + length; cb(null, parsePacketData(newbuf, state, isServer, packetsToParse)); } }); } else { - cb(null, parsePacketData(buffer.slice(cursor, cursor + length), state, isServer, packetsToParse)); + cb(null, parsePacketData(buf, state, isServer, packetsToParse)); } } @@ -1567,6 +1555,7 @@ module.exports = { minecraftVersion: '1.8.1', sessionVersion: 13, parsePacket: parsePacket, + parsePacketData: parsePacketData, parseNewStylePacket: parseNewStylePacket, createPacketBuffer: createPacketBuffer, compressPacketBuffer: compressPacketBuffer, @@ -1577,6 +1566,7 @@ module.exports = { packetNames: packetNames, packetFields: packetFields, packetStates: packetStates, + types: types, states: states, get: get, debug: debug,