Repository navigation
Releases: m-stilling/snbt-parser-php
Release list
v1.2.0
Behavior changes
- Numbers outside the range of their type now throw
SNBTParseException, for example300b,1.5band1e400. - Tag constructors and
intsToUuid()now throwSNBTInvalidArgumentExceptionfor values outside the range, and forINFandNaN. - Unquoted values such as
0x1F,0b101and1_000are now numbers, not strings. CompoundTag::getIterator()returns\Iterator, not\ArrayIterator. All keys are strings.- Classes that extend
Tagmust add thebool $escapeControlCharactersparameter torender(). They must also add it toquote(),serializeKey()andtoSnbt()if they override them.
Added
- Typed getters on
CompoundTagandListTag:getString(),getInt(),getFloat(),getBool(),getCompound(),getList()andgetAs(). SNBTParser::parseCompound()returns aCompoundTag.Tag::fromPhp()makes tags from PHP values.with(),without()andwithAppended()return a changed copy of a compound or a list.SNBTParseExceptionhasposition,lineNumberandcolumnNumber.- The parser reads the Minecraft 1.21.5 syntax: hexadecimal and binary numbers,
_in numbers, the new string escapes, trailing commas, andbool()anduuid(). toSnbt(escapeControlCharacters: true)writes control characters as escapes.MINandMAXconstants on the integer tags, andNumberArrayTag::elementType().
Fixed
toSnbt()output with a line feed, a carriage return or a tab now parses on Minecraft 1.21.4 and earlier.- Every exception that the package throws implements
SNBTException. - Iterating a
CompoundTaggives string keys, also for numeric keys.
Package
- The package archive does not contain
composer.lock. composer.jsonsuggestsext-intl.
Full Changelog: v1.1.0...v1.2.0
v1.1.0
This release adds three helpers that convert between UUID strings and the four-integer arrays Minecraft stores them as. It completes the round trip that intsToUuid() started. No existing behavior changes.
Added
SNBTParser::uuidToInts(string $uuid): arrayreturns the four signed 32-bit integers for a UUID. It accepts the hyphenated form or 32 bare hex digits, in either case, and throwsInvalidArgumentExceptionfor any other input.SNBTParser::uuidToSnbt(string $uuid, SNBTFormat $format = SNBTFormat::Compact): stringreturns the same integers as a ready-made SNBT int array, for example[I;110787060,1156138790,-1514210135,238594805]. The format argument works the same as ontoSnbt().IntArrayTag::toUuid(): stringreads a parsed int array as a UUID string. It throwsInvalidArgumentExceptionunless the array holds exactly four integers.
Example
use Stilling\SNBTParser\SNBTParser;
SNBTParser::uuidToInts("069a79f4-44e9-4726-a5be-fca90e38aaf5");
// [110787060, 1156138790, -1514210135, 238594805]
SNBTParser::uuidToSnbt("069a79f4-44e9-4726-a5be-fca90e38aaf5");
// "[I;110787060,1156138790,-1514210135,238594805]"
SNBTParser::parseTyped('{UUID: [I; 110787060, 1156138790, -1514210135, 238594805]}')->get("UUID")->toUuid();
// "069a79f4-44e9-4726-a5be-fca90e38aaf5"Full Changelog: v1.0.0...v1.1.0
v1.0.0
This release replaces the JSON round-trip with a direct parser. parse() keeps its return values. A new parseTyped() returns a tag tree that keeps the NBT types and can serialize back to SNBT.
What's Changed
- Direct SNBT parser with a typed tag tree by @m-stilling in #1
Added
SNBTParser::parseTyped(string $input): Tagparses SNBT into a typed tag tree. Every value is aTagsubclass underStilling\SNBTParser\Tag:ByteTag,ShortTag,IntTag,LongTag,FloatTag,DoubleTag,BooleanTag,StringTag,ByteArrayTag,IntArrayTag,LongArrayTag,ListTagandCompoundTag. The tree tells0b,0s,0and0Lapart.Tag::toPhp()returns the native PHP value. This is the same value thatparse()returns.Tag::toSnbt(SNBTFormat $format = SNBTFormat::Compact)serializes the tag back to SNBT and keeps the NBT types. A compactdata getblob round-trips byte for byte.SNBTFormatselects the layout oftoSnbt().Compactgives{a:1,b:[1,2]}.Spacedgives{ a: 1, b: [ 1, 2 ] }.Prettyputs compounds and lists on multiple lines with four-space indentation, and keeps typed number arrays on one line.CompoundTag::get(string $key): ?TagandCompoundTag::has(string $key): boolread compound entries.ListTag::get(int $index): ?Tagreads list items.CompoundTag,ListTagand the three number array tags implementCountableandIteratorAggregate.count($tag)andforeach ($tag as $key => $value)work on them. The readonlyentries,itemsandvaluesproperties expose the contents as arrays.examples/parse-typed.phpdumps a typed tree, itstoPhp()value and itstoSnbt()output.
Changed
parse()now delegates toparseTyped()->toPhp(). The return values do not change: every integer type becomesint, every floating-point type becomesfloat,trueandfalsebecomebool.- Unquoted string values parse.
{ id: stone }returns[ "id" => "stone" ]. Earlier versions threw on this input. - The escape sequences
\n,\rand\tdecode to the control characters.toSnbt()writes them back as escape sequences. [B; true, false]parses to the bytes1and0. Earlier versions returned0for both.- Invalid typed-array elements throw
SNBTParseException. This covers[I; foo],[I; 1.5],[I; 1f]and boolean keywords outside a byte array. Earlier versions returned0for these elements. Any integer suffix is still accepted in any array type, so[I; 1b, 2s]parses. - Parse errors report the byte position and the text near it. Example:
Expected ',' or '}' at position 6 near "x: 1}".
Removed
- The
ext-mbstringrequirement. The package needs no PHP extensions. - The internal
Stilling\SNBTParser\Tokensnamespace. It was not part of the public API.
Compatibility
- PHP 8.3, 8.4 and 8.5 are supported. The CI matrix tests all three with the lowest and the highest dependency versions.
SNBTParser::parse()andSNBTParser::intsToUuid()keep their signatures. The declared return type ofparse()no longer listsobject, which it never returned.
Upgrading from 0.3
No code changes are needed for parse() and intsToUuid(). Check these points:
- If your input relied on invalid typed-array elements parsing as
0, it now throws. Fix the input, or catchSNBTParseException. - If your input contained
\n,\ror\tescape sequences, the values now contain the control characters instead of the two-character sequences. - If you catch parse errors by message text, update the patterns. The messages changed.
Full Changelog: v0.3.0...v1.0.0
v0.3.0
What's Changed
This release focuses on parser correctness, fixing several string and number edge cases, and broadens SNBT compatibility, alongside stricter internal typing.
Fixes
- Strings: spaces inside quoted strings are no longer stripped
- Strings: values are now escaped via
json_encode, fixing malformed output for strings containing quotes, backslashes, tabs, or newlines - Strings: correctly terminate strings ending in an escaped backslash (e.g.
"C:\\") - Arrays: empty typed arrays (
[I;],[B;],[L;]) now parse to[]instead of[0] - Numbers: full float/double precision is preserved instead of being rounded to 14 significant digits (e.g.
0.10000000149011612d)
Features
- Allow dots, dashes, and plus signs in unquoted compound keys
- Tolerate tabs and newlines between tokens, so pretty-printed SNBT parses
- Malformed input now throws a dedicated
SNBTParseException(implementsSNBTException, extendsRuntimeException) instead of a bareException(still catchable as\Exception)
Tooling
- Static analysis with PHPStan at level 8 across
srcandtests, enforced in CI - Development-only files are trimmed from the distributed package via
.gitattributes
Full Changelog: v0.2.0...v0.3.0
v0.2.0
What's Changed
- Removed PHP 8.3 support
It only ever actually worked due to unintentional polyfills for mb_* functions, and I rather avoid an explicit dependency. If you require this to work on PHP 8.3, install v0.1.2 alongsidesymfony/polyfill-mbstring. - Added tests against PHP 8.5
Full Changelog: v0.1.2...v0.2.0
v0.1.2
What's Changed
- refactor: recursive -> iterative parsing leading to massive reductions in memory usage for large SNBT payloads
Full Changelog: v0.1.1...v0.1.2