diff --git a/composer.json b/composer.json index ea49fcd3f..c548e6331 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "require": { "php": "^8.0", "php-64bit": "*", - "ext-chunkutils2": "^0.2.0", + "ext-chunkutils2": "^0.3.0", "ext-crypto": "^0.3.1", "ext-ctype": "*", "ext-curl": "*", diff --git a/composer.lock b/composer.lock index 62ccacf9d..70eadad96 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "009abb4d28399a27dc9d059bfd849aee", + "content-hash": "ad6be987e3e2228abcb23e169f139d29", "packages": [ { "name": "adhocore/json-comment", @@ -3532,7 +3532,7 @@ "platform": { "php": "^8.0", "php-64bit": "*", - "ext-chunkutils2": "^0.2.0", + "ext-chunkutils2": "^0.3.0", "ext-crypto": "^0.3.1", "ext-ctype": "*", "ext-curl": "*", diff --git a/src/PocketMine.php b/src/PocketMine.php index 4d6d3cd4a..afac6fd8d 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -129,7 +129,7 @@ namespace pocketmine { } $chunkutils2_version = phpversion("chunkutils2"); - $wantedVersionLock = "0.2"; + $wantedVersionLock = "0.3"; $wantedVersionMin = "$wantedVersionLock.0"; if($chunkutils2_version !== false && ( version_compare($chunkutils2_version, $wantedVersionMin) < 0 || diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 8f621e0c8..956559886 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -32,8 +32,10 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; +use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; use function count; +use function str_repeat; final class ChunkSerializer{ @@ -81,8 +83,17 @@ final class ChunkSerializer{ $stream->putByte(count($layers)); foreach($layers as $blocks){ - $stream->putByte(($blocks->getBitsPerBlock() << 1) | ($persistentBlockStates ? 0 : 1)); - $stream->put($blocks->getWordArray()); + if($blocks->getBitsPerBlock() === 0){ + //TODO: we use these in memory, but the game doesn't support them yet + //polyfill them with 1-bpb instead + $bitsPerBlock = 1; + $words = str_repeat("\x00", PalettedBlockArray::getExpectedWordArraySize(1)); + }else{ + $bitsPerBlock = $blocks->getBitsPerBlock(); + $words = $blocks->getWordArray(); + } + $stream->putByte(($bitsPerBlock << 1) | ($persistentBlockStates ? 0 : 1)); + $stream->put($words); $palette = $blocks->getPalette(); //these LSHIFT by 1 uvarints are optimizations: the client expects zigzag varints here diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 92beecc2a..d849822b5 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -446,8 +446,15 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $layers = $subChunk->getBlockLayers(); $subStream->putByte(count($layers)); foreach($layers as $blocks){ - $subStream->putByte($blocks->getBitsPerBlock() << 1); - $subStream->put($blocks->getWordArray()); + if($blocks->getBitsPerBlock() !== 0){ + $subStream->putByte($blocks->getBitsPerBlock() << 1); + $subStream->put($blocks->getWordArray()); + }else{ + //TODO: we use these in-memory, but they aren't supported on disk by the game yet + //polyfill them with a zero'd 1-bpb instead + $subStream->putByte(1 << 1); + $subStream->put(str_repeat("\x00", PalettedBlockArray::getExpectedWordArraySize(1))); + } $palette = $blocks->getPalette(); $subStream->putLInt(count($palette));