deserializer = new BlockStateToBlockObjectDeserializer(); $this->serializer = new BlockObjectToBlockStateSerializer(); } public function testAllKnownBlockStatesSerializableAndDeserializable() : void{ foreach(BlockFactory::getInstance()->getAllKnownStates() as $block){ try{ $blockStateData = $this->serializer->serializeBlock($block); }catch(BlockStateSerializeException $e){ self::fail($e->getMessage()); } try{ $newBlock = $this->deserializer->deserializeBlock($blockStateData); }catch(BlockStateDeserializeException $e){ self::fail($e->getMessage()); } if($block->getTypeId() === BlockTypeIds::POTION_CAULDRON){ //this pretends to be a water cauldron in the blockstate, and stores its actual data in the blockentity continue; } //The following are workarounds for differences in blockstate representation in Bedrock vs PM //In these cases, some properties are not stored in the blockstate (but rather in the block entity NBT), but //they do form part of the internal blockstate hash in PM. This leads to inconsistencies when serializing //and deserializing blockstates. if( ($block instanceof BaseBanner && $newBlock instanceof BaseBanner) || ($block instanceof Bed && $newBlock instanceof Bed) ){ $newBlock->setColor($block->getColor()); }elseif($block instanceof Skull && $newBlock instanceof Skull){ $newBlock->setSkullType($block->getSkullType()); } self::assertSame($block->getStateId(), $newBlock->getStateId(), "Mismatch of blockstate for " . $block->getName() . ", " . print_r($block, true) . " vs " . print_r($newBlock, true)); } } }