mirror of
https://github.com/PrismarineJS/node-minecraft-protocol.git
synced 2024-12-02 03:56:54 -05:00
Start on parsing compressed packets
This commit is contained in:
parent
d657371b6b
commit
426a01249c
2 changed files with 91 additions and 1 deletions
|
@ -8,6 +8,7 @@ var net = require('net')
|
||||||
, oldStylePacket = protocol.oldStylePacket
|
, oldStylePacket = protocol.oldStylePacket
|
||||||
, newStylePacket = protocol.newStylePacket
|
, newStylePacket = protocol.newStylePacket
|
||||||
, parsePacket = protocol.parsePacket
|
, parsePacket = protocol.parsePacket
|
||||||
|
, parseNewStylePacket = protocol.parseNewStylePacket
|
||||||
, packetIds = protocol.packetIds
|
, packetIds = protocol.packetIds
|
||||||
, packetNames = protocol.packetNames
|
, packetNames = protocol.packetNames
|
||||||
, states = protocol.states
|
, states = protocol.states
|
||||||
|
@ -89,7 +90,10 @@ Client.prototype.setSocket = function(socket) {
|
||||||
incomingBuffer = Buffer.concat([incomingBuffer, data]);
|
incomingBuffer = Buffer.concat([incomingBuffer, data]);
|
||||||
var parsed, packet;
|
var parsed, packet;
|
||||||
while (true) {
|
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) break;
|
||||||
if (parsed.error) {
|
if (parsed.error) {
|
||||||
this.emit('error', parsed.error);
|
this.emit('error', parsed.error);
|
||||||
|
|
|
@ -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 = {
|
module.exports = {
|
||||||
version: 47,
|
version: 47,
|
||||||
minecraftVersion: '1.8.1',
|
minecraftVersion: '1.8.1',
|
||||||
sessionVersion: 13,
|
sessionVersion: 13,
|
||||||
parsePacket: parsePacket,
|
parsePacket: parsePacket,
|
||||||
|
parseNewStylePacket: parseNewStylePacket,
|
||||||
createPacketBuffer: createPacketBuffer,
|
createPacketBuffer: createPacketBuffer,
|
||||||
compressPacketBuffer: compressPacketBuffer,
|
compressPacketBuffer: compressPacketBuffer,
|
||||||
oldStylePacket: oldStylePacket,
|
oldStylePacket: oldStylePacket,
|
||||||
|
|
Loading…
Reference in a new issue