diff --git a/src/main/java/de/bixilon/minosoft/nbt/tag/CompoundTag.java b/src/main/java/de/bixilon/minosoft/nbt/tag/CompoundTag.java index b585a3662..79f56ace5 100644 --- a/src/main/java/de/bixilon/minosoft/nbt/tag/CompoundTag.java +++ b/src/main/java/de/bixilon/minosoft/nbt/tag/CompoundTag.java @@ -30,23 +30,11 @@ public class CompoundTag implements NBTTag { } public CompoundTag(boolean subTag, InByteBuffer buffer) { - if (buffer.readByte() == 0) { - // no nbt - name = null; - data = new HashMap<>(); - return; + if (subTag) { + this.name = null; } else { - buffer.setPosition(buffer.getPosition() - 1); - } - if (!subTag) { - if (buffer.readByte() != TagTypes.COMPOUND.getId()) { // will be a Compound Tag - // decompressed but still bad.... :( - throw new IllegalArgumentException("Bad nbt"); - } // if in an array, there is no name this.name = buffer.readString(buffer.readShort()); // length - } else { - this.name = null; } this.data = new HashMap<>(); while (true) { @@ -57,44 +45,7 @@ public class CompoundTag implements NBTTag { break; } String tagName = buffer.readString(buffer.readShort()); // length - switch (tagType) { - case BYTE: - data.put(tagName, new ByteTag(buffer)); - break; - case SHORT: - data.put(tagName, new ShortTag(buffer)); - break; - case INT: - data.put(tagName, new IntTag(buffer)); - break; - case LONG: - data.put(tagName, new LongTag(buffer)); - break; - case FLOAT: - data.put(tagName, new FloatTag(buffer)); - break; - case DOUBLE: - data.put(tagName, new DoubleTag(buffer)); - break; - case BYTE_ARRAY: - data.put(tagName, new ByteArrayTag(buffer)); - break; - case STRING: - data.put(tagName, new StringTag(buffer)); - break; - case LIST: - data.put(tagName, new ListTag(buffer)); - break; - case COMPOUND: - data.put(tagName, new CompoundTag(true, buffer)); - break; - case INT_ARRAY: - data.put(tagName, new IntArrayTag(buffer)); - break; - case LONG_ARRAY: - data.put(tagName, new LongArrayTag(buffer)); - break; - } + data.put(tagName, buffer.readNBT(tagType)); } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java index 356576948..6f1a6bdd7 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java @@ -31,7 +31,7 @@ import de.bixilon.minosoft.game.datatypes.objectLoader.particle.data.ItemParticl import de.bixilon.minosoft.game.datatypes.objectLoader.particle.data.ParticleData; import de.bixilon.minosoft.game.datatypes.objectLoader.recipes.Ingredient; import de.bixilon.minosoft.game.datatypes.world.BlockPosition; -import de.bixilon.minosoft.nbt.tag.CompoundTag; +import de.bixilon.minosoft.nbt.tag.*; import de.bixilon.minosoft.util.BitByte; import de.bixilon.minosoft.util.Util; @@ -123,6 +123,15 @@ public class InByteBuffer { return new String(readBytes(length), StandardCharsets.UTF_8); } + + public String[] readStringArray(int length) { + String[] ret = new String[length]; + for (int i = 0; i < length; i++) { + ret[i] = new String(readBytes(readVarInt()), StandardCharsets.UTF_8); + } + return ret; + } + public String readString(int length) { return new String(readBytes(length)); } @@ -257,7 +266,7 @@ public class InByteBuffer { } } - public CompoundTag readNBT(boolean compressed) { + public NBTTag readNBT(boolean compressed) { if (compressed) { short length = readShort(); if (length == -1) { @@ -265,18 +274,54 @@ public class InByteBuffer { return new CompoundTag(); } try { - return new CompoundTag(new InByteBuffer(Util.decompressGzip(readBytes(length)), version)); + return new InByteBuffer(Util.decompressGzip(readBytes(length)), version).readNBT(); } catch (IOException e) { // oh no e.printStackTrace(); throw new IllegalArgumentException("Bad nbt"); } - // try again } - return new CompoundTag(this); + TagTypes type = TagTypes.getById(readByte()); + if (type == TagTypes.COMPOUND) { + // shouldn't be a subtag + return new CompoundTag(false, this); + } + return readNBT(); } - public CompoundTag readNBT() { + public NBTTag readNBT(TagTypes tagType) { + switch (tagType) { + case END: + return null; + case BYTE: + return new ByteTag(this); + case SHORT: + return new ShortTag(this); + case INT: + return new IntTag(this); + case LONG: + return new LongTag(this); + case FLOAT: + return new FloatTag(this); + case DOUBLE: + return new DoubleTag(this); + case BYTE_ARRAY: + return new ByteArrayTag(this); + case STRING: + return new StringTag(this); + case LIST: + return new ListTag(this); + case COMPOUND: + return new CompoundTag(true, this); + case INT_ARRAY: + return new IntArrayTag(this); + case LONG_ARRAY: + return new LongArrayTag(this); + } + return null; + } + + public NBTTag readNBT() { return readNBT(false); } @@ -294,11 +339,11 @@ public class InByteBuffer { } byte count = readByte(); short metaData = readShort(); - CompoundTag nbt = readNBT(version == ProtocolVersion.VERSION_1_7_10); + CompoundTag nbt = (CompoundTag) readNBT(version == ProtocolVersion.VERSION_1_7_10); return new Slot(Items.getItemByLegacy(id, metaData), count, metaData, nbt); default: if (readBoolean()) { - return new Slot(Items.getItem(readVarInt(), version), readByte(), readNBT()); + return new Slot(Items.getItem(readVarInt(), version), readByte(), (CompoundTag) readNBT()); } } return null;