From 1a22263c03142869d6923ed13b6233c2bd30e77c Mon Sep 17 00:00:00 2001 From: deathcap Date: Sun, 14 Feb 2016 22:21:29 -0800 Subject: [PATCH 1/3] Add optionalLengthPrefixedNbt data type, used in MC 1.7 --- src/datatypes/minecraft.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/datatypes/minecraft.js b/src/datatypes/minecraft.js index 6add0d2..6c2236e 100644 --- a/src/datatypes/minecraft.js +++ b/src/datatypes/minecraft.js @@ -5,6 +5,7 @@ module.exports = { 'UUID': [readUUID, writeUUID, 16], 'nbt': [readNbt, writeNbt, sizeOfNbt], 'optionalNbt':[readOptionalNbt,writeOptionalNbt,sizeOfOptionalNbt], + 'optionalLengthPrefixedNbt':[readOptionalLengthPrefixedNbt,writeOptionalLengthPrefixedNbt,sizeOfOptionalLengthPrefixedNbt], 'restBuffer': [readRestBuffer, writeRestBuffer, sizeOfRestBuffer], 'entityMetadataLoop': [readEntityMetadata, writeEntityMetadata, sizeOfEntityMetadata] }; @@ -54,6 +55,29 @@ function sizeOfOptionalNbt(value) { return nbt.proto.sizeOf(value,"nbt"); } +// Length-prefixed optional NBT, short instead of null byte: http://wiki.vg/index.php?title=Slot_Data&diff=6056&oldid=4753 +function readOptionalLengthPrefixedNbt(buffer, offset) { + if(buffer.readInt16BE(offset) == -1) return {size:2}; + return nbt.proto.read(buffer,offset,"nbt"); +} + +function writeOptionalLengthPrefixedNbt(value, buffer, offset) { + if(value==undefined) { + buffer.writeInt16BE(-1,offset); + return offset+2; + } + buffer.writeInt16(sizeOfNbt(value),offset); + return nbt.proto.write(value,buffer,offset+2,"nbt"); +} + +function sizeOfOptionalLengthPrefixedNbt(value) { + if(value==undefined) + return 2; + return 2+nbt.proto.sizeOf(value,"nbt"); +} + + + function readRestBuffer(buffer, offset) { return { value: buffer.slice(offset), From a92929417727e68e962923edc1d17916d69c42f7 Mon Sep 17 00:00:00 2001 From: deathcap Date: Sun, 14 Feb 2016 22:54:33 -0800 Subject: [PATCH 2/3] Fix offset of NBT payload after 2-byte length --- src/datatypes/minecraft.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datatypes/minecraft.js b/src/datatypes/minecraft.js index 6c2236e..d7625c1 100644 --- a/src/datatypes/minecraft.js +++ b/src/datatypes/minecraft.js @@ -58,7 +58,7 @@ function sizeOfOptionalNbt(value) { // Length-prefixed optional NBT, short instead of null byte: http://wiki.vg/index.php?title=Slot_Data&diff=6056&oldid=4753 function readOptionalLengthPrefixedNbt(buffer, offset) { if(buffer.readInt16BE(offset) == -1) return {size:2}; - return nbt.proto.read(buffer,offset,"nbt"); + return nbt.proto.read(buffer,offset+2,"nbt"); } function writeOptionalLengthPrefixedNbt(value, buffer, offset) { From b25ac14a138657ca139dbdc61359ab0e9827a165 Mon Sep 17 00:00:00 2001 From: deathcap Date: Sun, 14 Feb 2016 23:16:35 -0800 Subject: [PATCH 3/3] Change to compressedNbt, and add zlib gunzip decompression --- src/datatypes/minecraft.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/datatypes/minecraft.js b/src/datatypes/minecraft.js index d7625c1..a366468 100644 --- a/src/datatypes/minecraft.js +++ b/src/datatypes/minecraft.js @@ -1,11 +1,12 @@ const nbt = require('prismarine-nbt'); const UUID = require('uuid-1345'); +const zlib = require('zlib'); module.exports = { 'UUID': [readUUID, writeUUID, 16], 'nbt': [readNbt, writeNbt, sizeOfNbt], 'optionalNbt':[readOptionalNbt,writeOptionalNbt,sizeOfOptionalNbt], - 'optionalLengthPrefixedNbt':[readOptionalLengthPrefixedNbt,writeOptionalLengthPrefixedNbt,sizeOfOptionalLengthPrefixedNbt], + 'compressedNbt':[readCompressedNbt,writeCompressedNbt,sizeOfCompressedNbt], 'restBuffer': [readRestBuffer, writeRestBuffer, sizeOfRestBuffer], 'entityMetadataLoop': [readEntityMetadata, writeEntityMetadata, sizeOfEntityMetadata] }; @@ -55,13 +56,19 @@ function sizeOfOptionalNbt(value) { return nbt.proto.sizeOf(value,"nbt"); } -// Length-prefixed optional NBT, short instead of null byte: http://wiki.vg/index.php?title=Slot_Data&diff=6056&oldid=4753 -function readOptionalLengthPrefixedNbt(buffer, offset) { - if(buffer.readInt16BE(offset) == -1) return {size:2}; - return nbt.proto.read(buffer,offset+2,"nbt"); +// Length-prefixed compressed NBT, see differences: http://wiki.vg/index.php?title=Slot_Data&diff=6056&oldid=4753 +function readCompressedNbt(buffer, offset) { + const length = buffer.readInt16BE(offset); + if(length == -1) return {size:2}; + + const compressedNbt = buffer.slice(offset+2, offset+2+length); + + const nbtBuffer = zlib.gunzipSync(compressedNbt); // TODO: async + + return nbt.proto.read(nbtBuffer,0,"nbt"); } -function writeOptionalLengthPrefixedNbt(value, buffer, offset) { +function writeCompressedNbt(value, buffer, offset) { if(value==undefined) { buffer.writeInt16BE(-1,offset); return offset+2; @@ -70,7 +77,7 @@ function writeOptionalLengthPrefixedNbt(value, buffer, offset) { return nbt.proto.write(value,buffer,offset+2,"nbt"); } -function sizeOfOptionalLengthPrefixedNbt(value) { +function sizeOfCompressedNbt(value) { if(value==undefined) return 2; return 2+nbt.proto.sizeOf(value,"nbt");