From efd113bdc88a9b8382e6f1a47b70cb39493a0790 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 26 Feb 2024 17:09:09 +0000 Subject: [PATCH] Integrate pmmp/BedrockProtocol@65b3d0b341afc5c0aa952f1d71a4109d78bb0a59 --- composer.json | 2 +- composer.lock | 22 ++++++------ src/Server.php | 11 +++--- src/network/mcpe/ChunkRequestTask.php | 6 ++-- src/network/mcpe/NetworkSession.php | 8 ++--- .../mcpe/StandardPacketBroadcaster.php | 10 ++---- src/network/mcpe/convert/TypeConverter.php | 29 +++++++++++---- src/network/mcpe/raklib/RakLibInterface.php | 5 --- .../mcpe/serializer/ChunkSerializer.php | 5 ++- tools/generate-bedrock-data-from-packets.php | 35 ++++++++++--------- 10 files changed, 67 insertions(+), 66 deletions(-) diff --git a/composer.json b/composer.json index 47e798b16..01b4c75b1 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "pocketmine/bedrock-block-upgrade-schema": "~3.5.0+bedrock-1.20.60", "pocketmine/bedrock-data": "~2.8.0+bedrock-1.20.60", "pocketmine/bedrock-item-upgrade-schema": "~1.7.0+bedrock-1.20.60", - "pocketmine/bedrock-protocol": "~27.0.0+bedrock-1.20.60", + "pocketmine/bedrock-protocol": "dev-master", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/color": "^0.3.0", diff --git a/composer.lock b/composer.lock index 47aeeaeca..eb6faf8b2 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": "d923f5fd75f0d33eb5198268a74a58b4", + "content-hash": "1786511a89ee1a1e932ecc68834ec476", "packages": [ { "name": "adhocore/json-comment", @@ -200,21 +200,20 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "27.0.1+bedrock-1.20.60", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "0cebb55f6e904f722b14d420f6b2c84c7fa69f10" + "reference": "6e73f21cdc7433f0674dfcdf4817f478aa5528e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/0cebb55f6e904f722b14d420f6b2c84c7fa69f10", - "reference": "0cebb55f6e904f722b14d420f6b2c84c7fa69f10", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/6e73f21cdc7433f0674dfcdf4817f478aa5528e6", + "reference": "6e73f21cdc7433f0674dfcdf4817f478aa5528e6", "shasum": "" }, "require": { "ext-json": "*", - "netresearch/jsonmapper": "^4.0", "php": "^8.1", "pocketmine/binaryutils": "^0.2.0", "pocketmine/color": "^0.2.0 || ^0.3.0", @@ -223,11 +222,12 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "1.10.39", + "phpstan/phpstan": "1.10.59", "phpstan/phpstan-phpunit": "^1.0.0", "phpstan/phpstan-strict-rules": "^1.0.0", "phpunit/phpunit": "^9.5 || ^10.0" }, + "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -241,9 +241,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/27.0.1+bedrock-1.20.60" + "source": "https://github.com/pmmp/BedrockProtocol/tree/master" }, - "time": "2024-02-07T11:53:50+00:00" + "time": "2024-02-26T16:18:34+00:00" }, { "name": "pocketmine/binaryutils", @@ -2931,7 +2931,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "pocketmine/bedrock-protocol": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/src/Server.php b/src/Server.php index 73bfdb85a..ed7f52d63 100644 --- a/src/Server.php +++ b/src/Server.php @@ -59,7 +59,6 @@ use pocketmine\network\mcpe\EntityEventBroadcaster; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\PacketBroadcaster; use pocketmine\network\mcpe\protocol\ProtocolInfo; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm; use pocketmine\network\mcpe\raklib\RakLibInterface; use pocketmine\network\mcpe\StandardEntityEventBroadcaster; @@ -1187,12 +1186,11 @@ class Server{ bool $useQuery, PacketBroadcaster $packetBroadcaster, EntityEventBroadcaster $entityEventBroadcaster, - PacketSerializerContext $packetSerializerContext, TypeConverter $typeConverter ) : bool{ $prettyIp = $ipV6 ? "[$ip]" : $ip; try{ - $rakLibRegistered = $this->network->registerInterface(new RakLibInterface($this, $ip, $port, $ipV6, $packetBroadcaster, $entityEventBroadcaster, $packetSerializerContext, $typeConverter)); + $rakLibRegistered = $this->network->registerInterface(new RakLibInterface($this, $ip, $port, $ipV6, $packetBroadcaster, $entityEventBroadcaster, $typeConverter)); }catch(NetworkInterfaceStartException $e){ $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_networkStartFailed( $ip, @@ -1219,15 +1217,14 @@ class Server{ $useQuery = $this->configGroup->getConfigBool(ServerProperties::ENABLE_QUERY, true); $typeConverter = TypeConverter::getInstance(); - $packetSerializerContext = new PacketSerializerContext($typeConverter->getItemTypeDictionary()); - $packetBroadcaster = new StandardPacketBroadcaster($this, $packetSerializerContext); + $packetBroadcaster = new StandardPacketBroadcaster($this); $entityEventBroadcaster = new StandardEntityEventBroadcaster($packetBroadcaster, $typeConverter); if( - !$this->startupPrepareConnectableNetworkInterfaces($this->getIp(), $this->getPort(), false, $useQuery, $packetBroadcaster, $entityEventBroadcaster, $packetSerializerContext, $typeConverter) || + !$this->startupPrepareConnectableNetworkInterfaces($this->getIp(), $this->getPort(), false, $useQuery, $packetBroadcaster, $entityEventBroadcaster, $typeConverter) || ( $this->configGroup->getConfigBool(ServerProperties::ENABLE_IPV6, true) && - !$this->startupPrepareConnectableNetworkInterfaces($this->getIpV6(), $this->getPortV6(), true, $useQuery, $packetBroadcaster, $entityEventBroadcaster, $packetSerializerContext, $typeConverter) + !$this->startupPrepareConnectableNetworkInterfaces($this->getIpV6(), $this->getPortV6(), true, $useQuery, $packetBroadcaster, $entityEventBroadcaster, $typeConverter) ) ){ return false; diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 05a4f20c1..13b5db5b7 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -28,7 +28,6 @@ use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\LevelChunkPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\protocol\types\ChunkPosition; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\serializer\ChunkSerializer; @@ -72,11 +71,10 @@ class ChunkRequestTask extends AsyncTask{ $subCount = ChunkSerializer::getSubChunkCount($chunk, $dimensionId); $converter = TypeConverter::getInstance(); - $encoderContext = new PacketSerializerContext($converter->getItemTypeDictionary()); - $payload = ChunkSerializer::serializeFullChunk($chunk, $dimensionId, $converter->getBlockTranslator(), $encoderContext, $this->tiles); + $payload = ChunkSerializer::serializeFullChunk($chunk, $dimensionId, $converter->getBlockTranslator(), $this->tiles); $stream = new BinaryStream(); - PacketBatch::encodePackets($stream, $encoderContext, [LevelChunkPacket::create(new ChunkPosition($this->chunkX, $this->chunkZ), $dimensionId, $subCount, false, null, $payload)]); + PacketBatch::encodePackets($stream, [LevelChunkPacket::create(new ChunkPosition($this->chunkX, $this->chunkZ), $dimensionId, $subCount, false, null, $payload)]); $compressor = $this->compressor->deserialize(); $this->setResult(chr($compressor->getNetworkId()) . $compressor->compress($stream->getBuffer())); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 8ac4db98f..63fab278e 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -67,7 +67,6 @@ use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\mcpe\protocol\SetDifficultyPacket; @@ -180,7 +179,6 @@ class NetworkSession{ private Server $server, private NetworkSessionManager $manager, private PacketPool $packetPool, - private PacketSerializerContext $packetSerializerContext, private PacketSender $sender, private PacketBroadcaster $broadcaster, private EntityEventBroadcaster $entityEventBroadcaster, @@ -435,7 +433,7 @@ class NetworkSession{ $decodeTimings = Timings::getDecodeDataPacketTimings($packet); $decodeTimings->startTiming(); try{ - $stream = PacketSerializer::decoder($buffer, 0, $this->packetSerializerContext); + $stream = PacketSerializer::decoder($buffer, 0); try{ $packet->decode($stream); }catch(PacketDecodeException $e){ @@ -494,7 +492,7 @@ class NetworkSession{ } foreach($packets as $evPacket){ - $this->addToSendBuffer(self::encodePacketTimed(PacketSerializer::encoder($this->packetSerializerContext), $evPacket)); + $this->addToSendBuffer(self::encodePacketTimed(PacketSerializer::encoder(), $evPacket)); } if($immediate){ $this->flushSendBuffer(true); @@ -554,8 +552,6 @@ class NetworkSession{ } } - public function getPacketSerializerContext() : PacketSerializerContext{ return $this->packetSerializerContext; } - public function getBroadcaster() : PacketBroadcaster{ return $this->broadcaster; } public function getEntityEventBroadcaster() : EntityEventBroadcaster{ return $this->entityEventBroadcaster; } diff --git a/src/network/mcpe/StandardPacketBroadcaster.php b/src/network/mcpe/StandardPacketBroadcaster.php index 1de6f80fe..32afdeeb7 100644 --- a/src/network/mcpe/StandardPacketBroadcaster.php +++ b/src/network/mcpe/StandardPacketBroadcaster.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\BinaryStream; @@ -37,8 +36,7 @@ use function strlen; final class StandardPacketBroadcaster implements PacketBroadcaster{ public function __construct( - private Server $server, - private PacketSerializerContext $protocolContext + private Server $server ){} public function broadcastPackets(array $recipients, array $packets) : void{ @@ -58,10 +56,6 @@ final class StandardPacketBroadcaster implements PacketBroadcaster{ /** @var NetworkSession[][] $targetsByCompressor */ $targetsByCompressor = []; foreach($recipients as $recipient){ - if($recipient->getPacketSerializerContext() !== $this->protocolContext){ - throw new \InvalidArgumentException("Only recipients with the same protocol context as the broadcaster can be broadcast to by this broadcaster"); - } - //TODO: different compressors might be compatible, it might not be necessary to split them up by object $compressor = $recipient->getCompressor(); $compressors[spl_object_id($compressor)] = $compressor; @@ -72,7 +66,7 @@ final class StandardPacketBroadcaster implements PacketBroadcaster{ $totalLength = 0; $packetBuffers = []; foreach($packets as $packet){ - $buffer = NetworkSession::encodePacketTimed(PacketSerializer::encoder($this->protocolContext), $packet); + $buffer = NetworkSession::encodePacketTimed(PacketSerializer::encoder(), $packet); //varint length prefix + packet buffer $totalLength += (((int) log(strlen($buffer), 128)) + 1) + strlen($buffer); $packetBuffers[] = $buffer; diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 53ce6e98a..0f9789de7 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -30,13 +30,17 @@ use pocketmine\crafting\RecipeIngredient; use pocketmine\crafting\TagWildcardRecipeIngredient; use pocketmine\data\bedrock\BedrockDataFiles; use pocketmine\data\bedrock\item\BlockItemIdMap; +use pocketmine\data\bedrock\item\ItemTypeNames; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use pocketmine\nbt\NbtException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\GameMode as ProtocolGameMode; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStackExtraData; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStackExtraDataShield; use pocketmine\network\mcpe\protocol\types\recipe\IntIdMetaItemDescriptor; use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient as ProtocolRecipeIngredient; use pocketmine\network\mcpe\protocol\types\recipe\StringIdMetaItemDescriptor; @@ -76,7 +80,7 @@ class TypeConverter{ ); $this->itemTypeDictionary = ItemTypeDictionaryFromDataHelper::loadFromString(Filesystem::fileGetContents(BedrockDataFiles::REQUIRED_ITEM_LIST_JSON)); - $this->shieldRuntimeId = $this->itemTypeDictionary->fromStringId("minecraft:shield"); + $this->shieldRuntimeId = $this->itemTypeDictionary->fromStringId(ItemTypeNames::SHIELD); $this->itemTranslator = new ItemTranslator( $this->itemTypeDictionary, @@ -217,26 +221,39 @@ class TypeConverter{ [$id, $meta, $blockRuntimeId] = $idMeta; } + $extraData = $id === $this->shieldRuntimeId ? + new ItemStackExtraDataShield($nbt, canPlaceOn: [], canDestroy: [], blockingTick: 0) : + new ItemStackExtraData($nbt, canPlaceOn: [], canDestroy: []); + $extraDataSerializer = PacketSerializer::encoder(); + $extraData->write($extraDataSerializer); + return new ItemStack( $id, $meta, $itemStack->getCount(), $blockRuntimeId ?? ItemTranslator::NO_BLOCK_RUNTIME_ID, - $nbt, - [], - [], - $id === $this->shieldRuntimeId ? 0 : null + $extraDataSerializer->getBuffer(), ); } /** + * WARNING: Avoid this in server-side code. If you need to compare ItemStacks provided by the client to the + * server, prefer encoding the server's itemstack and comparing the serialized ItemStack, instead of converting + * the client's ItemStack to a core Item. + * This method will fully decode the item's extra data, which can be very costly if the item has a lot of NBT data. + * * @throws TypeConversionException */ public function netItemStackToCore(ItemStack $itemStack) : Item{ if($itemStack->getId() === 0){ return VanillaItems::AIR(); } - $compound = $itemStack->getNbt(); + $extraDataDeserializer = PacketSerializer::decoder($itemStack->getRawExtraData(), 0); + $extraData = $itemStack->getId() === $this->shieldRuntimeId ? + ItemStackExtraDataShield::read($extraDataDeserializer) : + ItemStackExtraData::read($extraDataDeserializer); + + $compound = $extraData->getNbt(); $itemResult = $this->itemTranslator->fromNetworkId($itemStack->getId(), $itemStack->getMeta(), $itemStack->getBlockRuntimeId()); diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 17aa87e83..b2325f569 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -33,7 +33,6 @@ use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\PacketBroadcaster; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\ProtocolInfo; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\Network; use pocketmine\network\NetworkInterfaceStartException; use pocketmine\network\PacketHandlingException; @@ -84,7 +83,6 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ private PacketBroadcaster $packetBroadcaster; private EntityEventBroadcaster $entityEventBroadcaster; - private PacketSerializerContext $packetSerializerContext; private TypeConverter $typeConverter; public function __construct( @@ -94,12 +92,10 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ bool $ipV6, PacketBroadcaster $packetBroadcaster, EntityEventBroadcaster $entityEventBroadcaster, - PacketSerializerContext $packetSerializerContext, TypeConverter $typeConverter ){ $this->server = $server; $this->packetBroadcaster = $packetBroadcaster; - $this->packetSerializerContext = $packetSerializerContext; $this->entityEventBroadcaster = $entityEventBroadcaster; $this->typeConverter = $typeConverter; @@ -192,7 +188,6 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->server, $this->network->getSessionManager(), PacketPool::getInstance(), - $this->packetSerializerContext, new RakLibPacketSender($sessionId, $this), $this->packetBroadcaster, $this->entityEventBroadcaster, diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index e089daef5..9120f34a7 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -30,7 +30,6 @@ use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\convert\BlockTranslator; use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; @@ -84,8 +83,8 @@ final class ChunkSerializer{ /** * @phpstan-param DimensionIds::* $dimensionId */ - public static function serializeFullChunk(Chunk $chunk, int $dimensionId, BlockTranslator $blockTranslator, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{ - $stream = PacketSerializer::encoder($encoderContext); + public static function serializeFullChunk(Chunk $chunk, int $dimensionId, BlockTranslator $blockTranslator, ?string $tiles = null) : string{ + $stream = PacketSerializer::encoder(); $subChunkCount = self::getSubChunkCount($chunk, $dimensionId); $writtenCount = 0; diff --git a/tools/generate-bedrock-data-from-packets.php b/tools/generate-bedrock-data-from-packets.php index 77d2b9d93..ca15bd8be 100644 --- a/tools/generate-bedrock-data-from-packets.php +++ b/tools/generate-bedrock-data-from-packets.php @@ -34,6 +34,7 @@ use pocketmine\crafting\json\SmithingTransformRecipeData; use pocketmine\crafting\json\SmithingTrimRecipeData; use pocketmine\data\bedrock\block\BlockStateData; use pocketmine\data\bedrock\item\BlockItemIdMap; +use pocketmine\data\bedrock\item\ItemTypeNames; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; @@ -50,12 +51,12 @@ use pocketmine\network\mcpe\protocol\CreativeContentPacket; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\protocol\StartGamePacket; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\types\inventory\CreativeContentEntry; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\protocol\types\ItemTypeEntry; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStackExtraData; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStackExtraDataShield; use pocketmine\network\mcpe\protocol\types\recipe\ComplexAliasItemDescriptor; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe; use pocketmine\network\mcpe\protocol\types\recipe\IntIdMetaItemDescriptor; @@ -170,16 +171,21 @@ class ParserPacketHandler extends PacketHandler{ $data->meta = $meta; } - $nbt = $itemStack->getNbt(); - if($nbt !== null && count($nbt) > 0){ - $data->nbt = base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($nbt))); - } + $rawExtraData = $itemStack->getRawExtraData(); + if($rawExtraData !== ""){ + $decoder = PacketSerializer::decoder($rawExtraData, 0); + $extraData = $itemStringId === ItemTypeNames::SHIELD ? ItemStackExtraDataShield::read($decoder) : ItemStackExtraData::read($decoder); + $nbt = $extraData->getNbt(); + if($nbt !== null && count($nbt) > 0){ + $data->nbt = base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($nbt))); + } - if(count($itemStack->getCanPlaceOn()) > 0){ - $data->can_place_on = $itemStack->getCanPlaceOn(); - } - if(count($itemStack->getCanDestroy()) > 0){ - $data->can_destroy = $itemStack->getCanDestroy(); + if(count($extraData->getCanPlaceOn()) > 0){ + $data->can_place_on = $extraData->getCanPlaceOn(); + } + if(count($extraData->getCanDestroy()) > 0){ + $data->can_destroy = $extraData->getCanDestroy(); + } } return $data; @@ -421,7 +427,7 @@ class ParserPacketHandler extends PacketHandler{ $recipes["potion_type"][] = new PotionTypeRecipeData( $this->recipeIngredientToJson(new RecipeIngredient(new IntIdMetaItemDescriptor($recipe->getInputItemId(), $recipe->getInputItemMeta()), 1)), $this->recipeIngredientToJson(new RecipeIngredient(new IntIdMetaItemDescriptor($recipe->getIngredientItemId(), $recipe->getIngredientItemMeta()), 1)), - $this->itemStackToJson(new ItemStack($recipe->getOutputItemId(), $recipe->getOutputItemMeta(), 1, 0, null, [], [], null)), + $this->itemStackToJson(new ItemStack($recipe->getOutputItemId(), $recipe->getOutputItemMeta(), 1, 0, "")), ); } @@ -571,10 +577,7 @@ function main(array $argv) : int{ fwrite(STDERR, "Unknown packet on line " . ($lineNum + 1) . ": " . $parts[1]); continue; } - $serializer = PacketSerializer::decoder($raw, 0, new PacketSerializerContext( - $handler->itemTypeDictionary ?? - new ItemTypeDictionary([new ItemTypeEntry("minecraft:shield", 0, false)])) - ); + $serializer = PacketSerializer::decoder($raw, 0); $pk->decode($serializer); $pk->handle($handler);