Pmmp NBT Versions Save

PHP library for working with the NBT (Named Binary Tag) data storage format, as designed by Mojang.

1.0.0

9 months ago

Changes since 0.3.4

  • Added BaseNbtSerializer->readHeadless() and BaseNbtSerializer->writeHeadless(). These are needed for one specific place in the Bedrock protocol and are otherwise not usually seen.

Despite the version bump to 1.0.0, this isn't a huge release. Staying on 0.x for so long was a mistake that needed to be corrected.

0.3.4

1 year ago

Changes since 0.3.3

  • Fixed crashes when encountering TAG_ByteArray or TAG_IntArray with length larger than int32 max. NbtDataException is now thrown in these cases.

0.3.3

1 year ago

Changes since 0.3.2

  • JsonNbtParser no longer throws InvalidArgumentException when attempting to create tags with out-of-bounds values (e.g. TAG_Byte with value larger than a byte) - NbtDataException is now thrown instead.
  • JsonNbtParser no longer throws TypeError when attempting to create TAG_List with mixed value types - NbtDataException is now thrown instead.

0.3.2

2 years ago

Changes since 0.3.1

  • TAG_Compounds containing repeated keys in binary data is no longer treated as a corruption case. While it technically is corruption, it's problematic to throw on it due to inability to recover the data using this library.

0.2.19

2 years ago

Changes since 0.2.18

  • TAG_Compounds containing repeated keys in binary data is no longer treated as a corruption case. While it technically is corruption, it's problematic due to inability to recover the data using this library.

0.3.1

2 years ago

Changes since 0.3.0

  • Fixed UnexpectedValueException being thrown instead of NbtDataException when encountering a non-empty list of TAG_End.

0.3.0

2 years ago

This is a major release featuring significant API changes. It is not API-compatible with 0.2.x.

Changes since 0.2.x

  • Error handling during decoding has been improved. Now, broken NBT will cause an NbtDataException to be thrown, instead of a generic \UnexpectedValueException.
  • NBT serializers now use BinaryStream provided by pocketmine/binaryutils to decode data, instead of an in-house implementation.
  • The library no longer depends on ext-zlib. Instead, decompressing of compressed NBT is left to the user, which allows more freedom of usage of the library, as well as enabling the usage of faster compressors such as ext-libdeflate.
  • The output format when using __toString() on tags has been revamped for improved readability.
    • The short names of tags are rendered in the output, instead of the full class name.
    • ByteArrayTags are now printed as base64 to prevent console breakage.

API changes

  • The following classes have been renamed:
    • NBTStream has been renamed to BaseNbtSerializer.
    • LittleEndianNBTStream has been renamed to LittleEndianNbtSerializer.
    • BigEndianNBTStream has been renamed to BigEndianNbtSerializer.
    • NamedTag has been renamed to Tag (although all of the functionality that made it Named has been removed - see below).
  • NetworkLittleEndianNBTStream has been removed. Since the format of this type of NBT is dependent on the current Minecraft protocol, and not standard, it's too volatile for inclusion in this library.
    • For users of PocketMine-MP, NetworkNbtSerializer serves as the replacement.
  • BaseNbtSerializer (previously NBTStream) has the following changes:
    • write() now accepts a TreeRoot instead of a NamedTag. Since tags don't contain names anymore, this allows the root tag to be named if desired.
    • write() no longer accepts an array of tags.
    • writeMultiple() has been added.
    • read() now returns a TreeRoot instead of a NamedTag.
    • read() no longer accepts a $doMultiple parameter.
    • readMultiple() method has been added.
    • read() and readMultiple() now throw NbtDataException on data errors, instead of \UnexpectedValueException.
    • toArray() and fromArray() were removed. This functionality had no clear purpose and was heavily broken for several years.
    • readCompressed() and writeCompressed() were removed. The user is now responsible for decompressing before decoding, and compressing after encoding (if necessary).
  • JsonNbtParser has the following changes:
    • parseJson() now always returns CompoundTag. If an error occurs during deserialization, an exception will be thrown.
    • parseJson() now throws NbtDataException instead of \UnexpectedValueException on bad data.
  • Tags no longer contain names. Since names are keys for TAG_Compound, it didn't make sense for the tags themselves to contain them.
    • All Tag constructors have had the $name argument removed. They now only accept values.
    • For the root tag, which may have a name even though it's not inside a TAG_Compound, a TreeRoot class has been added.
    • The methods getName() and setName() have been removed.
    • Tags with the same values will now compare as equal, regardless of their positions in lists or keys in compounds.
  • Tag->read() has been made static. This allows simple tag types to be immutable, which significantly improves performance during cloning.
  • All Tag implementations are now final.
  • ListTag has the following changes:
    • No longer supports ArrayAccess interfaces. Since ListTag is strictly expected to behave like a list, it was too ambiguous what array access was supposed to do.
    • Now implements IteratorAggregate instead of Iterator. This allows by-value modification of the ListTag while iterating over it, similar to how an array works.
  • CompoundTag has the following changes:
    • ArrayAccess is no longer supported. Its magical behaviour was impossible to statically analyse, and it was unclear what its behaviour was in some circumstances.
    • IteratorAggregate is now implemented instead of Iterator. This allows by-value modification during iteration without breaking iteration, similar to how array copy-on-write works.
    • getTagValue() is no longer exposed to the public API.
    • hasTag() has been removed. It can be replaced by a statement like if(($tag = $compound->getTag("name")) instanceof SomeTag) instead, which is faster and more static-analysis-friendly.
    • getTag() no longer accepts an $expectedTagType parameter (see previous point).
    • setTag() now requires a $name argument before the $tag.
    • The helper methods setByte(), setShort(), setInt() etc. now all require a $name argument in addition to the $value argument.
    • The helper methods setByte(), setShort(), setInt() etc. have had the $force argument removed.
    • The helper methods setByte(), setShort(), setInt() etc. are now fluent.
    • The helper methods getByte(), getShort(), getInt() etc. have had the $badTagDefault argument removed.
    • The helper methods getByte(), getShort(), getInt() etc. may now throw UnexpectedTagTypeException or NoSuchTagException when encountering incompatible data, instead of \UnexpectedValueException.
    • setTag() no longer throws an exception when overwriting a tag of a different type. Since NBT should usually be built from scratch on save anyway, this check didn't make much sense.

0.2.18

3 years ago

Changes since 0.2.17

  • Dropped support for pmmp/PreProcessor. Preprocessing NBT code will now have no effect. (Since the optimisations in use were heavily out of date anyway, they did not have much use anyway.)

0.2.17

3 years ago

Changes since 0.2.16

  • Fixed FloatTag incorrectly comparing as not-equal after encode/decode with values such as 0.3 (stored with higher precision in memory (64-bit) than possible to represent (32-bit)).

0.2.16

3 years ago

Changes since 0.2.15

  • Now tested on PHP 8.0.