From ab75838c89b750a34bf2485e0b9c11a94de7a3c4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 10 Jun 2023 18:35:42 +0100 Subject: [PATCH 01/25] First shot at implementing acacia trees this is mostly working, but due to some issue with leaf decay, the edges of the larger canopy will decay within minutes. I don't know why this is yet, but it's likely some incorrect implementation of Leaves causing the problem. In addition, the secondary branch of acacia may generate next to the base block of the trunk, which I've never observed to happen in vanilla. This has a 2% chance of occurring, so I haven't been able to rule it out yet, but it probably shouldn't happen. --- src/world/generator/object/AcaciaTree.php | 132 +++++++++++++++++++++ src/world/generator/object/TreeFactory.php | 2 + 2 files changed, 134 insertions(+) create mode 100644 src/world/generator/object/AcaciaTree.php diff --git a/src/world/generator/object/AcaciaTree.php b/src/world/generator/object/AcaciaTree.php new file mode 100644 index 000000000..75e58a9b3 --- /dev/null +++ b/src/world/generator/object/AcaciaTree.php @@ -0,0 +1,132 @@ +nextRange(0, 2) + $random->nextRange(0, 2); + } + + protected function placeTrunk(int $x, int $y, int $z, Random $random, int $trunkHeight, BlockTransaction $transaction) : void{ + // The base dirt block + $transaction->addBlockAt($x, $y - 1, $z, VanillaBlocks::DIRT()); + + $firstBranchHeight = $trunkHeight - 1 - $random->nextRange(0, 3); + + for($yy = 0; $yy <= $firstBranchHeight; ++$yy){ + $transaction->addBlockAt($x, $y + $yy, $z, $this->trunkBlock); + } + + $mainBranchFacing = Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]; + + //this branch may grow a second trunk if the diagonal length is less than the max length + $this->mainBranchTip = $this->placeBranch( + $transaction, + new Vector3($x, $y + $firstBranchHeight, $z), + $mainBranchFacing, + $random->nextRange(1, 3), + $trunkHeight - $firstBranchHeight + ); + + $secondBranchFacing = Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]; + if($secondBranchFacing !== $mainBranchFacing){ + $secondBranchLength = $random->nextRange(1, 3); + $this->secondBranchTip = $this->placeBranch( + $transaction, + new Vector3($x, $y + ($firstBranchHeight - $random->nextRange(0, 1)), $z), + $secondBranchFacing, + $secondBranchLength, + $secondBranchLength //the secondary branch may not form a second trunk + ); + } + } + + protected function placeBranch(BlockTransaction $transaction, Vector3 $start, int $branchFacing, int $maxDiagonal, int $length) : Vector3{ + $diagonalPlaced = 0; + + $nextBlockPos = $start; + for($yy = 0; $yy < $length; $yy++){ + $nextBlockPos = $nextBlockPos->up(); + if($diagonalPlaced < $maxDiagonal){ + $nextBlockPos = $nextBlockPos->getSide($branchFacing); + $diagonalPlaced++; + } + $transaction->addBlock($nextBlockPos, $this->trunkBlock); + } + + return $nextBlockPos; + } + + protected function placeCanopyLayer(BlockTransaction $transaction, Vector3 $center, int $radius, int $maxTaxicabDistance) : void{ + $centerX = $center->getFloorX(); + $centerY = $center->getFloorY(); + $centerZ = $center->getFloorZ(); + + for($x = $centerX - $radius; $x <= $centerX + $radius; ++$x){ + for($z = $centerZ - $radius; $z <= $centerZ + $radius; ++$z){ + if( + abs($x - $centerX) + abs($z - $centerZ) <= $maxTaxicabDistance && + $transaction->fetchBlockAt($x, $centerY, $z)->canBeReplaced() + ){ + $transaction->addBlockAt($x, $centerY, $z, $this->leafBlock); + } + } + } + } + + protected function placeCanopy(int $x, int $y, int $z, Random $random, BlockTransaction $transaction) : void{ + $mainBranchTip = $this->mainBranchTip; + if($mainBranchTip !== null){ + $this->placeCanopyLayer($transaction, $mainBranchTip, radius: 3, maxTaxicabDistance: 5); + $this->placeCanopyLayer($transaction, $mainBranchTip->up(), radius: 2, maxTaxicabDistance: 2); + } + $secondBranchTip = $this->secondBranchTip; + if($secondBranchTip !== null){ + $this->placeCanopyLayer($transaction, $secondBranchTip, radius: 2, maxTaxicabDistance: 3); + $this->placeCanopyLayer($transaction, $secondBranchTip->up(), radius: 1, maxTaxicabDistance: 2); + } + } +} diff --git a/src/world/generator/object/TreeFactory.php b/src/world/generator/object/TreeFactory.php index ecab73c79..1d95a77b1 100644 --- a/src/world/generator/object/TreeFactory.php +++ b/src/world/generator/object/TreeFactory.php @@ -49,6 +49,8 @@ final class TreeFactory{ }else{*/ //} + }elseif($type->equals(TreeType::ACACIA())){ + return new AcaciaTree(); } return null; } From c01d2dc7181d8e2c98115c19d85759ab990860da Mon Sep 17 00:00:00 2001 From: BrandPVP <114182697+BrandPVP@users.noreply.github.com> Date: Thu, 6 Jul 2023 13:08:13 +0300 Subject: [PATCH 02/25] CreativeInventory per Player (#5694) --- .../transaction/action/CreateItemAction.php | 3 +-- src/network/mcpe/InventoryManager.php | 3 +-- .../mcpe/handler/ItemStackRequestExecutor.php | 3 +-- src/player/Player.php | 22 +++++++++++++++++++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/inventory/transaction/action/CreateItemAction.php b/src/inventory/transaction/action/CreateItemAction.php index 99605bf96..3ebda6900 100644 --- a/src/inventory/transaction/action/CreateItemAction.php +++ b/src/inventory/transaction/action/CreateItemAction.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; -use pocketmine\inventory\CreativeInventory; use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\item\VanillaItems; @@ -43,7 +42,7 @@ class CreateItemAction extends InventoryAction{ if($source->hasFiniteResources()){ throw new TransactionValidationException("Player has finite resources, cannot create items"); } - if(!CreativeInventory::getInstance()->contains($this->sourceItem)){ + if(!$source->getCreativeInventory()->contains($this->sourceItem)){ throw new TransactionValidationException("Creative inventory does not contain requested item"); } } diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index bdd3a892d..a94dbe946 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -35,7 +35,6 @@ use pocketmine\block\inventory\LoomInventory; use pocketmine\block\inventory\SmithingTableInventory; use pocketmine\block\inventory\StonecutterInventory; use pocketmine\crafting\FurnaceType; -use pocketmine\inventory\CreativeInventory; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\inventory\transaction\InventoryTransaction; @@ -603,7 +602,7 @@ class InventoryManager{ } public function syncCreative() : void{ - $this->session->sendDataPacket(CreativeInventoryCache::getInstance()->getCache(CreativeInventory::getInstance())); + $this->session->sendDataPacket(CreativeInventoryCache::getInstance()->getCache($this->player->getCreativeInventory())); } private function newItemStackId() : int{ diff --git a/src/network/mcpe/handler/ItemStackRequestExecutor.php b/src/network/mcpe/handler/ItemStackRequestExecutor.php index f9532291c..10787f84b 100644 --- a/src/network/mcpe/handler/ItemStackRequestExecutor.php +++ b/src/network/mcpe/handler/ItemStackRequestExecutor.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; -use pocketmine\inventory\CreativeInventory; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\CreateItemAction; use pocketmine\inventory\transaction\action\DestroyItemAction; @@ -327,7 +326,7 @@ class ItemStackRequestExecutor{ $this->builder->addAction(new DestroyItemAction($destroyed)); }elseif($action instanceof CreativeCreateStackRequestAction){ - $item = CreativeInventory::getInstance()->getItem($action->getCreativeItemId()); + $item = $this->player->getCreativeInventory()->getItem($action->getCreativeItemId()); if($item === null){ throw new ItemStackRequestProcessException("No such creative item index: " . $action->getCreativeItemId()); } diff --git a/src/player/Player.php b/src/player/Player.php index 11dabf7db..4a13654d7 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -80,6 +80,7 @@ use pocketmine\event\player\PlayerViewDistanceChangeEvent; use pocketmine\form\Form; use pocketmine\form\FormValidationException; use pocketmine\inventory\CallbackInventoryListener; +use pocketmine\inventory\CreativeInventory; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerCraftingInventory; use pocketmine\inventory\PlayerCursorInventory; @@ -217,6 +218,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ protected array $permanentWindows = []; protected PlayerCursorInventory $cursorInventory; protected PlayerCraftingInventory $craftingGrid; + protected CreativeInventory $creativeInventory; protected int $messageCounter = 2; @@ -307,6 +309,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->uuid = $this->playerInfo->getUuid(); $this->xuid = $this->playerInfo instanceof XboxLivePlayerInfo ? $this->playerInfo->getXuid() : ""; + $this->creativeInventory = CreativeInventory::getInstance(); + $rootPermissions = [DefaultPermissions::ROOT_USER => true]; if($this->server->isOp($this->username)){ $rootPermissions[DefaultPermissions::ROOT_OPERATOR] = true; @@ -2532,6 +2536,24 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return $this->craftingGrid; } + /** + * Returns the creative inventory shown to the player. + * Unless changed by a plugin, this is usually the same for all players. + */ + public function getCreativeInventory() : CreativeInventory{ + return $this->creativeInventory; + } + + /** + * To set a custom creative inventory, you need to make a clone of a CreativeInventory instance. + */ + public function setCreativeInventory(CreativeInventory $inventory) : void{ + $this->creativeInventory = $inventory; + if($this->spawned && $this->isConnected()){ + $this->getNetworkSession()->getInvManager()?->syncCreative(); + } + } + /** * @internal Called to clean up crafting grid and cursor inventory when it is detected that the player closed their * inventory. From 7132ac0ad30c42105d903084249838f9ce3f29e1 Mon Sep 17 00:00:00 2001 From: ace Date: Thu, 13 Jul 2023 20:22:01 +0800 Subject: [PATCH 03/25] Implemented strong slowness potion (#5888) --- src/data/bedrock/PotionTypeIdMap.php | 1 + src/data/bedrock/PotionTypeIds.php | 1 + .../runtime/RuntimeEnumDeserializerTrait.php | 21 ++++++++++--------- .../runtime/RuntimeEnumSerializerTrait.php | 21 ++++++++++--------- src/item/PotionType.php | 4 ++++ src/item/StringToItemParser.php | 2 ++ 6 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/data/bedrock/PotionTypeIdMap.php b/src/data/bedrock/PotionTypeIdMap.php index 2e6fef3cc..8194f24a2 100644 --- a/src/data/bedrock/PotionTypeIdMap.php +++ b/src/data/bedrock/PotionTypeIdMap.php @@ -84,6 +84,7 @@ final class PotionTypeIdMap{ $this->register(PotionTypeIds::STRONG_TURTLE_MASTER, PotionType::STRONG_TURTLE_MASTER()); $this->register(PotionTypeIds::SLOW_FALLING, PotionType::SLOW_FALLING()); $this->register(PotionTypeIds::LONG_SLOW_FALLING, PotionType::LONG_SLOW_FALLING()); + $this->register(PotionTypeIds::STRONG_SLOWNESS, PotionType::STRONG_SLOWNESS()); } private function register(int $id, PotionType $type) : void{ diff --git a/src/data/bedrock/PotionTypeIds.php b/src/data/bedrock/PotionTypeIds.php index aa69461ce..f2d82f39f 100644 --- a/src/data/bedrock/PotionTypeIds.php +++ b/src/data/bedrock/PotionTypeIds.php @@ -66,4 +66,5 @@ final class PotionTypeIds{ public const STRONG_TURTLE_MASTER = 39; public const SLOW_FALLING = 40; public const LONG_SLOW_FALLING = 41; + public const STRONG_SLOWNESS = 42; } diff --git a/src/data/runtime/RuntimeEnumDeserializerTrait.php b/src/data/runtime/RuntimeEnumDeserializerTrait.php index c4864a7e7..4774304a9 100644 --- a/src/data/runtime/RuntimeEnumDeserializerTrait.php +++ b/src/data/runtime/RuntimeEnumDeserializerTrait.php @@ -190,16 +190,17 @@ trait RuntimeEnumDeserializerTrait{ 29 => \pocketmine\item\PotionType::STRONG_LEAPING(), 30 => \pocketmine\item\PotionType::STRONG_POISON(), 31 => \pocketmine\item\PotionType::STRONG_REGENERATION(), - 32 => \pocketmine\item\PotionType::STRONG_STRENGTH(), - 33 => \pocketmine\item\PotionType::STRONG_SWIFTNESS(), - 34 => \pocketmine\item\PotionType::STRONG_TURTLE_MASTER(), - 35 => \pocketmine\item\PotionType::SWIFTNESS(), - 36 => \pocketmine\item\PotionType::THICK(), - 37 => \pocketmine\item\PotionType::TURTLE_MASTER(), - 38 => \pocketmine\item\PotionType::WATER(), - 39 => \pocketmine\item\PotionType::WATER_BREATHING(), - 40 => \pocketmine\item\PotionType::WEAKNESS(), - 41 => \pocketmine\item\PotionType::WITHER(), + 32 => \pocketmine\item\PotionType::STRONG_SLOWNESS(), + 33 => \pocketmine\item\PotionType::STRONG_STRENGTH(), + 34 => \pocketmine\item\PotionType::STRONG_SWIFTNESS(), + 35 => \pocketmine\item\PotionType::STRONG_TURTLE_MASTER(), + 36 => \pocketmine\item\PotionType::SWIFTNESS(), + 37 => \pocketmine\item\PotionType::THICK(), + 38 => \pocketmine\item\PotionType::TURTLE_MASTER(), + 39 => \pocketmine\item\PotionType::WATER(), + 40 => \pocketmine\item\PotionType::WATER_BREATHING(), + 41 => \pocketmine\item\PotionType::WEAKNESS(), + 42 => \pocketmine\item\PotionType::WITHER(), default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for PotionType") }; } diff --git a/src/data/runtime/RuntimeEnumSerializerTrait.php b/src/data/runtime/RuntimeEnumSerializerTrait.php index fd65ffb42..c570046c6 100644 --- a/src/data/runtime/RuntimeEnumSerializerTrait.php +++ b/src/data/runtime/RuntimeEnumSerializerTrait.php @@ -190,16 +190,17 @@ trait RuntimeEnumSerializerTrait{ \pocketmine\item\PotionType::STRONG_LEAPING() => 29, \pocketmine\item\PotionType::STRONG_POISON() => 30, \pocketmine\item\PotionType::STRONG_REGENERATION() => 31, - \pocketmine\item\PotionType::STRONG_STRENGTH() => 32, - \pocketmine\item\PotionType::STRONG_SWIFTNESS() => 33, - \pocketmine\item\PotionType::STRONG_TURTLE_MASTER() => 34, - \pocketmine\item\PotionType::SWIFTNESS() => 35, - \pocketmine\item\PotionType::THICK() => 36, - \pocketmine\item\PotionType::TURTLE_MASTER() => 37, - \pocketmine\item\PotionType::WATER() => 38, - \pocketmine\item\PotionType::WATER_BREATHING() => 39, - \pocketmine\item\PotionType::WEAKNESS() => 40, - \pocketmine\item\PotionType::WITHER() => 41, + \pocketmine\item\PotionType::STRONG_SLOWNESS() => 32, + \pocketmine\item\PotionType::STRONG_STRENGTH() => 33, + \pocketmine\item\PotionType::STRONG_SWIFTNESS() => 34, + \pocketmine\item\PotionType::STRONG_TURTLE_MASTER() => 35, + \pocketmine\item\PotionType::SWIFTNESS() => 36, + \pocketmine\item\PotionType::THICK() => 37, + \pocketmine\item\PotionType::TURTLE_MASTER() => 38, + \pocketmine\item\PotionType::WATER() => 39, + \pocketmine\item\PotionType::WATER_BREATHING() => 40, + \pocketmine\item\PotionType::WEAKNESS() => 41, + \pocketmine\item\PotionType::WITHER() => 42, default => throw new \pocketmine\utils\AssumptionFailedError("All PotionType cases should be covered") }); } diff --git a/src/item/PotionType.php b/src/item/PotionType.php index 7ec0f3876..e7feb0b8e 100644 --- a/src/item/PotionType.php +++ b/src/item/PotionType.php @@ -65,6 +65,7 @@ use pocketmine\utils\EnumTrait; * @method static PotionType STRONG_LEAPING() * @method static PotionType STRONG_POISON() * @method static PotionType STRONG_REGENERATION() + * @method static PotionType STRONG_SLOWNESS() * @method static PotionType STRONG_STRENGTH() * @method static PotionType STRONG_SWIFTNESS() * @method static PotionType STRONG_TURTLE_MASTER() @@ -201,6 +202,9 @@ final class PotionType{ ]), new self("long_slow_falling", "Long Slow Falling", fn() => [ //TODO + ]), + new self("strong_slowness", "Strong Slowness", fn() => [ + new EffectInstance(VanillaEffects::SLOWNESS(), 20 * 20, 3) ]) ); } diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 46b37e3ae..e5e5252e1 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -1506,6 +1506,8 @@ final class StringToItemParser extends StringToTParser{ $result->register("strong_poison_splash_potion", fn() => Items::SPLASH_POTION()->setType(PotionType::STRONG_POISON())); $result->register("strong_regeneration_potion", fn() => Items::POTION()->setType(PotionType::STRONG_REGENERATION())); $result->register("strong_regeneration_splash_potion", fn() => Items::SPLASH_POTION()->setType(PotionType::STRONG_REGENERATION())); + $result->register("strong_slowness_potion", fn() => Items::POTION()->setType(PotionType::STRONG_SLOWNESS())); + $result->register("strong_slowness_splash_potion", fn() => Items::SPLASH_POTION()->setType(PotionType::STRONG_SLOWNESS())); $result->register("strong_strength_potion", fn() => Items::POTION()->setType(PotionType::STRONG_STRENGTH())); $result->register("strong_strength_splash_potion", fn() => Items::SPLASH_POTION()->setType(PotionType::STRONG_STRENGTH())); $result->register("strong_swiftness_potion", fn() => Items::POTION()->setType(PotionType::STRONG_SWIFTNESS())); From 259cc305df109c134fa36dde44655599e238d804 Mon Sep 17 00:00:00 2001 From: jasonw_4331 Date: Thu, 13 Jul 2023 08:36:53 -0400 Subject: [PATCH 04/25] Implement 1.20.10 short sneaking (#5892) --- src/entity/Living.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/entity/Living.php b/src/entity/Living.php index 29a8ceae8..2cf5d4053 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -217,6 +217,7 @@ abstract class Living extends Entity{ public function setSneaking(bool $value = true) : void{ $this->sneaking = $value; $this->networkPropertiesDirty = true; + $this->recalculateSize(); } public function isSprinting() : bool{ @@ -258,6 +259,8 @@ abstract class Living extends Entity{ if($this->isSwimming() || $this->isGliding()){ $width = $size->getWidth(); $this->setSize((new EntitySizeInfo($width, $width, $width * 0.9))->scale($this->getScale())); + }elseif($this->isSneaking()){ + $this->setSize((new EntitySizeInfo(3 / 4 * $size->getHeight(), $size->getWidth(), 3 / 4 * $size->getEyeHeight()))->scale($this->getScale())); }else{ $this->setSize($size->scale($this->getScale())); } From dca752c72f8daeb669dacebf67b0e093cbe366c4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jul 2023 14:50:02 +0100 Subject: [PATCH 05/25] Stem: implement facing property fixes #5858 technically speaking, the sideways states for non-fully-grown stems shouldn't exist, but they do in Bedrock, and changing this code to split non-fully-grown stems from fully grown ones would likely require BC breaks. This was the minimum necessary to achieve the desired functionality. --- src/block/Stem.php | 30 +++++++++++++++++-- .../convert/BlockStateDeserializerHelper.php | 9 ++++-- .../convert/BlockStateSerializerHelper.php | 6 +++- .../block_factory_consistency_check.json | 2 +- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/block/Stem.php b/src/block/Stem.php index 5f06a46cb..b0d49b28e 100644 --- a/src/block/Stem.php +++ b/src/block/Stem.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; use pocketmine\math\Facing; @@ -30,11 +31,34 @@ use function array_rand; use function mt_rand; abstract class Stem extends Crops{ + protected int $facing = Facing::UP; + + protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{ + parent::describeBlockOnlyState($w); + $w->facingExcept($this->facing, Facing::DOWN); + } + + public function getFacing() : int{ return $this->facing; } + + /** @return $this */ + public function setFacing(int $facing) : self{ + if($facing === Facing::DOWN){ + throw new \InvalidArgumentException("DOWN is not a valid facing for this block"); + } + $this->facing = $facing; + return $this; + } abstract protected function getPlant() : Block; + public function onNearbyBlockChange() : void{ + if($this->facing !== Facing::UP && !$this->getSide($this->facing)->hasSameTypeId($this->getPlant())){ + $this->position->getWorld()->setBlock($this->position, $this->setFacing(Facing::UP)); + } + } + public function onRandomTick() : void{ - if(mt_rand(0, 2) === 1){ + if($this->facing === Facing::UP && mt_rand(0, 2) === 1){ $world = $this->position->getWorld(); if($this->age < self::MAX_AGE){ $block = clone $this; @@ -52,11 +76,13 @@ abstract class Stem extends Crops{ } } - $side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]); + $facing = Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]; + $side = $this->getSide($facing); if($side->getTypeId() === BlockTypeIds::AIR && $side->getSide(Facing::DOWN)->hasTypeTag(BlockTypeTags::DIRT)){ $ev = new BlockGrowEvent($side, $grow); $ev->call(); if(!$ev->isCancelled()){ + $world->setBlock($this->position, $this->setFacing($facing)); $world->setBlock($side->position, $ev->getNewState()); } } diff --git a/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php b/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php index fab50717c..8018d71b8 100644 --- a/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php +++ b/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php @@ -236,9 +236,12 @@ final class BlockStateDeserializerHelper{ /** @throws BlockStateDeserializeException */ public static function decodeStem(Stem $block, BlockStateReader $in) : Stem{ - //TODO: our stems don't support facings yet (facing_direction) - $in->todo(BlockStateNames::FACING_DIRECTION); - return self::decodeCrops($block, $in); + //In PM, we use Facing::UP to indicate that the stem is not attached to a pumpkin/melon, since this makes the + //most intuitive sense (the stem is pointing at the sky). However, Bedrock uses the DOWN state for this, which + //is absurd, and I refuse to make our API similarly absurd. + $facing = $in->readFacingWithoutUp(); + return self::decodeCrops($block, $in) + ->setFacing($facing === Facing::DOWN ? Facing::UP : $facing); } /** @throws BlockStateDeserializeException */ diff --git a/src/data/bedrock/block/convert/BlockStateSerializerHelper.php b/src/data/bedrock/block/convert/BlockStateSerializerHelper.php index 7fc15fce6..97fa5532f 100644 --- a/src/data/bedrock/block/convert/BlockStateSerializerHelper.php +++ b/src/data/bedrock/block/convert/BlockStateSerializerHelper.php @@ -223,8 +223,12 @@ final class BlockStateSerializerHelper{ } public static function encodeStem(Stem $block, BlockStateWriter $out) : BlockStateWriter{ + //In PM, we use Facing::UP to indicate that the stem is not attached to a pumpkin/melon, since this makes the + //most intuitive sense (the stem is pointing at the sky). However, Bedrock uses the DOWN state for this, which + //is absurd, and I refuse to make our API similarly absurd. + $facing = $block->getFacing(); return self::encodeCrops($block, $out) - ->writeHorizontalFacing(Facing::NORTH); //TODO: PM impl doesn't support this yet + ->writeFacingWithoutUp($facing === Facing::UP ? Facing::DOWN : $facing); } public static function encodeStone(string $type) : BlockStateWriter{ diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 46838b853..e0d1bca1d 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"knownStates":{"???":[2624010],"Acacia Button":[2560272,2560273,2560274,2560275,2560276,2560277,2560280,2560281,2560282,2560283,2560284,2560285],"Acacia Door":[2560512,2560513,2560514,2560515,2560516,2560517,2560518,2560519,2560520,2560521,2560522,2560523,2560524,2560525,2560526,2560527,2560528,2560529,2560530,2560531,2560532,2560533,2560534,2560535,2560536,2560537,2560538,2560539,2560540,2560541,2560542,2560543],"Acacia Fence":[2560787],"Acacia Fence Gate":[2561040,2561041,2561042,2561043,2561044,2561045,2561046,2561047,2561048,2561049,2561050,2561051,2561052,2561053,2561054,2561055],"Acacia Leaves":[2561300,2561301,2561302,2561303],"Acacia Log":[2561554,2561555,2561556,2561557,2561558,2561559],"Acacia Planks":[2561815],"Acacia Pressure Plate":[2562072,2562073],"Acacia Sapling":[2562328,2562329],"Acacia Sign":[2562576,2562577,2562578,2562579,2562580,2562581,2562582,2562583,2562584,2562585,2562586,2562587,2562588,2562589,2562590,2562591],"Acacia Slab":[2562841,2562842,2562843],"Acacia Stairs":[2563096,2563097,2563098,2563099,2563100,2563101,2563102,2563103],"Acacia Trapdoor":[2563344,2563345,2563346,2563347,2563348,2563349,2563350,2563351,2563352,2563353,2563354,2563355,2563356,2563357,2563358,2563359],"Acacia Wall Sign":[2563612,2563613,2563614,2563615],"Acacia Wood":[2563866,2563867,2563868,2563869,2563870,2563871],"Actinium":[2594197],"Activator Rail":[2564128,2564129,2564130,2564131,2564132,2564133,2564136,2564137,2564138,2564139,2564140,2564141],"Air":[2560016],"All Sided Mushroom Stem":[2564385],"Allium":[2564642],"Aluminum":[2594454],"Americium":[2594711],"Amethyst":[2698284],"Ancient Debris":[2698541],"Andesite":[2564899],"Andesite Slab":[2565156,2565157,2565158],"Andesite Stairs":[2565408,2565409,2565410,2565411,2565412,2565413,2565414,2565415],"Andesite Wall":[2565632,2565633,2565634,2565635,2565636,2565637,2565638,2565639,2565640,2565641,2565642,2565643,2565644,2565645,2565646,2565647,2565648,2565649,2565650,2565651,2565652,2565653,2565654,2565655,2565656,2565657,2565658,2565659,2565660,2565661,2565662,2565663,2565664,2565665,2565666,2565667,2565668,2565669,2565670,2565671,2565672,2565673,2565674,2565675,2565676,2565677,2565678,2565679,2565680,2565681,2565682,2565683,2565684,2565685,2565686,2565687,2565688,2565689,2565690,2565691,2565692,2565693,2565694,2565695,2565728,2565729,2565730,2565731,2565732,2565733,2565734,2565735,2565736,2565737,2565738,2565739,2565740,2565741,2565742,2565743,2565750,2565760,2565761,2565762,2565763,2565764,2565765,2565766,2565767,2565768,2565769,2565770,2565771,2565772,2565773,2565774,2565775,2565776,2565777,2565778,2565779,2565780,2565781,2565782,2565783,2565784,2565785,2565786,2565787,2565788,2565789,2565790,2565791,2565792,2565793,2565794,2565795,2565796,2565797,2565798,2565799,2565800,2565801,2565802,2565803,2565804,2565805,2565806,2565807,2565808,2565809,2565810,2565811,2565812,2565813,2565814,2565815,2565816,2565817,2565818,2565819,2565820,2565821,2565822,2565823,2565856,2565857,2565858,2565859,2565860,2565861,2565862,2565863,2565864,2565865,2565866,2565867,2565868,2565869,2565870,2565871,2565878],"Antimony":[2594968],"Anvil":[2565921,2565922,2565923,2565925,2565926,2565927,2565929,2565930,2565931,2565933,2565934,2565935],"Argon":[2595225],"Arsenic":[2595482],"Astatine":[2595739],"Azalea Leaves":[2735804,2735805,2735806,2735807],"Azure Bluet":[2566184],"Bamboo":[2566432,2566433,2566435,2566436,2566437,2566439,2566440,2566441,2566443,2566444,2566445,2566447],"Bamboo Sapling":[2566698,2566699],"Banner":[2566912,2566913,2566914,2566915,2566916,2566917,2566918,2566919,2566920,2566921,2566922,2566923,2566924,2566925,2566926,2566927,2566928,2566929,2566930,2566931,2566932,2566933,2566934,2566935,2566936,2566937,2566938,2566939,2566940,2566941,2566942,2566943,2566944,2566945,2566946,2566947,2566948,2566949,2566950,2566951,2566952,2566953,2566954,2566955,2566956,2566957,2566958,2566959,2566960,2566961,2566962,2566963,2566964,2566965,2566966,2566967,2566968,2566969,2566970,2566971,2566972,2566973,2566974,2566975,2566976,2566977,2566978,2566979,2566980,2566981,2566982,2566983,2566984,2566985,2566986,2566987,2566988,2566989,2566990,2566991,2566992,2566993,2566994,2566995,2566996,2566997,2566998,2566999,2567000,2567001,2567002,2567003,2567004,2567005,2567006,2567007,2567008,2567009,2567010,2567011,2567012,2567013,2567014,2567015,2567016,2567017,2567018,2567019,2567020,2567021,2567022,2567023,2567024,2567025,2567026,2567027,2567028,2567029,2567030,2567031,2567032,2567033,2567034,2567035,2567036,2567037,2567038,2567039,2567040,2567041,2567042,2567043,2567044,2567045,2567046,2567047,2567048,2567049,2567050,2567051,2567052,2567053,2567054,2567055,2567056,2567057,2567058,2567059,2567060,2567061,2567062,2567063,2567064,2567065,2567066,2567067,2567068,2567069,2567070,2567071,2567072,2567073,2567074,2567075,2567076,2567077,2567078,2567079,2567080,2567081,2567082,2567083,2567084,2567085,2567086,2567087,2567088,2567089,2567090,2567091,2567092,2567093,2567094,2567095,2567096,2567097,2567098,2567099,2567100,2567101,2567102,2567103,2567104,2567105,2567106,2567107,2567108,2567109,2567110,2567111,2567112,2567113,2567114,2567115,2567116,2567117,2567118,2567119,2567120,2567121,2567122,2567123,2567124,2567125,2567126,2567127,2567128,2567129,2567130,2567131,2567132,2567133,2567134,2567135,2567136,2567137,2567138,2567139,2567140,2567141,2567142,2567143,2567144,2567145,2567146,2567147,2567148,2567149,2567150,2567151,2567152,2567153,2567154,2567155,2567156,2567157,2567158,2567159,2567160,2567161,2567162,2567163,2567164,2567165,2567166,2567167],"Barium":[2595996],"Barrel":[2567200,2567201,2567204,2567205,2567206,2567207,2567208,2567209,2567212,2567213,2567214,2567215],"Barrier":[2567469],"Basalt":[2698796,2698798,2698799],"Beacon":[2567726],"Bed Block":[2567936,2567937,2567938,2567939,2567940,2567941,2567942,2567943,2567944,2567945,2567946,2567947,2567948,2567949,2567950,2567951,2567952,2567953,2567954,2567955,2567956,2567957,2567958,2567959,2567960,2567961,2567962,2567963,2567964,2567965,2567966,2567967,2567968,2567969,2567970,2567971,2567972,2567973,2567974,2567975,2567976,2567977,2567978,2567979,2567980,2567981,2567982,2567983,2567984,2567985,2567986,2567987,2567988,2567989,2567990,2567991,2567992,2567993,2567994,2567995,2567996,2567997,2567998,2567999,2568000,2568001,2568002,2568003,2568004,2568005,2568006,2568007,2568008,2568009,2568010,2568011,2568012,2568013,2568014,2568015,2568016,2568017,2568018,2568019,2568020,2568021,2568022,2568023,2568024,2568025,2568026,2568027,2568028,2568029,2568030,2568031,2568032,2568033,2568034,2568035,2568036,2568037,2568038,2568039,2568040,2568041,2568042,2568043,2568044,2568045,2568046,2568047,2568048,2568049,2568050,2568051,2568052,2568053,2568054,2568055,2568056,2568057,2568058,2568059,2568060,2568061,2568062,2568063,2568064,2568065,2568066,2568067,2568068,2568069,2568070,2568071,2568072,2568073,2568074,2568075,2568076,2568077,2568078,2568079,2568080,2568081,2568082,2568083,2568084,2568085,2568086,2568087,2568088,2568089,2568090,2568091,2568092,2568093,2568094,2568095,2568096,2568097,2568098,2568099,2568100,2568101,2568102,2568103,2568104,2568105,2568106,2568107,2568108,2568109,2568110,2568111,2568112,2568113,2568114,2568115,2568116,2568117,2568118,2568119,2568120,2568121,2568122,2568123,2568124,2568125,2568126,2568127,2568128,2568129,2568130,2568131,2568132,2568133,2568134,2568135,2568136,2568137,2568138,2568139,2568140,2568141,2568142,2568143,2568144,2568145,2568146,2568147,2568148,2568149,2568150,2568151,2568152,2568153,2568154,2568155,2568156,2568157,2568158,2568159,2568160,2568161,2568162,2568163,2568164,2568165,2568166,2568167,2568168,2568169,2568170,2568171,2568172,2568173,2568174,2568175,2568176,2568177,2568178,2568179,2568180,2568181,2568182,2568183,2568184,2568185,2568186,2568187,2568188,2568189,2568190,2568191],"Bedrock":[2568240,2568241],"Beetroot Block":[2568496,2568497,2568498,2568499,2568500,2568501,2568502,2568503],"Bell":[2568752,2568753,2568754,2568755,2568756,2568757,2568758,2568759,2568760,2568761,2568762,2568763,2568764,2568765,2568766,2568767],"Berkelium":[2596253],"Beryllium":[2596510],"Birch Button":[2569008,2569009,2569010,2569011,2569014,2569015,2569016,2569017,2569018,2569019,2569022,2569023],"Birch Door":[2569248,2569249,2569250,2569251,2569252,2569253,2569254,2569255,2569256,2569257,2569258,2569259,2569260,2569261,2569262,2569263,2569264,2569265,2569266,2569267,2569268,2569269,2569270,2569271,2569272,2569273,2569274,2569275,2569276,2569277,2569278,2569279],"Birch Fence":[2569525],"Birch Fence Gate":[2569776,2569777,2569778,2569779,2569780,2569781,2569782,2569783,2569784,2569785,2569786,2569787,2569788,2569789,2569790,2569791],"Birch Leaves":[2570036,2570037,2570038,2570039],"Birch Log":[2570296,2570297,2570298,2570299,2570300,2570301],"Birch Planks":[2570553],"Birch Pressure Plate":[2570810,2570811],"Birch Sapling":[2571066,2571067],"Birch Sign":[2571312,2571313,2571314,2571315,2571316,2571317,2571318,2571319,2571320,2571321,2571322,2571323,2571324,2571325,2571326,2571327],"Birch Slab":[2571580,2571581,2571583],"Birch Stairs":[2571832,2571833,2571834,2571835,2571836,2571837,2571838,2571839],"Birch Trapdoor":[2572080,2572081,2572082,2572083,2572084,2572085,2572086,2572087,2572088,2572089,2572090,2572091,2572092,2572093,2572094,2572095],"Birch Wall Sign":[2572352,2572353,2572354,2572355],"Birch Wood":[2572608,2572609,2572610,2572611,2572612,2572613],"Bismuth":[2596767],"Blackstone":[2699569],"Blackstone Slab":[2699824,2699826,2699827],"Blackstone Stairs":[2700080,2700081,2700082,2700083,2700084,2700085,2700086,2700087],"Blackstone Wall":[2700288,2700289,2700290,2700291,2700292,2700293,2700294,2700295,2700296,2700297,2700298,2700299,2700300,2700301,2700302,2700303,2700304,2700305,2700306,2700307,2700308,2700309,2700310,2700311,2700312,2700313,2700314,2700315,2700316,2700317,2700318,2700319,2700320,2700321,2700322,2700323,2700324,2700325,2700326,2700327,2700328,2700329,2700330,2700331,2700332,2700333,2700334,2700335,2700336,2700337,2700338,2700339,2700340,2700341,2700342,2700343,2700344,2700345,2700346,2700347,2700348,2700349,2700350,2700351,2700388,2700400,2700401,2700402,2700403,2700404,2700405,2700406,2700407,2700408,2700409,2700410,2700411,2700412,2700413,2700414,2700415,2700416,2700417,2700418,2700419,2700420,2700421,2700422,2700423,2700424,2700425,2700426,2700427,2700428,2700429,2700430,2700431,2700432,2700433,2700434,2700435,2700436,2700437,2700438,2700439,2700440,2700441,2700442,2700443,2700444,2700445,2700446,2700447,2700448,2700449,2700450,2700451,2700452,2700453,2700454,2700455,2700456,2700457,2700458,2700459,2700460,2700461,2700462,2700463,2700464,2700465,2700466,2700467,2700468,2700469,2700470,2700471,2700472,2700473,2700474,2700475,2700476,2700477,2700478,2700479,2700516,2700528,2700529,2700530,2700531,2700532,2700533,2700534,2700535,2700536,2700537,2700538,2700539,2700540,2700541,2700542,2700543],"Blast Furnace":[2573120,2573121,2573122,2573123,2573124,2573125,2573126,2573127],"Blue Ice":[2573637],"Blue Orchid":[2573894],"Blue Torch":[2574146,2574147,2574148,2574149,2574150],"Bohrium":[2597024],"Bone Block":[2574408,2574409,2574410],"Bookshelf":[2574665],"Boron":[2597281],"Brewing Stand":[2574920,2574921,2574922,2574923,2574924,2574925,2574926,2574927],"Brick Slab":[2575177,2575178,2575179],"Brick Stairs":[2575432,2575433,2575434,2575435,2575436,2575437,2575438,2575439],"Brick Wall":[2575616,2575617,2575618,2575619,2575620,2575621,2575622,2575623,2575624,2575625,2575626,2575627,2575628,2575629,2575630,2575631,2575645,2575680,2575681,2575682,2575683,2575684,2575685,2575686,2575687,2575688,2575689,2575690,2575691,2575692,2575693,2575694,2575695,2575696,2575697,2575698,2575699,2575700,2575701,2575702,2575703,2575704,2575705,2575706,2575707,2575708,2575709,2575710,2575711,2575712,2575713,2575714,2575715,2575716,2575717,2575718,2575719,2575720,2575721,2575722,2575723,2575724,2575725,2575726,2575727,2575728,2575729,2575730,2575731,2575732,2575733,2575734,2575735,2575736,2575737,2575738,2575739,2575740,2575741,2575742,2575743,2575744,2575745,2575746,2575747,2575748,2575749,2575750,2575751,2575752,2575753,2575754,2575755,2575756,2575757,2575758,2575759,2575773,2575808,2575809,2575810,2575811,2575812,2575813,2575814,2575815,2575816,2575817,2575818,2575819,2575820,2575821,2575822,2575823,2575824,2575825,2575826,2575827,2575828,2575829,2575830,2575831,2575832,2575833,2575834,2575835,2575836,2575837,2575838,2575839,2575840,2575841,2575842,2575843,2575844,2575845,2575846,2575847,2575848,2575849,2575850,2575851,2575852,2575853,2575854,2575855,2575856,2575857,2575858,2575859,2575860,2575861,2575862,2575863,2575864,2575865,2575866,2575867,2575868,2575869,2575870,2575871],"Bricks":[2575950],"Bromine":[2597538],"Brown Mushroom":[2576464],"Brown Mushroom Block":[2576720,2576721,2576722,2576723,2576724,2576725,2576726,2576727,2576728,2576729,2576731],"Cactus":[2576976,2576977,2576978,2576979,2576980,2576981,2576982,2576983,2576984,2576985,2576986,2576987,2576988,2576989,2576990,2576991],"Cadmium":[2597795],"Cake":[2577232,2577233,2577234,2577235,2577237,2577238,2577239],"Cake With Candle":[2729638,2729639],"Cake With Dyed Candle":[2729888,2729889,2729890,2729891,2729892,2729893,2729894,2729895,2729896,2729897,2729898,2729899,2729900,2729901,2729902,2729903,2729904,2729905,2729906,2729907,2729908,2729909,2729910,2729911,2729912,2729913,2729914,2729915,2729916,2729917,2729918,2729919],"Calcite":[2704709],"Calcium":[2598052],"Californium":[2598309],"Candle":[2729120,2729121,2729122,2729123,2729124,2729125,2729126,2729127],"Carbon":[2598566],"Carpet":[2577488,2577489,2577490,2577491,2577492,2577493,2577494,2577495,2577496,2577497,2577498,2577499,2577500,2577501,2577502,2577503],"Carrot Block":[2577744,2577745,2577746,2577747,2577748,2577749,2577750,2577751],"Cartography Table":[2730666],"Carved Pumpkin":[2578004,2578005,2578006,2578007],"Cauldron":[2731694],"Cave Vines":[2736512,2736513,2736514,2736515,2736516,2736517,2736518,2736519,2736520,2736521,2736522,2736523,2736524,2736525,2736526,2736527,2736528,2736529,2736530,2736531,2736532,2736533,2736534,2736535,2736536,2736537,2736544,2736545,2736546,2736547,2736548,2736549,2736550,2736551,2736552,2736553,2736554,2736555,2736556,2736557,2736558,2736559,2736560,2736561,2736562,2736563,2736564,2736565,2736566,2736567,2736568,2736569,2736576,2736577,2736578,2736579,2736580,2736581,2736582,2736583,2736584,2736585,2736586,2736587,2736588,2736589,2736590,2736591,2736592,2736593,2736594,2736595,2736596,2736597,2736598,2736599,2736600,2736601,2736608,2736609,2736610,2736611,2736612,2736613,2736614,2736615,2736616,2736617,2736618,2736619,2736620,2736621,2736622,2736623,2736624,2736625,2736626,2736627,2736628,2736629,2736630,2736631,2736632,2736633],"Cerium":[2598823],"Cesium":[2599080],"Chain":[2734776,2734778,2734779],"Cherry Button":[2737088,2737089,2737090,2737091,2737094,2737095,2737096,2737097,2737098,2737099,2737102,2737103],"Cherry Door":[2737344,2737345,2737346,2737347,2737348,2737349,2737350,2737351,2737352,2737353,2737354,2737355,2737356,2737357,2737358,2737359,2737360,2737361,2737362,2737363,2737364,2737365,2737366,2737367,2737368,2737369,2737370,2737371,2737372,2737373,2737374,2737375],"Cherry Fence":[2737605],"Cherry Fence Gate":[2737856,2737857,2737858,2737859,2737860,2737861,2737862,2737863,2737864,2737865,2737866,2737867,2737868,2737869,2737870,2737871],"Cherry Leaves":[2738116,2738117,2738118,2738119],"Cherry Log":[2738376,2738377,2738378,2738379,2738380,2738381],"Cherry Planks":[2738633],"Cherry Pressure Plate":[2738890,2738891],"Cherry Sign":[2739392,2739393,2739394,2739395,2739396,2739397,2739398,2739399,2739400,2739401,2739402,2739403,2739404,2739405,2739406,2739407],"Cherry Slab":[2739660,2739661,2739663],"Cherry Stairs":[2739912,2739913,2739914,2739915,2739916,2739917,2739918,2739919],"Cherry Trapdoor":[2740160,2740161,2740162,2740163,2740164,2740165,2740166,2740167,2740168,2740169,2740170,2740171,2740172,2740173,2740174,2740175],"Cherry Wall Sign":[2740432,2740433,2740434,2740435],"Cherry Wood":[2740688,2740689,2740690,2740691,2740692,2740693],"Chest":[2578520,2578521,2578522,2578523],"Chiseled Deepslate":[2710106],"Chiseled Nether Bricks":[2710363],"Chiseled Polished Blackstone":[2702139],"Chiseled Quartz Block":[2578776,2578777,2578779],"Chiseled Red Sandstone":[2579034],"Chiseled Sandstone":[2579291],"Chiseled Stone Bricks":[2579548],"Chlorine":[2599337],"Chorus Flower":[2732976,2732977,2732978,2732979,2732982,2732983],"Chorus Plant":[2733236],"Chromium":[2599594],"Clay Block":[2579805],"Coal Block":[2580062],"Coal Ore":[2580319],"Cobalt":[2599851],"Cobbled Deepslate":[2707793],"Cobbled Deepslate Slab":[2708048,2708050,2708051],"Cobbled Deepslate Stairs":[2708304,2708305,2708306,2708307,2708308,2708309,2708310,2708311],"Cobbled Deepslate Wall":[2708484,2708496,2708497,2708498,2708499,2708500,2708501,2708502,2708503,2708504,2708505,2708506,2708507,2708508,2708509,2708510,2708511,2708544,2708545,2708546,2708547,2708548,2708549,2708550,2708551,2708552,2708553,2708554,2708555,2708556,2708557,2708558,2708559,2708560,2708561,2708562,2708563,2708564,2708565,2708566,2708567,2708568,2708569,2708570,2708571,2708572,2708573,2708574,2708575,2708576,2708577,2708578,2708579,2708580,2708581,2708582,2708583,2708584,2708585,2708586,2708587,2708588,2708589,2708590,2708591,2708592,2708593,2708594,2708595,2708596,2708597,2708598,2708599,2708600,2708601,2708602,2708603,2708604,2708605,2708606,2708607,2708612,2708624,2708625,2708626,2708627,2708628,2708629,2708630,2708631,2708632,2708633,2708634,2708635,2708636,2708637,2708638,2708639,2708672,2708673,2708674,2708675,2708676,2708677,2708678,2708679,2708680,2708681,2708682,2708683,2708684,2708685,2708686,2708687,2708688,2708689,2708690,2708691,2708692,2708693,2708694,2708695,2708696,2708697,2708698,2708699,2708700,2708701,2708702,2708703,2708704,2708705,2708706,2708707,2708708,2708709,2708710,2708711,2708712,2708713,2708714,2708715,2708716,2708717,2708718,2708719,2708720,2708721,2708722,2708723,2708724,2708725,2708726,2708727,2708728,2708729,2708730,2708731,2708732,2708733,2708734,2708735],"Cobblestone":[2580576],"Cobblestone Slab":[2580832,2580833,2580835],"Cobblestone Stairs":[2581088,2581089,2581090,2581091,2581092,2581093,2581094,2581095],"Cobblestone Wall":[2581280,2581281,2581282,2581283,2581284,2581285,2581286,2581287,2581288,2581289,2581290,2581291,2581292,2581293,2581294,2581295,2581299,2581312,2581313,2581314,2581315,2581316,2581317,2581318,2581319,2581320,2581321,2581322,2581323,2581324,2581325,2581326,2581327,2581328,2581329,2581330,2581331,2581332,2581333,2581334,2581335,2581336,2581337,2581338,2581339,2581340,2581341,2581342,2581343,2581344,2581345,2581346,2581347,2581348,2581349,2581350,2581351,2581352,2581353,2581354,2581355,2581356,2581357,2581358,2581359,2581360,2581361,2581362,2581363,2581364,2581365,2581366,2581367,2581368,2581369,2581370,2581371,2581372,2581373,2581374,2581375,2581408,2581409,2581410,2581411,2581412,2581413,2581414,2581415,2581416,2581417,2581418,2581419,2581420,2581421,2581422,2581423,2581427,2581440,2581441,2581442,2581443,2581444,2581445,2581446,2581447,2581448,2581449,2581450,2581451,2581452,2581453,2581454,2581455,2581456,2581457,2581458,2581459,2581460,2581461,2581462,2581463,2581464,2581465,2581466,2581467,2581468,2581469,2581470,2581471,2581472,2581473,2581474,2581475,2581476,2581477,2581478,2581479,2581480,2581481,2581482,2581483,2581484,2581485,2581486,2581487,2581488,2581489,2581490,2581491,2581492,2581493,2581494,2581495,2581496,2581497,2581498,2581499,2581500,2581501,2581502,2581503],"Cobweb":[2581604],"Cocoa Block":[2581856,2581857,2581858,2581859,2581860,2581861,2581862,2581863,2581868,2581869,2581870,2581871],"Compound Creator":[2582116,2582117,2582118,2582119],"Concrete":[2582368,2582369,2582370,2582371,2582372,2582373,2582374,2582375,2582376,2582377,2582378,2582379,2582380,2582381,2582382,2582383],"Concrete Powder":[2582624,2582625,2582626,2582627,2582628,2582629,2582630,2582631,2582632,2582633,2582634,2582635,2582636,2582637,2582638,2582639],"Copernicium":[2600365],"Copper":[2600622],"Copper Block":[2728096,2728097,2728098,2728099,2728100,2728101,2728102,2728103],"Copper Ore":[2725012],"Coral":[2582880,2582881,2582882,2582883,2582885,2582888,2582889,2582890,2582891,2582893],"Coral Block":[2583136,2583137,2583138,2583139,2583142,2583144,2583145,2583146,2583147,2583150],"Coral Fan":[2583392,2583393,2583394,2583395,2583399,2583400,2583401,2583402,2583403,2583407,2583408,2583409,2583410,2583411,2583415,2583416,2583417,2583418,2583419,2583423],"Cornflower":[2583660],"Cracked Deepslate Bricks":[2706251],"Cracked Deepslate Tiles":[2707536],"Cracked Nether Bricks":[2710620],"Cracked Polished Blackstone Bricks":[2703424],"Cracked Stone Bricks":[2583917],"Crafting Table":[2584174],"Crimson Button":[2717298,2717299,2717300,2717301,2717302,2717303,2717306,2717307,2717308,2717309,2717310,2717311],"Crimson Door":[2718816,2718817,2718818,2718819,2718820,2718821,2718822,2718823,2718824,2718825,2718826,2718827,2718828,2718829,2718830,2718831,2718832,2718833,2718834,2718835,2718836,2718837,2718838,2718839,2718840,2718841,2718842,2718843,2718844,2718845,2718846,2718847],"Crimson Fence":[2713447],"Crimson Fence Gate":[2719600,2719601,2719602,2719603,2719604,2719605,2719606,2719607,2719608,2719609,2719610,2719611,2719612,2719613,2719614,2719615],"Crimson Hyphae":[2715760,2715761,2715762,2715763,2715764,2715765],"Crimson Planks":[2712676],"Crimson Pressure Plate":[2718072,2718073],"Crimson Sign":[2721152,2721153,2721154,2721155,2721156,2721157,2721158,2721159,2721160,2721161,2721162,2721163,2721164,2721165,2721166,2721167],"Crimson Slab":[2714216,2714218,2714219],"Crimson Stairs":[2720384,2720385,2720386,2720387,2720388,2720389,2720390,2720391],"Crimson Stem":[2714984,2714985,2714988,2714989,2714990,2714991],"Crimson Trapdoor":[2716528,2716529,2716530,2716531,2716532,2716533,2716534,2716535,2716536,2716537,2716538,2716539,2716540,2716541,2716542,2716543],"Crimson Wall Sign":[2721928,2721929,2721930,2721931],"Crying Obsidian":[2727325],"Curium":[2600879],"Cut Copper Block":[2728352,2728353,2728354,2728355,2728356,2728357,2728358,2728359],"Cut Copper Slab Slab":[2728608,2728609,2728610,2728611,2728612,2728613,2728614,2728615,2728616,2728617,2728618,2728619,2728620,2728621,2728622,2728623,2728624,2728625,2728626,2728627,2728628,2728629,2728630,2728631],"Cut Copper Stairs":[2728832,2728833,2728834,2728835,2728836,2728837,2728838,2728839,2728840,2728841,2728842,2728843,2728844,2728845,2728846,2728847,2728848,2728849,2728850,2728851,2728852,2728853,2728854,2728855,2728856,2728857,2728858,2728859,2728860,2728861,2728862,2728863,2728864,2728865,2728866,2728867,2728868,2728869,2728870,2728871,2728872,2728873,2728874,2728875,2728876,2728877,2728878,2728879,2728880,2728881,2728882,2728883,2728884,2728885,2728886,2728887,2728888,2728889,2728890,2728891,2728892,2728893,2728894,2728895],"Cut Red Sandstone":[2584431],"Cut Red Sandstone Slab":[2584688,2584689,2584690],"Cut Sandstone":[2584945],"Cut Sandstone Slab":[2585200,2585202,2585203],"Dandelion":[2585716],"Dark Oak Button":[2585968,2585969,2585972,2585973,2585974,2585975,2585976,2585977,2585980,2585981,2585982,2585983],"Dark Oak Door":[2586208,2586209,2586210,2586211,2586212,2586213,2586214,2586215,2586216,2586217,2586218,2586219,2586220,2586221,2586222,2586223,2586224,2586225,2586226,2586227,2586228,2586229,2586230,2586231,2586232,2586233,2586234,2586235,2586236,2586237,2586238,2586239],"Dark Oak Fence":[2586487],"Dark Oak Fence Gate":[2586736,2586737,2586738,2586739,2586740,2586741,2586742,2586743,2586744,2586745,2586746,2586747,2586748,2586749,2586750,2586751],"Dark Oak Leaves":[2587000,2587001,2587002,2587003],"Dark Oak Log":[2587256,2587257,2587258,2587259,2587262,2587263],"Dark Oak Planks":[2587515],"Dark Oak Pressure Plate":[2587772,2587773],"Dark Oak Sapling":[2588028,2588029],"Dark Oak Sign":[2588272,2588273,2588274,2588275,2588276,2588277,2588278,2588279,2588280,2588281,2588282,2588283,2588284,2588285,2588286,2588287],"Dark Oak Slab":[2588541,2588542,2588543],"Dark Oak Stairs":[2588800,2588801,2588802,2588803,2588804,2588805,2588806,2588807],"Dark Oak Trapdoor":[2589056,2589057,2589058,2589059,2589060,2589061,2589062,2589063,2589064,2589065,2589066,2589067,2589068,2589069,2589070,2589071],"Dark Oak Wall Sign":[2589312,2589313,2589314,2589315],"Dark Oak Wood":[2589568,2589569,2589570,2589571,2589574,2589575],"Dark Prismarine":[2589828],"Dark Prismarine Slab":[2590084,2590085,2590087],"Dark Prismarine Stairs":[2590336,2590337,2590338,2590339,2590340,2590341,2590342,2590343],"Darmstadtium":[2601136],"Daylight Sensor":[2590592,2590593,2590594,2590595,2590596,2590597,2590598,2590599,2590600,2590601,2590602,2590603,2590604,2590605,2590606,2590607,2590608,2590609,2590610,2590611,2590612,2590613,2590614,2590615,2590616,2590617,2590618,2590619,2590620,2590621,2590622,2590623],"Dead Bush":[2590856],"Deepslate":[2704964,2704966,2704967],"Deepslate Brick Slab":[2705480,2705481,2705482],"Deepslate Brick Stairs":[2705736,2705737,2705738,2705739,2705740,2705741,2705742,2705743],"Deepslate Brick Wall":[2705920,2705921,2705922,2705923,2705924,2705925,2705926,2705927,2705928,2705929,2705930,2705931,2705932,2705933,2705934,2705935,2705946,2705984,2705985,2705986,2705987,2705988,2705989,2705990,2705991,2705992,2705993,2705994,2705995,2705996,2705997,2705998,2705999,2706000,2706001,2706002,2706003,2706004,2706005,2706006,2706007,2706008,2706009,2706010,2706011,2706012,2706013,2706014,2706015,2706016,2706017,2706018,2706019,2706020,2706021,2706022,2706023,2706024,2706025,2706026,2706027,2706028,2706029,2706030,2706031,2706032,2706033,2706034,2706035,2706036,2706037,2706038,2706039,2706040,2706041,2706042,2706043,2706044,2706045,2706046,2706047,2706048,2706049,2706050,2706051,2706052,2706053,2706054,2706055,2706056,2706057,2706058,2706059,2706060,2706061,2706062,2706063,2706074,2706112,2706113,2706114,2706115,2706116,2706117,2706118,2706119,2706120,2706121,2706122,2706123,2706124,2706125,2706126,2706127,2706128,2706129,2706130,2706131,2706132,2706133,2706134,2706135,2706136,2706137,2706138,2706139,2706140,2706141,2706142,2706143,2706144,2706145,2706146,2706147,2706148,2706149,2706150,2706151,2706152,2706153,2706154,2706155,2706156,2706157,2706158,2706159,2706160,2706161,2706162,2706163,2706164,2706165,2706166,2706167,2706168,2706169,2706170,2706171,2706172,2706173,2706174,2706175],"Deepslate Bricks":[2705223],"Deepslate Coal Ore":[2722956],"Deepslate Copper Ore":[2724755],"Deepslate Diamond Ore":[2723213],"Deepslate Emerald Ore":[2723470],"Deepslate Gold Ore":[2724498],"Deepslate Iron Ore":[2724241],"Deepslate Lapis Lazuli Ore":[2723727],"Deepslate Redstone Ore":[2723984,2723985],"Deepslate Tile Slab":[2706764,2706765,2706767],"Deepslate Tile Stairs":[2707016,2707017,2707018,2707019,2707020,2707021,2707022,2707023],"Deepslate Tile Wall":[2707200,2707201,2707202,2707203,2707204,2707205,2707206,2707207,2707208,2707209,2707210,2707211,2707212,2707213,2707214,2707215,2707231,2707264,2707265,2707266,2707267,2707268,2707269,2707270,2707271,2707272,2707273,2707274,2707275,2707276,2707277,2707278,2707279,2707280,2707281,2707282,2707283,2707284,2707285,2707286,2707287,2707288,2707289,2707290,2707291,2707292,2707293,2707294,2707295,2707296,2707297,2707298,2707299,2707300,2707301,2707302,2707303,2707304,2707305,2707306,2707307,2707308,2707309,2707310,2707311,2707312,2707313,2707314,2707315,2707316,2707317,2707318,2707319,2707320,2707321,2707322,2707323,2707324,2707325,2707326,2707327,2707328,2707329,2707330,2707331,2707332,2707333,2707334,2707335,2707336,2707337,2707338,2707339,2707340,2707341,2707342,2707343,2707359,2707392,2707393,2707394,2707395,2707396,2707397,2707398,2707399,2707400,2707401,2707402,2707403,2707404,2707405,2707406,2707407,2707408,2707409,2707410,2707411,2707412,2707413,2707414,2707415,2707416,2707417,2707418,2707419,2707420,2707421,2707422,2707423,2707424,2707425,2707426,2707427,2707428,2707429,2707430,2707431,2707432,2707433,2707434,2707435,2707436,2707437,2707438,2707439,2707440,2707441,2707442,2707443,2707444,2707445,2707446,2707447,2707448,2707449,2707450,2707451,2707452,2707453,2707454,2707455],"Deepslate Tiles":[2706508],"Detector Rail":[2591104,2591105,2591106,2591107,2591108,2591109,2591112,2591113,2591114,2591115,2591116,2591117],"Diamond Block":[2591370],"Diamond Ore":[2591627],"Diorite":[2591884],"Diorite Slab":[2592140,2592141,2592143],"Diorite Stairs":[2592392,2592393,2592394,2592395,2592396,2592397,2592398,2592399],"Diorite Wall":[2592512,2592513,2592514,2592515,2592516,2592517,2592518,2592519,2592520,2592521,2592522,2592523,2592524,2592525,2592526,2592527,2592528,2592529,2592530,2592531,2592532,2592533,2592534,2592535,2592536,2592537,2592538,2592539,2592540,2592541,2592542,2592543,2592544,2592545,2592546,2592547,2592548,2592549,2592550,2592551,2592552,2592553,2592554,2592555,2592556,2592557,2592558,2592559,2592560,2592561,2592562,2592563,2592564,2592565,2592566,2592567,2592568,2592569,2592570,2592571,2592572,2592573,2592574,2592575,2592576,2592577,2592578,2592579,2592580,2592581,2592582,2592583,2592584,2592585,2592586,2592587,2592588,2592589,2592590,2592591,2592607,2592640,2592641,2592642,2592643,2592644,2592645,2592646,2592647,2592648,2592649,2592650,2592651,2592652,2592653,2592654,2592655,2592656,2592657,2592658,2592659,2592660,2592661,2592662,2592663,2592664,2592665,2592666,2592667,2592668,2592669,2592670,2592671,2592672,2592673,2592674,2592675,2592676,2592677,2592678,2592679,2592680,2592681,2592682,2592683,2592684,2592685,2592686,2592687,2592688,2592689,2592690,2592691,2592692,2592693,2592694,2592695,2592696,2592697,2592698,2592699,2592700,2592701,2592702,2592703,2592704,2592705,2592706,2592707,2592708,2592709,2592710,2592711,2592712,2592713,2592714,2592715,2592716,2592717,2592718,2592719,2592735],"Dirt":[2592912,2592913,2592914],"Double Tallgrass":[2593168,2593169],"Dragon Egg":[2593426],"Dried Kelp Block":[2593683],"Dubnium":[2601393],"Dyed Candle":[2729344,2729345,2729346,2729347,2729348,2729349,2729350,2729351,2729352,2729353,2729354,2729355,2729356,2729357,2729358,2729359,2729360,2729361,2729362,2729363,2729364,2729365,2729366,2729367,2729368,2729369,2729370,2729371,2729372,2729373,2729374,2729375,2729376,2729377,2729378,2729379,2729380,2729381,2729382,2729383,2729384,2729385,2729386,2729387,2729388,2729389,2729390,2729391,2729392,2729393,2729394,2729395,2729396,2729397,2729398,2729399,2729400,2729401,2729402,2729403,2729404,2729405,2729406,2729407,2729408,2729409,2729410,2729411,2729412,2729413,2729414,2729415,2729416,2729417,2729418,2729419,2729420,2729421,2729422,2729423,2729424,2729425,2729426,2729427,2729428,2729429,2729430,2729431,2729432,2729433,2729434,2729435,2729436,2729437,2729438,2729439,2729440,2729441,2729442,2729443,2729444,2729445,2729446,2729447,2729448,2729449,2729450,2729451,2729452,2729453,2729454,2729455,2729456,2729457,2729458,2729459,2729460,2729461,2729462,2729463,2729464,2729465,2729466,2729467,2729468,2729469,2729470,2729471],"Dyed Shulker Box":[2593936,2593937,2593938,2593939,2593940,2593941,2593942,2593943,2593944,2593945,2593946,2593947,2593948,2593949,2593950,2593951],"Dysprosium":[2601650],"Einsteinium":[2601907],"Element Constructor":[2600108,2600109,2600110,2600111],"Emerald Block":[2624781],"Emerald Ore":[2625038],"Enchanting Table":[2625295],"End Portal Frame":[2625552,2625553,2625554,2625555,2625556,2625557,2625558,2625559],"End Rod":[2625808,2625809,2625810,2625811,2625812,2625813],"End Stone":[2626066],"End Stone Brick Slab":[2626321,2626322,2626323],"End Stone Brick Stairs":[2626576,2626577,2626578,2626579,2626580,2626581,2626582,2626583],"End Stone Brick Wall":[2626816,2626817,2626818,2626819,2626820,2626821,2626822,2626823,2626824,2626825,2626826,2626827,2626828,2626829,2626830,2626831,2626832,2626833,2626834,2626835,2626836,2626837,2626838,2626839,2626840,2626841,2626842,2626843,2626844,2626845,2626846,2626847,2626848,2626849,2626850,2626851,2626852,2626853,2626854,2626855,2626856,2626857,2626858,2626859,2626860,2626861,2626862,2626863,2626864,2626865,2626866,2626867,2626868,2626869,2626870,2626871,2626872,2626873,2626874,2626875,2626876,2626877,2626878,2626879,2626885,2626896,2626897,2626898,2626899,2626900,2626901,2626902,2626903,2626904,2626905,2626906,2626907,2626908,2626909,2626910,2626911,2626944,2626945,2626946,2626947,2626948,2626949,2626950,2626951,2626952,2626953,2626954,2626955,2626956,2626957,2626958,2626959,2626960,2626961,2626962,2626963,2626964,2626965,2626966,2626967,2626968,2626969,2626970,2626971,2626972,2626973,2626974,2626975,2626976,2626977,2626978,2626979,2626980,2626981,2626982,2626983,2626984,2626985,2626986,2626987,2626988,2626989,2626990,2626991,2626992,2626993,2626994,2626995,2626996,2626997,2626998,2626999,2627000,2627001,2627002,2627003,2627004,2627005,2627006,2627007,2627013,2627024,2627025,2627026,2627027,2627028,2627029,2627030,2627031,2627032,2627033,2627034,2627035,2627036,2627037,2627038,2627039],"End Stone Bricks":[2627094],"Ender Chest":[2627348,2627349,2627350,2627351],"Erbium":[2602164],"Europium":[2602421],"Fake Wooden Slab":[2627608,2627609,2627610],"Farmland":[2627864,2627865,2627866,2627867,2627868,2627869,2627870,2627871],"Fermium":[2602678],"Fern":[2628122],"Fire Block":[2628368,2628369,2628370,2628371,2628372,2628373,2628374,2628375,2628376,2628377,2628378,2628379,2628380,2628381,2628382,2628383],"Flerovium":[2602935],"Fletching Table":[2628636],"Flower Pot":[2628893],"Flowering Azalea Leaves":[2736060,2736061,2736062,2736063],"Fluorine":[2603192],"Francium":[2603449],"Froglight":[2734001,2734002,2734003,2734005,2734006,2734007,2734013,2734014,2734015],"Frosted Ice":[2629148,2629149,2629150,2629151],"Furnace":[2629400,2629401,2629402,2629403,2629404,2629405,2629406,2629407],"Gadolinium":[2603706],"Gallium":[2603963],"Germanium":[2604220],"Gilded Blackstone":[2727582],"Glass":[2629664],"Glass Pane":[2629921],"Glazed Terracotta":[2697984,2697985,2697986,2697987,2697988,2697989,2697990,2697991,2697992,2697993,2697994,2697995,2697996,2697997,2697998,2697999,2698000,2698001,2698002,2698003,2698004,2698005,2698006,2698007,2698008,2698009,2698010,2698011,2698012,2698013,2698014,2698015,2698016,2698017,2698018,2698019,2698020,2698021,2698022,2698023,2698024,2698025,2698026,2698027,2698028,2698029,2698030,2698031,2698032,2698033,2698034,2698035,2698036,2698037,2698038,2698039,2698040,2698041,2698042,2698043,2698044,2698045,2698046,2698047],"Glow Item Frame":[2735280,2735281,2735284,2735285,2735286,2735287,2735288,2735289,2735292,2735293,2735294,2735295],"Glow Lichen":[2736832,2736833,2736834,2736835,2736836,2736837,2736838,2736839,2736840,2736841,2736842,2736843,2736844,2736845,2736846,2736847,2736848,2736849,2736850,2736851,2736852,2736853,2736854,2736855,2736856,2736857,2736858,2736859,2736860,2736861,2736862,2736863,2736864,2736865,2736866,2736867,2736868,2736869,2736870,2736871,2736872,2736873,2736874,2736875,2736876,2736877,2736878,2736879,2736880,2736881,2736882,2736883,2736884,2736885,2736886,2736887,2736888,2736889,2736890,2736891,2736892,2736893,2736894,2736895],"Glowing Obsidian":[2630178],"Glowstone":[2630435],"Gold":[2604477],"Gold Block":[2630692],"Gold Ore":[2630949],"Granite":[2631206],"Granite Slab":[2631461,2631462,2631463],"Granite Stairs":[2631720,2631721,2631722,2631723,2631724,2631725,2631726,2631727],"Granite Wall":[2631936,2631937,2631938,2631939,2631940,2631941,2631942,2631943,2631944,2631945,2631946,2631947,2631948,2631949,2631950,2631951,2631952,2631953,2631954,2631955,2631956,2631957,2631958,2631959,2631960,2631961,2631962,2631963,2631964,2631965,2631966,2631967,2631968,2631969,2631970,2631971,2631972,2631973,2631974,2631975,2631976,2631977,2631978,2631979,2631980,2631981,2631982,2631983,2631984,2631985,2631986,2631987,2631988,2631989,2631990,2631991,2631992,2631993,2631994,2631995,2631996,2631997,2631998,2631999,2632032,2632033,2632034,2632035,2632036,2632037,2632038,2632039,2632040,2632041,2632042,2632043,2632044,2632045,2632046,2632047,2632057,2632064,2632065,2632066,2632067,2632068,2632069,2632070,2632071,2632072,2632073,2632074,2632075,2632076,2632077,2632078,2632079,2632080,2632081,2632082,2632083,2632084,2632085,2632086,2632087,2632088,2632089,2632090,2632091,2632092,2632093,2632094,2632095,2632096,2632097,2632098,2632099,2632100,2632101,2632102,2632103,2632104,2632105,2632106,2632107,2632108,2632109,2632110,2632111,2632112,2632113,2632114,2632115,2632116,2632117,2632118,2632119,2632120,2632121,2632122,2632123,2632124,2632125,2632126,2632127,2632160,2632161,2632162,2632163,2632164,2632165,2632166,2632167,2632168,2632169,2632170,2632171,2632172,2632173,2632174,2632175,2632185],"Grass":[2632234],"Grass Path":[2632491],"Gravel":[2632748],"Green Torch":[2633514,2633515,2633516,2633517,2633518],"Hafnium":[2604734],"Hanging Roots":[2730409],"Hardened Clay":[2633776],"Hardened Glass":[2634033],"Hardened Glass Pane":[2634290],"Hassium":[2604991],"Hay Bale":[2634545,2634546,2634547],"Heat Block":[2578263],"Helium":[2605248],"Holmium":[2605505],"Honeycomb Block":[2722699],"Hopper":[2634800,2634801,2634804,2634806,2634807,2634808,2634809,2634812,2634814,2634815],"Hydrogen":[2605762],"Ice":[2635061],"Indium":[2606019],"Infested Chiseled Stone Brick":[2635318],"Infested Cobblestone":[2635575],"Infested Cracked Stone Brick":[2635832],"Infested Mossy Stone Brick":[2636089],"Infested Stone":[2636346],"Infested Stone Brick":[2636603],"Invisible Bedrock":[2637374],"Iodine":[2606276],"Iridium":[2606533],"Iron":[2606790],"Iron Bars":[2637888],"Iron Block":[2637631],"Iron Door":[2638144,2638145,2638146,2638147,2638148,2638149,2638150,2638151,2638152,2638153,2638154,2638155,2638156,2638157,2638158,2638159,2638160,2638161,2638162,2638163,2638164,2638165,2638166,2638167,2638168,2638169,2638170,2638171,2638172,2638173,2638174,2638175],"Iron Ore":[2638402],"Iron Trapdoor":[2638656,2638657,2638658,2638659,2638660,2638661,2638662,2638663,2638664,2638665,2638666,2638667,2638668,2638669,2638670,2638671],"Item Frame":[2638912,2638913,2638916,2638917,2638918,2638919,2638920,2638921,2638924,2638925,2638926,2638927],"Jack o'Lantern":[2647396,2647397,2647398,2647399],"Jukebox":[2639173],"Jungle Button":[2639426,2639427,2639428,2639429,2639430,2639431,2639434,2639435,2639436,2639437,2639438,2639439],"Jungle Door":[2639680,2639681,2639682,2639683,2639684,2639685,2639686,2639687,2639688,2639689,2639690,2639691,2639692,2639693,2639694,2639695,2639696,2639697,2639698,2639699,2639700,2639701,2639702,2639703,2639704,2639705,2639706,2639707,2639708,2639709,2639710,2639711],"Jungle Fence":[2639944],"Jungle Fence Gate":[2640192,2640193,2640194,2640195,2640196,2640197,2640198,2640199,2640200,2640201,2640202,2640203,2640204,2640205,2640206,2640207],"Jungle Leaves":[2640456,2640457,2640458,2640459],"Jungle Log":[2640712,2640713,2640714,2640715,2640718,2640719],"Jungle Planks":[2640972],"Jungle Pressure Plate":[2641228,2641229],"Jungle Sapling":[2641486,2641487],"Jungle Sign":[2641728,2641729,2641730,2641731,2641732,2641733,2641734,2641735,2641736,2641737,2641738,2641739,2641740,2641741,2641742,2641743],"Jungle Slab":[2642000,2642001,2642002],"Jungle Stairs":[2642256,2642257,2642258,2642259,2642260,2642261,2642262,2642263],"Jungle Trapdoor":[2642512,2642513,2642514,2642515,2642516,2642517,2642518,2642519,2642520,2642521,2642522,2642523,2642524,2642525,2642526,2642527],"Jungle Wall Sign":[2642768,2642769,2642770,2642771],"Jungle Wood":[2643024,2643025,2643028,2643029,2643030,2643031],"Krypton":[2607047],"Lab Table":[2643284,2643285,2643286,2643287],"Ladder":[2643540,2643541,2643542,2643543],"Lantern":[2643798,2643799],"Lanthanum":[2607304],"Lapis Lazuli Block":[2644056],"Lapis Lazuli Ore":[2644313],"Large Fern":[2644570,2644571],"Lava":[2644800,2644801,2644802,2644803,2644804,2644805,2644806,2644807,2644808,2644809,2644810,2644811,2644812,2644813,2644814,2644815,2644816,2644817,2644818,2644819,2644820,2644821,2644822,2644823,2644824,2644825,2644826,2644827,2644828,2644829,2644830,2644831],"Lava Cauldron":[2732208,2732209,2732210,2732211,2732212,2732213],"Lawrencium":[2607561],"Lead":[2607818],"Lectern":[2645080,2645081,2645082,2645083,2645084,2645085,2645086,2645087],"Legacy Stonecutter":[2645341],"Lever":[2645584,2645585,2645586,2645587,2645588,2645589,2645590,2645591,2645592,2645593,2645594,2645595,2645596,2645597,2645598,2645599],"Light Block":[2703680,2703681,2703682,2703683,2703684,2703685,2703686,2703687,2703688,2703689,2703690,2703691,2703692,2703693,2703694,2703695],"Lightning Rod":[2727834,2727835,2727836,2727837,2727838,2727839],"Lilac":[2646368,2646369],"Lily Pad":[2646883],"Lily of the Valley":[2646626],"Lithium":[2608075],"Livermorium":[2608332],"Loom":[2647652,2647653,2647654,2647655],"Lutetium":[2608589],"Magma Block":[2648168],"Magnesium":[2608846],"Manganese":[2609103],"Mangrove Button":[2717040,2717041,2717044,2717045,2717046,2717047,2717048,2717049,2717052,2717053,2717054,2717055],"Mangrove Door":[2718560,2718561,2718562,2718563,2718564,2718565,2718566,2718567,2718568,2718569,2718570,2718571,2718572,2718573,2718574,2718575,2718576,2718577,2718578,2718579,2718580,2718581,2718582,2718583,2718584,2718585,2718586,2718587,2718588,2718589,2718590,2718591],"Mangrove Fence":[2713190],"Mangrove Fence Gate":[2719344,2719345,2719346,2719347,2719348,2719349,2719350,2719351,2719352,2719353,2719354,2719355,2719356,2719357,2719358,2719359],"Mangrove Leaves":[2735548,2735549,2735550,2735551],"Mangrove Log":[2714728,2714729,2714732,2714733,2714734,2714735],"Mangrove Planks":[2712419],"Mangrove Pressure Plate":[2717816,2717817],"Mangrove Roots":[2733493],"Mangrove Sign":[2720896,2720897,2720898,2720899,2720900,2720901,2720902,2720903,2720904,2720905,2720906,2720907,2720908,2720909,2720910,2720911],"Mangrove Slab":[2713960,2713961,2713963],"Mangrove Stairs":[2720128,2720129,2720130,2720131,2720132,2720133,2720134,2720135],"Mangrove Trapdoor":[2716272,2716273,2716274,2716275,2716276,2716277,2716278,2716279,2716280,2716281,2716282,2716283,2716284,2716285,2716286,2716287],"Mangrove Wall Sign":[2721668,2721669,2721670,2721671],"Mangrove Wood":[2715498,2715499,2715500,2715501,2715502,2715503],"Material Reducer":[2648424,2648425,2648426,2648427],"Meitnerium":[2609360],"Melon Block":[2648682],"Melon Stem":[2648936,2648937,2648938,2648939,2648940,2648941,2648942,2648943],"Mendelevium":[2609617],"Mercury":[2609874],"Mob Head":[2649152,2649153,2649154,2649156,2649157,2649158,2649159,2649160,2649161,2649162,2649164,2649165,2649166,2649167,2649184,2649185,2649186,2649188,2649189,2649190,2649191,2649200,2649201,2649202,2649204,2649205,2649206,2649207,2649208,2649209,2649210,2649212,2649213,2649214,2649215],"Molybdenum":[2610131],"Monster Spawner":[2649453],"Moscovium":[2610388],"Mossy Cobblestone":[2649710],"Mossy Cobblestone Slab":[2649965,2649966,2649967],"Mossy Cobblestone Stairs":[2650224,2650225,2650226,2650227,2650228,2650229,2650230,2650231],"Mossy Cobblestone Wall":[2650401,2650416,2650417,2650418,2650419,2650420,2650421,2650422,2650423,2650424,2650425,2650426,2650427,2650428,2650429,2650430,2650431,2650432,2650433,2650434,2650435,2650436,2650437,2650438,2650439,2650440,2650441,2650442,2650443,2650444,2650445,2650446,2650447,2650448,2650449,2650450,2650451,2650452,2650453,2650454,2650455,2650456,2650457,2650458,2650459,2650460,2650461,2650462,2650463,2650464,2650465,2650466,2650467,2650468,2650469,2650470,2650471,2650472,2650473,2650474,2650475,2650476,2650477,2650478,2650479,2650480,2650481,2650482,2650483,2650484,2650485,2650486,2650487,2650488,2650489,2650490,2650491,2650492,2650493,2650494,2650495,2650529,2650544,2650545,2650546,2650547,2650548,2650549,2650550,2650551,2650552,2650553,2650554,2650555,2650556,2650557,2650558,2650559,2650560,2650561,2650562,2650563,2650564,2650565,2650566,2650567,2650568,2650569,2650570,2650571,2650572,2650573,2650574,2650575,2650576,2650577,2650578,2650579,2650580,2650581,2650582,2650583,2650584,2650585,2650586,2650587,2650588,2650589,2650590,2650591,2650592,2650593,2650594,2650595,2650596,2650597,2650598,2650599,2650600,2650601,2650602,2650603,2650604,2650605,2650606,2650607,2650608,2650609,2650610,2650611,2650612,2650613,2650614,2650615,2650616,2650617,2650618,2650619,2650620,2650621,2650622,2650623],"Mossy Stone Brick Slab":[2650736,2650738,2650739],"Mossy Stone Brick Stairs":[2650992,2650993,2650994,2650995,2650996,2650997,2650998,2650999],"Mossy Stone Brick Wall":[2651172,2651184,2651185,2651186,2651187,2651188,2651189,2651190,2651191,2651192,2651193,2651194,2651195,2651196,2651197,2651198,2651199,2651200,2651201,2651202,2651203,2651204,2651205,2651206,2651207,2651208,2651209,2651210,2651211,2651212,2651213,2651214,2651215,2651216,2651217,2651218,2651219,2651220,2651221,2651222,2651223,2651224,2651225,2651226,2651227,2651228,2651229,2651230,2651231,2651232,2651233,2651234,2651235,2651236,2651237,2651238,2651239,2651240,2651241,2651242,2651243,2651244,2651245,2651246,2651247,2651248,2651249,2651250,2651251,2651252,2651253,2651254,2651255,2651256,2651257,2651258,2651259,2651260,2651261,2651262,2651263,2651300,2651312,2651313,2651314,2651315,2651316,2651317,2651318,2651319,2651320,2651321,2651322,2651323,2651324,2651325,2651326,2651327,2651328,2651329,2651330,2651331,2651332,2651333,2651334,2651335,2651336,2651337,2651338,2651339,2651340,2651341,2651342,2651343,2651344,2651345,2651346,2651347,2651348,2651349,2651350,2651351,2651352,2651353,2651354,2651355,2651356,2651357,2651358,2651359,2651360,2651361,2651362,2651363,2651364,2651365,2651366,2651367,2651368,2651369,2651370,2651371,2651372,2651373,2651374,2651375,2651376,2651377,2651378,2651379,2651380,2651381,2651382,2651383,2651384,2651385,2651386,2651387,2651388,2651389,2651390,2651391],"Mossy Stone Bricks":[2651509],"Mud":[2725526],"Mud Brick Slab":[2726040,2726041,2726042],"Mud Brick Stairs":[2726296,2726297,2726298,2726299,2726300,2726301,2726302,2726303],"Mud Brick Wall":[2726400,2726401,2726402,2726403,2726404,2726405,2726406,2726407,2726408,2726409,2726410,2726411,2726412,2726413,2726414,2726415,2726416,2726417,2726418,2726419,2726420,2726421,2726422,2726423,2726424,2726425,2726426,2726427,2726428,2726429,2726430,2726431,2726432,2726433,2726434,2726435,2726436,2726437,2726438,2726439,2726440,2726441,2726442,2726443,2726444,2726445,2726446,2726447,2726448,2726449,2726450,2726451,2726452,2726453,2726454,2726455,2726456,2726457,2726458,2726459,2726460,2726461,2726462,2726463,2726474,2726480,2726481,2726482,2726483,2726484,2726485,2726486,2726487,2726488,2726489,2726490,2726491,2726492,2726493,2726494,2726495,2726528,2726529,2726530,2726531,2726532,2726533,2726534,2726535,2726536,2726537,2726538,2726539,2726540,2726541,2726542,2726543,2726544,2726545,2726546,2726547,2726548,2726549,2726550,2726551,2726552,2726553,2726554,2726555,2726556,2726557,2726558,2726559,2726560,2726561,2726562,2726563,2726564,2726565,2726566,2726567,2726568,2726569,2726570,2726571,2726572,2726573,2726574,2726575,2726576,2726577,2726578,2726579,2726580,2726581,2726582,2726583,2726584,2726585,2726586,2726587,2726588,2726589,2726590,2726591,2726602,2726608,2726609,2726610,2726611,2726612,2726613,2726614,2726615,2726616,2726617,2726618,2726619,2726620,2726621,2726622,2726623],"Mud Bricks":[2725783],"Muddy Mangrove Roots":[2733748,2733750,2733751],"Mushroom Stem":[2651766],"Mycelium":[2652023],"Neodymium":[2610645],"Neon":[2610902],"Neptunium":[2611159],"Nether Brick Fence":[2652280],"Nether Brick Slab":[2652536,2652537,2652539],"Nether Brick Stairs":[2652792,2652793,2652794,2652795,2652796,2652797,2652798,2652799],"Nether Brick Wall":[2652971,2652976,2652977,2652978,2652979,2652980,2652981,2652982,2652983,2652984,2652985,2652986,2652987,2652988,2652989,2652990,2652991,2652992,2652993,2652994,2652995,2652996,2652997,2652998,2652999,2653000,2653001,2653002,2653003,2653004,2653005,2653006,2653007,2653008,2653009,2653010,2653011,2653012,2653013,2653014,2653015,2653016,2653017,2653018,2653019,2653020,2653021,2653022,2653023,2653024,2653025,2653026,2653027,2653028,2653029,2653030,2653031,2653032,2653033,2653034,2653035,2653036,2653037,2653038,2653039,2653040,2653041,2653042,2653043,2653044,2653045,2653046,2653047,2653048,2653049,2653050,2653051,2653052,2653053,2653054,2653055,2653099,2653104,2653105,2653106,2653107,2653108,2653109,2653110,2653111,2653112,2653113,2653114,2653115,2653116,2653117,2653118,2653119,2653120,2653121,2653122,2653123,2653124,2653125,2653126,2653127,2653128,2653129,2653130,2653131,2653132,2653133,2653134,2653135,2653136,2653137,2653138,2653139,2653140,2653141,2653142,2653143,2653144,2653145,2653146,2653147,2653148,2653149,2653150,2653151,2653152,2653153,2653154,2653155,2653156,2653157,2653158,2653159,2653160,2653161,2653162,2653163,2653164,2653165,2653166,2653167,2653168,2653169,2653170,2653171,2653172,2653173,2653174,2653175,2653176,2653177,2653178,2653179,2653180,2653181,2653182,2653183],"Nether Bricks":[2653308],"Nether Gold Ore":[2725269],"Nether Portal":[2653564,2653565],"Nether Quartz Ore":[2653822],"Nether Reactor Core":[2654079],"Nether Wart":[2654336,2654337,2654338,2654339],"Nether Wart Block":[2654593],"Netherite Block":[2731180],"Netherrack":[2654850],"Nickel":[2611416],"Nihonium":[2611673],"Niobium":[2611930],"Nitrogen":[2612187],"Nobelium":[2612444],"Note Block":[2655107],"Oak Button":[2655360,2655361,2655364,2655365,2655366,2655367,2655368,2655369,2655372,2655373,2655374,2655375],"Oak Door":[2655616,2655617,2655618,2655619,2655620,2655621,2655622,2655623,2655624,2655625,2655626,2655627,2655628,2655629,2655630,2655631,2655632,2655633,2655634,2655635,2655636,2655637,2655638,2655639,2655640,2655641,2655642,2655643,2655644,2655645,2655646,2655647],"Oak Fence":[2655878],"Oak Fence Gate":[2656128,2656129,2656130,2656131,2656132,2656133,2656134,2656135,2656136,2656137,2656138,2656139,2656140,2656141,2656142,2656143],"Oak Leaves":[2656392,2656393,2656394,2656395],"Oak Log":[2656648,2656649,2656650,2656651,2656652,2656653],"Oak Planks":[2656906],"Oak Pressure Plate":[2657162,2657163],"Oak Sapling":[2657420,2657421],"Oak Sign":[2657664,2657665,2657666,2657667,2657668,2657669,2657670,2657671,2657672,2657673,2657674,2657675,2657676,2657677,2657678,2657679],"Oak Slab":[2657932,2657934,2657935],"Oak Stairs":[2658184,2658185,2658186,2658187,2658188,2658189,2658190,2658191],"Oak Trapdoor":[2658448,2658449,2658450,2658451,2658452,2658453,2658454,2658455,2658456,2658457,2658458,2658459,2658460,2658461,2658462,2658463],"Oak Wall Sign":[2658704,2658705,2658706,2658707],"Oak Wood":[2658960,2658961,2658962,2658963,2658966,2658967],"Obsidian":[2659219],"Oganesson":[2612701],"Orange Tulip":[2659733],"Osmium":[2612958],"Oxeye Daisy":[2659990],"Oxygen":[2613215],"Packed Ice":[2660247],"Packed Mud":[2726811],"Palladium":[2613472],"Peony":[2660504,2660505],"Phosphorus":[2613729],"Pink Tulip":[2661018],"Platinum":[2613986],"Plutonium":[2614243],"Podzol":[2661275],"Polished Andesite":[2661532],"Polished Andesite Slab":[2661788,2661789,2661791],"Polished Andesite Stairs":[2662040,2662041,2662042,2662043,2662044,2662045,2662046,2662047],"Polished Basalt":[2699053,2699054,2699055],"Polished Blackstone":[2700597],"Polished Blackstone Brick Slab":[2702652,2702653,2702655],"Polished Blackstone Brick Stairs":[2702904,2702905,2702906,2702907,2702908,2702909,2702910,2702911],"Polished Blackstone Brick Wall":[2703104,2703105,2703106,2703107,2703108,2703109,2703110,2703111,2703112,2703113,2703114,2703115,2703116,2703117,2703118,2703119,2703120,2703121,2703122,2703123,2703124,2703125,2703126,2703127,2703128,2703129,2703130,2703131,2703132,2703133,2703134,2703135,2703136,2703137,2703138,2703139,2703140,2703141,2703142,2703143,2703144,2703145,2703146,2703147,2703148,2703149,2703150,2703151,2703152,2703153,2703154,2703155,2703156,2703157,2703158,2703159,2703160,2703161,2703162,2703163,2703164,2703165,2703166,2703167,2703215,2703216,2703217,2703218,2703219,2703220,2703221,2703222,2703223,2703224,2703225,2703226,2703227,2703228,2703229,2703230,2703231,2703232,2703233,2703234,2703235,2703236,2703237,2703238,2703239,2703240,2703241,2703242,2703243,2703244,2703245,2703246,2703247,2703248,2703249,2703250,2703251,2703252,2703253,2703254,2703255,2703256,2703257,2703258,2703259,2703260,2703261,2703262,2703263,2703264,2703265,2703266,2703267,2703268,2703269,2703270,2703271,2703272,2703273,2703274,2703275,2703276,2703277,2703278,2703279,2703280,2703281,2703282,2703283,2703284,2703285,2703286,2703287,2703288,2703289,2703290,2703291,2703292,2703293,2703294,2703295,2703343,2703344,2703345,2703346,2703347,2703348,2703349,2703350,2703351,2703352,2703353,2703354,2703355,2703356,2703357,2703358,2703359],"Polished Blackstone Bricks":[2702396],"Polished Blackstone Button":[2700850,2700851,2700852,2700853,2700854,2700855,2700858,2700859,2700860,2700861,2700862,2700863],"Polished Blackstone Pressure Plate":[2701110,2701111],"Polished Blackstone Slab":[2701368,2701369,2701370],"Polished Blackstone Stairs":[2701624,2701625,2701626,2701627,2701628,2701629,2701630,2701631],"Polished Blackstone Wall":[2701824,2701825,2701826,2701827,2701828,2701829,2701830,2701831,2701832,2701833,2701834,2701835,2701836,2701837,2701838,2701839,2701840,2701841,2701842,2701843,2701844,2701845,2701846,2701847,2701848,2701849,2701850,2701851,2701852,2701853,2701854,2701855,2701856,2701857,2701858,2701859,2701860,2701861,2701862,2701863,2701864,2701865,2701866,2701867,2701868,2701869,2701870,2701871,2701872,2701873,2701874,2701875,2701876,2701877,2701878,2701879,2701880,2701881,2701882,2701883,2701884,2701885,2701886,2701887,2701930,2701936,2701937,2701938,2701939,2701940,2701941,2701942,2701943,2701944,2701945,2701946,2701947,2701948,2701949,2701950,2701951,2701952,2701953,2701954,2701955,2701956,2701957,2701958,2701959,2701960,2701961,2701962,2701963,2701964,2701965,2701966,2701967,2701968,2701969,2701970,2701971,2701972,2701973,2701974,2701975,2701976,2701977,2701978,2701979,2701980,2701981,2701982,2701983,2701984,2701985,2701986,2701987,2701988,2701989,2701990,2701991,2701992,2701993,2701994,2701995,2701996,2701997,2701998,2701999,2702000,2702001,2702002,2702003,2702004,2702005,2702006,2702007,2702008,2702009,2702010,2702011,2702012,2702013,2702014,2702015,2702058,2702064,2702065,2702066,2702067,2702068,2702069,2702070,2702071,2702072,2702073,2702074,2702075,2702076,2702077,2702078,2702079],"Polished Deepslate":[2708821],"Polished Deepslate Slab":[2709076,2709078,2709079],"Polished Deepslate Stairs":[2709328,2709329,2709330,2709331,2709332,2709333,2709334,2709335],"Polished Deepslate Wall":[2709512,2709520,2709521,2709522,2709523,2709524,2709525,2709526,2709527,2709528,2709529,2709530,2709531,2709532,2709533,2709534,2709535,2709568,2709569,2709570,2709571,2709572,2709573,2709574,2709575,2709576,2709577,2709578,2709579,2709580,2709581,2709582,2709583,2709584,2709585,2709586,2709587,2709588,2709589,2709590,2709591,2709592,2709593,2709594,2709595,2709596,2709597,2709598,2709599,2709600,2709601,2709602,2709603,2709604,2709605,2709606,2709607,2709608,2709609,2709610,2709611,2709612,2709613,2709614,2709615,2709616,2709617,2709618,2709619,2709620,2709621,2709622,2709623,2709624,2709625,2709626,2709627,2709628,2709629,2709630,2709631,2709640,2709648,2709649,2709650,2709651,2709652,2709653,2709654,2709655,2709656,2709657,2709658,2709659,2709660,2709661,2709662,2709663,2709696,2709697,2709698,2709699,2709700,2709701,2709702,2709703,2709704,2709705,2709706,2709707,2709708,2709709,2709710,2709711,2709712,2709713,2709714,2709715,2709716,2709717,2709718,2709719,2709720,2709721,2709722,2709723,2709724,2709725,2709726,2709727,2709728,2709729,2709730,2709731,2709732,2709733,2709734,2709735,2709736,2709737,2709738,2709739,2709740,2709741,2709742,2709743,2709744,2709745,2709746,2709747,2709748,2709749,2709750,2709751,2709752,2709753,2709754,2709755,2709756,2709757,2709758,2709759],"Polished Diorite":[2662303],"Polished Diorite Slab":[2662560,2662561,2662562],"Polished Diorite Stairs":[2662816,2662817,2662818,2662819,2662820,2662821,2662822,2662823],"Polished Granite":[2663074],"Polished Granite Slab":[2663329,2663330,2663331],"Polished Granite Stairs":[2663584,2663585,2663586,2663587,2663588,2663589,2663590,2663591],"Polonium":[2614500],"Poppy":[2663845],"Potassium":[2614757],"Potato Block":[2664096,2664097,2664098,2664099,2664100,2664101,2664102,2664103],"Potion Cauldron":[2732464,2732465,2732466,2732467,2732468,2732469],"Powered Rail":[2664354,2664355,2664356,2664357,2664358,2664359,2664362,2664363,2664364,2664365,2664366,2664367],"Praseodymium":[2615014],"Prismarine":[2664616],"Prismarine Bricks":[2664873],"Prismarine Bricks Slab":[2665128,2665130,2665131],"Prismarine Bricks Stairs":[2665384,2665385,2665386,2665387,2665388,2665389,2665390,2665391],"Prismarine Slab":[2665644,2665645,2665646],"Prismarine Stairs":[2665896,2665897,2665898,2665899,2665900,2665901,2665902,2665903],"Prismarine Wall":[2665984,2665985,2665986,2665987,2665988,2665989,2665990,2665991,2665992,2665993,2665994,2665995,2665996,2665997,2665998,2665999,2666000,2666001,2666002,2666003,2666004,2666005,2666006,2666007,2666008,2666009,2666010,2666011,2666012,2666013,2666014,2666015,2666016,2666017,2666018,2666019,2666020,2666021,2666022,2666023,2666024,2666025,2666026,2666027,2666028,2666029,2666030,2666031,2666032,2666033,2666034,2666035,2666036,2666037,2666038,2666039,2666040,2666041,2666042,2666043,2666044,2666045,2666046,2666047,2666080,2666081,2666082,2666083,2666084,2666085,2666086,2666087,2666088,2666089,2666090,2666091,2666092,2666093,2666094,2666095,2666110,2666112,2666113,2666114,2666115,2666116,2666117,2666118,2666119,2666120,2666121,2666122,2666123,2666124,2666125,2666126,2666127,2666128,2666129,2666130,2666131,2666132,2666133,2666134,2666135,2666136,2666137,2666138,2666139,2666140,2666141,2666142,2666143,2666144,2666145,2666146,2666147,2666148,2666149,2666150,2666151,2666152,2666153,2666154,2666155,2666156,2666157,2666158,2666159,2666160,2666161,2666162,2666163,2666164,2666165,2666166,2666167,2666168,2666169,2666170,2666171,2666172,2666173,2666174,2666175,2666208,2666209,2666210,2666211,2666212,2666213,2666214,2666215,2666216,2666217,2666218,2666219,2666220,2666221,2666222,2666223,2666238],"Promethium":[2615271],"Protactinium":[2615528],"Pumpkin":[2666415],"Pumpkin Stem":[2666672,2666673,2666674,2666675,2666676,2666677,2666678,2666679],"Purple Torch":[2667184,2667185,2667187,2667190,2667191],"Purpur Block":[2667443],"Purpur Pillar":[2667700,2667701,2667702],"Purpur Slab":[2667956,2667957,2667959],"Purpur Stairs":[2668208,2668209,2668210,2668211,2668212,2668213,2668214,2668215],"Quartz Block":[2668471],"Quartz Bricks":[2709849],"Quartz Pillar":[2668728,2668729,2668730],"Quartz Slab":[2668984,2668985,2668987],"Quartz Stairs":[2669240,2669241,2669242,2669243,2669244,2669245,2669246,2669247],"Radium":[2615785],"Radon":[2616042],"Rail":[2669490,2669491,2669496,2669497,2669498,2669499,2669500,2669501,2669502,2669503],"Raw Copper Block":[2703938],"Raw Gold Block":[2704195],"Raw Iron Block":[2704452],"Red Mushroom":[2670013],"Red Mushroom Block":[2670260,2670262,2670263,2670264,2670265,2670266,2670267,2670268,2670269,2670270,2670271],"Red Nether Brick Slab":[2670525,2670526,2670527],"Red Nether Brick Stairs":[2670784,2670785,2670786,2670787,2670788,2670789,2670790,2670791],"Red Nether Brick Wall":[2670848,2670849,2670850,2670851,2670852,2670853,2670854,2670855,2670856,2670857,2670858,2670859,2670860,2670861,2670862,2670863,2670865,2670912,2670913,2670914,2670915,2670916,2670917,2670918,2670919,2670920,2670921,2670922,2670923,2670924,2670925,2670926,2670927,2670928,2670929,2670930,2670931,2670932,2670933,2670934,2670935,2670936,2670937,2670938,2670939,2670940,2670941,2670942,2670943,2670944,2670945,2670946,2670947,2670948,2670949,2670950,2670951,2670952,2670953,2670954,2670955,2670956,2670957,2670958,2670959,2670960,2670961,2670962,2670963,2670964,2670965,2670966,2670967,2670968,2670969,2670970,2670971,2670972,2670973,2670974,2670975,2670976,2670977,2670978,2670979,2670980,2670981,2670982,2670983,2670984,2670985,2670986,2670987,2670988,2670989,2670990,2670991,2670993,2671040,2671041,2671042,2671043,2671044,2671045,2671046,2671047,2671048,2671049,2671050,2671051,2671052,2671053,2671054,2671055,2671056,2671057,2671058,2671059,2671060,2671061,2671062,2671063,2671064,2671065,2671066,2671067,2671068,2671069,2671070,2671071,2671072,2671073,2671074,2671075,2671076,2671077,2671078,2671079,2671080,2671081,2671082,2671083,2671084,2671085,2671086,2671087,2671088,2671089,2671090,2671091,2671092,2671093,2671094,2671095,2671096,2671097,2671098,2671099,2671100,2671101,2671102,2671103],"Red Nether Bricks":[2671298],"Red Sand":[2671555],"Red Sandstone":[2671812],"Red Sandstone Slab":[2672068,2672069,2672071],"Red Sandstone Stairs":[2672320,2672321,2672322,2672323,2672324,2672325,2672326,2672327],"Red Sandstone Wall":[2672384,2672385,2672386,2672387,2672388,2672389,2672390,2672391,2672392,2672393,2672394,2672395,2672396,2672397,2672398,2672399,2672407,2672448,2672449,2672450,2672451,2672452,2672453,2672454,2672455,2672456,2672457,2672458,2672459,2672460,2672461,2672462,2672463,2672464,2672465,2672466,2672467,2672468,2672469,2672470,2672471,2672472,2672473,2672474,2672475,2672476,2672477,2672478,2672479,2672480,2672481,2672482,2672483,2672484,2672485,2672486,2672487,2672488,2672489,2672490,2672491,2672492,2672493,2672494,2672495,2672496,2672497,2672498,2672499,2672500,2672501,2672502,2672503,2672504,2672505,2672506,2672507,2672508,2672509,2672510,2672511,2672512,2672513,2672514,2672515,2672516,2672517,2672518,2672519,2672520,2672521,2672522,2672523,2672524,2672525,2672526,2672527,2672535,2672576,2672577,2672578,2672579,2672580,2672581,2672582,2672583,2672584,2672585,2672586,2672587,2672588,2672589,2672590,2672591,2672592,2672593,2672594,2672595,2672596,2672597,2672598,2672599,2672600,2672601,2672602,2672603,2672604,2672605,2672606,2672607,2672608,2672609,2672610,2672611,2672612,2672613,2672614,2672615,2672616,2672617,2672618,2672619,2672620,2672621,2672622,2672623,2672624,2672625,2672626,2672627,2672628,2672629,2672630,2672631,2672632,2672633,2672634,2672635,2672636,2672637,2672638,2672639],"Red Torch":[2672841,2672842,2672843,2672844,2672845],"Red Tulip":[2673097],"Redstone":[2674896,2674897,2674898,2674899,2674900,2674901,2674902,2674903,2674904,2674905,2674906,2674907,2674908,2674909,2674910,2674911],"Redstone Block":[2673354],"Redstone Comparator":[2673600,2673601,2673602,2673603,2673604,2673605,2673606,2673607,2673608,2673609,2673610,2673611,2673612,2673613,2673614,2673615],"Redstone Lamp":[2673868,2673869],"Redstone Ore":[2674124,2674125],"Redstone Repeater":[2674368,2674369,2674370,2674371,2674372,2674373,2674374,2674375,2674376,2674377,2674378,2674379,2674380,2674381,2674382,2674383,2674384,2674385,2674386,2674387,2674388,2674389,2674390,2674391,2674392,2674393,2674394,2674395,2674396,2674397,2674398,2674399],"Redstone Torch":[2674626,2674627,2674628,2674629,2674630,2674634,2674635,2674636,2674637,2674638],"Reinforced Deepslate":[2736320],"Rhenium":[2616299],"Rhodium":[2616556],"Roentgenium":[2616813],"Rose Bush":[2675410,2675411],"Rubidium":[2617070],"Ruthenium":[2617327],"Rutherfordium":[2617584],"Samarium":[2617841],"Sand":[2675667],"Sandstone":[2675924],"Sandstone Slab":[2676180,2676181,2676183],"Sandstone Stairs":[2676432,2676433,2676434,2676435,2676436,2676437,2676438,2676439],"Sandstone Wall":[2676487,2676496,2676497,2676498,2676499,2676500,2676501,2676502,2676503,2676504,2676505,2676506,2676507,2676508,2676509,2676510,2676511,2676544,2676545,2676546,2676547,2676548,2676549,2676550,2676551,2676552,2676553,2676554,2676555,2676556,2676557,2676558,2676559,2676560,2676561,2676562,2676563,2676564,2676565,2676566,2676567,2676568,2676569,2676570,2676571,2676572,2676573,2676574,2676575,2676576,2676577,2676578,2676579,2676580,2676581,2676582,2676583,2676584,2676585,2676586,2676587,2676588,2676589,2676590,2676591,2676592,2676593,2676594,2676595,2676596,2676597,2676598,2676599,2676600,2676601,2676602,2676603,2676604,2676605,2676606,2676607,2676615,2676624,2676625,2676626,2676627,2676628,2676629,2676630,2676631,2676632,2676633,2676634,2676635,2676636,2676637,2676638,2676639,2676672,2676673,2676674,2676675,2676676,2676677,2676678,2676679,2676680,2676681,2676682,2676683,2676684,2676685,2676686,2676687,2676688,2676689,2676690,2676691,2676692,2676693,2676694,2676695,2676696,2676697,2676698,2676699,2676700,2676701,2676702,2676703,2676704,2676705,2676706,2676707,2676708,2676709,2676710,2676711,2676712,2676713,2676714,2676715,2676716,2676717,2676718,2676719,2676720,2676721,2676722,2676723,2676724,2676725,2676726,2676727,2676728,2676729,2676730,2676731,2676732,2676733,2676734,2676735],"Scandium":[2618098],"Sculk":[2735035],"Sea Lantern":[2676952],"Sea Pickle":[2677208,2677209,2677210,2677211,2677212,2677213,2677214,2677215],"Seaborgium":[2618355],"Selenium":[2618612],"Shroomlight":[2712162],"Shulker Box":[2677466],"Silicon":[2618869],"Silver":[2619126],"Slime Block":[2677723],"Smithing Table":[2730923],"Smoker":[2677976,2677977,2677978,2677979,2677980,2677981,2677982,2677983],"Smooth Basalt":[2699312],"Smooth Quartz Block":[2678237],"Smooth Quartz Slab":[2678492,2678494,2678495],"Smooth Quartz Stairs":[2678744,2678745,2678746,2678747,2678748,2678749,2678750,2678751],"Smooth Red Sandstone":[2679008],"Smooth Red Sandstone Slab":[2679264,2679265,2679267],"Smooth Red Sandstone Stairs":[2679520,2679521,2679522,2679523,2679524,2679525,2679526,2679527],"Smooth Sandstone":[2679779],"Smooth Sandstone Slab":[2680036,2680037,2680038],"Smooth Sandstone Stairs":[2680288,2680289,2680290,2680291,2680292,2680293,2680294,2680295],"Smooth Stone":[2680550],"Smooth Stone Slab":[2680805,2680806,2680807],"Snow Block":[2681064],"Snow Layer":[2681320,2681321,2681322,2681323,2681324,2681325,2681326,2681327],"Sodium":[2619383],"Soul Fire":[2711905],"Soul Lantern":[2711390,2711391],"Soul Sand":[2681578],"Soul Soil":[2711648],"Soul Torch":[2711130,2711131,2711132,2711133,2711135],"Sponge":[2681834,2681835],"Spore Blossom":[2731437],"Spruce Button":[2682080,2682081,2682084,2682085,2682086,2682087,2682088,2682089,2682092,2682093,2682094,2682095],"Spruce Door":[2682336,2682337,2682338,2682339,2682340,2682341,2682342,2682343,2682344,2682345,2682346,2682347,2682348,2682349,2682350,2682351,2682352,2682353,2682354,2682355,2682356,2682357,2682358,2682359,2682360,2682361,2682362,2682363,2682364,2682365,2682366,2682367],"Spruce Fence":[2682606],"Spruce Fence Gate":[2682848,2682849,2682850,2682851,2682852,2682853,2682854,2682855,2682856,2682857,2682858,2682859,2682860,2682861,2682862,2682863],"Spruce Leaves":[2683120,2683121,2683122,2683123],"Spruce Log":[2683376,2683377,2683378,2683379,2683380,2683381],"Spruce Planks":[2683634],"Spruce Pressure Plate":[2683890,2683891],"Spruce Sapling":[2684148,2684149],"Spruce Sign":[2684400,2684401,2684402,2684403,2684404,2684405,2684406,2684407,2684408,2684409,2684410,2684411,2684412,2684413,2684414,2684415],"Spruce Slab":[2684660,2684662,2684663],"Spruce Stairs":[2684912,2684913,2684914,2684915,2684916,2684917,2684918,2684919],"Spruce Trapdoor":[2685168,2685169,2685170,2685171,2685172,2685173,2685174,2685175,2685176,2685177,2685178,2685179,2685180,2685181,2685182,2685183],"Spruce Wall Sign":[2685432,2685433,2685434,2685435],"Spruce Wood":[2685688,2685689,2685690,2685691,2685694,2685695],"Stained Clay":[2685936,2685937,2685938,2685939,2685940,2685941,2685942,2685943,2685944,2685945,2685946,2685947,2685948,2685949,2685950,2685951],"Stained Glass":[2686192,2686193,2686194,2686195,2686196,2686197,2686198,2686199,2686200,2686201,2686202,2686203,2686204,2686205,2686206,2686207],"Stained Glass Pane":[2686448,2686449,2686450,2686451,2686452,2686453,2686454,2686455,2686456,2686457,2686458,2686459,2686460,2686461,2686462,2686463],"Stained Hardened Glass":[2686704,2686705,2686706,2686707,2686708,2686709,2686710,2686711,2686712,2686713,2686714,2686715,2686716,2686717,2686718,2686719],"Stained Hardened Glass Pane":[2686960,2686961,2686962,2686963,2686964,2686965,2686966,2686967,2686968,2686969,2686970,2686971,2686972,2686973,2686974,2686975],"Stone":[2686976],"Stone Brick Slab":[2687232,2687233,2687235],"Stone Brick Stairs":[2687488,2687489,2687490,2687491,2687492,2687493,2687494,2687495],"Stone Brick Wall":[2687744,2687745,2687746,2687747,2687748,2687749,2687750,2687751,2687752,2687753,2687754,2687755,2687756,2687757,2687758,2687759,2687760,2687761,2687762,2687763,2687764,2687765,2687766,2687767,2687768,2687769,2687770,2687771,2687772,2687773,2687774,2687775,2687776,2687777,2687778,2687779,2687780,2687781,2687782,2687783,2687784,2687785,2687786,2687787,2687788,2687789,2687790,2687791,2687792,2687793,2687794,2687795,2687796,2687797,2687798,2687799,2687800,2687801,2687802,2687803,2687804,2687805,2687806,2687807,2687808,2687809,2687810,2687811,2687812,2687813,2687814,2687815,2687816,2687817,2687818,2687819,2687820,2687821,2687822,2687823,2687827,2687872,2687873,2687874,2687875,2687876,2687877,2687878,2687879,2687880,2687881,2687882,2687883,2687884,2687885,2687886,2687887,2687888,2687889,2687890,2687891,2687892,2687893,2687894,2687895,2687896,2687897,2687898,2687899,2687900,2687901,2687902,2687903,2687904,2687905,2687906,2687907,2687908,2687909,2687910,2687911,2687912,2687913,2687914,2687915,2687916,2687917,2687918,2687919,2687920,2687921,2687922,2687923,2687924,2687925,2687926,2687927,2687928,2687929,2687930,2687931,2687932,2687933,2687934,2687935,2687936,2687937,2687938,2687939,2687940,2687941,2687942,2687943,2687944,2687945,2687946,2687947,2687948,2687949,2687950,2687951,2687955],"Stone Bricks":[2688004],"Stone Button":[2688256,2688257,2688260,2688261,2688262,2688263,2688264,2688265,2688268,2688269,2688270,2688271],"Stone Pressure Plate":[2688518,2688519],"Stone Slab":[2688773,2688774,2688775],"Stone Stairs":[2689032,2689033,2689034,2689035,2689036,2689037,2689038,2689039],"Stonecutter":[2689288,2689289,2689290,2689291],"Strontium":[2619640],"Sugarcane":[2692624,2692625,2692626,2692627,2692628,2692629,2692630,2692631,2692632,2692633,2692634,2692635,2692636,2692637,2692638,2692639],"Sulfur":[2619897],"Sunflower":[2692886,2692887],"Sweet Berry Bush":[2693144,2693145,2693146,2693147],"TNT":[2693656,2693657,2693658,2693659],"Tall Grass":[2693401],"Tantalum":[2620154],"Technetium":[2620411],"Tellurium":[2620668],"Tennessine":[2620925],"Terbium":[2621182],"Thallium":[2621439],"Thorium":[2621440],"Thulium":[2621697],"Tin":[2621954],"Tinted Glass":[2722442],"Titanium":[2622211],"Torch":[2693912,2693913,2693914,2693918,2693919],"Trapped Chest":[2694172,2694173,2694174,2694175],"Tripwire":[2694416,2694417,2694418,2694419,2694420,2694421,2694422,2694423,2694424,2694425,2694426,2694427,2694428,2694429,2694430,2694431],"Tripwire Hook":[2694672,2694673,2694674,2694675,2694676,2694677,2694678,2694679,2694680,2694681,2694682,2694683,2694684,2694685,2694686,2694687],"Tuff":[2710877],"Tungsten":[2622468],"Twisting Vines":[2734240,2734241,2734248,2734249,2734250,2734251,2734252,2734253,2734254,2734255,2734256,2734257,2734258,2734259,2734260,2734261,2734262,2734263,2734264,2734265,2734266,2734267,2734268,2734269,2734270,2734271],"Underwater Torch":[2694938,2694939,2694940,2694941,2694942],"Uranium":[2622725],"Vanadium":[2622982],"Vines":[2695200,2695201,2695202,2695203,2695204,2695205,2695206,2695207,2695208,2695209,2695210,2695211,2695212,2695213,2695214,2695215],"Wall Banner":[2695424,2695425,2695426,2695427,2695428,2695429,2695430,2695431,2695432,2695433,2695434,2695435,2695436,2695437,2695438,2695439,2695440,2695441,2695442,2695443,2695444,2695445,2695446,2695447,2695448,2695449,2695450,2695451,2695452,2695453,2695454,2695455,2695456,2695457,2695458,2695459,2695460,2695461,2695462,2695463,2695464,2695465,2695466,2695467,2695468,2695469,2695470,2695471,2695472,2695473,2695474,2695475,2695476,2695477,2695478,2695479,2695480,2695481,2695482,2695483,2695484,2695485,2695486,2695487],"Wall Coral Fan":[2695680,2695681,2695682,2695683,2695686,2695688,2695689,2695690,2695691,2695694,2695696,2695697,2695698,2695699,2695702,2695704,2695705,2695706,2695707,2695710,2695712,2695713,2695714,2695715,2695718,2695720,2695721,2695722,2695723,2695726,2695728,2695729,2695730,2695731,2695734,2695736,2695737,2695738,2695739,2695742],"Warped Button":[2717554,2717555,2717556,2717557,2717558,2717559,2717562,2717563,2717564,2717565,2717566,2717567],"Warped Door":[2719072,2719073,2719074,2719075,2719076,2719077,2719078,2719079,2719080,2719081,2719082,2719083,2719084,2719085,2719086,2719087,2719088,2719089,2719090,2719091,2719092,2719093,2719094,2719095,2719096,2719097,2719098,2719099,2719100,2719101,2719102,2719103],"Warped Fence":[2713704],"Warped Fence Gate":[2719872,2719873,2719874,2719875,2719876,2719877,2719878,2719879,2719880,2719881,2719882,2719883,2719884,2719885,2719886,2719887],"Warped Hyphae":[2716016,2716017,2716018,2716019,2716020,2716021],"Warped Planks":[2712933],"Warped Pressure Plate":[2718330,2718331],"Warped Sign":[2721408,2721409,2721410,2721411,2721412,2721413,2721414,2721415,2721416,2721417,2721418,2721419,2721420,2721421,2721422,2721423],"Warped Slab":[2714473,2714474,2714475],"Warped Stairs":[2720640,2720641,2720642,2720643,2720644,2720645,2720646,2720647],"Warped Stem":[2715242,2715243,2715244,2715245,2715246,2715247],"Warped Trapdoor":[2716784,2716785,2716786,2716787,2716788,2716789,2716790,2716791,2716792,2716793,2716794,2716795,2716796,2716797,2716798,2716799],"Warped Wall Sign":[2722184,2722185,2722186,2722187],"Warped Wart Block":[2727068],"Water":[2695968,2695969,2695970,2695971,2695972,2695973,2695974,2695975,2695976,2695977,2695978,2695979,2695980,2695981,2695982,2695983,2695984,2695985,2695986,2695987,2695988,2695989,2695990,2695991,2695992,2695993,2695994,2695995,2695996,2695997,2695998,2695999],"Water Cauldron":[2731946,2731947,2731948,2731949,2731950,2731951],"Weeping Vines":[2734496,2734497,2734504,2734505,2734506,2734507,2734508,2734509,2734510,2734511,2734512,2734513,2734514,2734515,2734516,2734517,2734518,2734519,2734520,2734521,2734522,2734523,2734524,2734525,2734526,2734527],"Weighted Pressure Plate Heavy":[2696224,2696225,2696226,2696227,2696228,2696229,2696230,2696231,2696232,2696233,2696234,2696235,2696236,2696237,2696238,2696239],"Weighted Pressure Plate Light":[2696480,2696481,2696482,2696483,2696484,2696485,2696486,2696487,2696488,2696489,2696490,2696491,2696492,2696493,2696494,2696495],"Wheat Block":[2696736,2696737,2696738,2696739,2696740,2696741,2696742,2696743],"White Tulip":[2697256],"Wither Rose":[2730152],"Wool":[2697504,2697505,2697506,2697507,2697508,2697509,2697510,2697511,2697512,2697513,2697514,2697515,2697516,2697517,2697518,2697519],"Xenon":[2623239],"Ytterbium":[2623496],"Yttrium":[2623753],"Zinc":[2624267],"Zirconium":[2624524],"ate!upd":[2637117],"reserved6":[2675153],"update!":[2636860]},"stateDataBits":8} \ No newline at end of file +{"knownStates":{"???":[2624010],"Acacia Button":[2560272,2560273,2560274,2560275,2560276,2560277,2560280,2560281,2560282,2560283,2560284,2560285],"Acacia Door":[2560512,2560513,2560514,2560515,2560516,2560517,2560518,2560519,2560520,2560521,2560522,2560523,2560524,2560525,2560526,2560527,2560528,2560529,2560530,2560531,2560532,2560533,2560534,2560535,2560536,2560537,2560538,2560539,2560540,2560541,2560542,2560543],"Acacia Fence":[2560787],"Acacia Fence Gate":[2561040,2561041,2561042,2561043,2561044,2561045,2561046,2561047,2561048,2561049,2561050,2561051,2561052,2561053,2561054,2561055],"Acacia Leaves":[2561300,2561301,2561302,2561303],"Acacia Log":[2561554,2561555,2561556,2561557,2561558,2561559],"Acacia Planks":[2561815],"Acacia Pressure Plate":[2562072,2562073],"Acacia Sapling":[2562328,2562329],"Acacia Sign":[2562576,2562577,2562578,2562579,2562580,2562581,2562582,2562583,2562584,2562585,2562586,2562587,2562588,2562589,2562590,2562591],"Acacia Slab":[2562841,2562842,2562843],"Acacia Stairs":[2563096,2563097,2563098,2563099,2563100,2563101,2563102,2563103],"Acacia Trapdoor":[2563344,2563345,2563346,2563347,2563348,2563349,2563350,2563351,2563352,2563353,2563354,2563355,2563356,2563357,2563358,2563359],"Acacia Wall Sign":[2563612,2563613,2563614,2563615],"Acacia Wood":[2563866,2563867,2563868,2563869,2563870,2563871],"Actinium":[2594197],"Activator Rail":[2564128,2564129,2564130,2564131,2564132,2564133,2564136,2564137,2564138,2564139,2564140,2564141],"Air":[2560016],"All Sided Mushroom Stem":[2564385],"Allium":[2564642],"Aluminum":[2594454],"Americium":[2594711],"Amethyst":[2698284],"Ancient Debris":[2698541],"Andesite":[2564899],"Andesite Slab":[2565156,2565157,2565158],"Andesite Stairs":[2565408,2565409,2565410,2565411,2565412,2565413,2565414,2565415],"Andesite Wall":[2565632,2565633,2565634,2565635,2565636,2565637,2565638,2565639,2565640,2565641,2565642,2565643,2565644,2565645,2565646,2565647,2565648,2565649,2565650,2565651,2565652,2565653,2565654,2565655,2565656,2565657,2565658,2565659,2565660,2565661,2565662,2565663,2565664,2565665,2565666,2565667,2565668,2565669,2565670,2565671,2565672,2565673,2565674,2565675,2565676,2565677,2565678,2565679,2565680,2565681,2565682,2565683,2565684,2565685,2565686,2565687,2565688,2565689,2565690,2565691,2565692,2565693,2565694,2565695,2565728,2565729,2565730,2565731,2565732,2565733,2565734,2565735,2565736,2565737,2565738,2565739,2565740,2565741,2565742,2565743,2565750,2565760,2565761,2565762,2565763,2565764,2565765,2565766,2565767,2565768,2565769,2565770,2565771,2565772,2565773,2565774,2565775,2565776,2565777,2565778,2565779,2565780,2565781,2565782,2565783,2565784,2565785,2565786,2565787,2565788,2565789,2565790,2565791,2565792,2565793,2565794,2565795,2565796,2565797,2565798,2565799,2565800,2565801,2565802,2565803,2565804,2565805,2565806,2565807,2565808,2565809,2565810,2565811,2565812,2565813,2565814,2565815,2565816,2565817,2565818,2565819,2565820,2565821,2565822,2565823,2565856,2565857,2565858,2565859,2565860,2565861,2565862,2565863,2565864,2565865,2565866,2565867,2565868,2565869,2565870,2565871,2565878],"Antimony":[2594968],"Anvil":[2565921,2565922,2565923,2565925,2565926,2565927,2565929,2565930,2565931,2565933,2565934,2565935],"Argon":[2595225],"Arsenic":[2595482],"Astatine":[2595739],"Azalea Leaves":[2735804,2735805,2735806,2735807],"Azure Bluet":[2566184],"Bamboo":[2566432,2566433,2566435,2566436,2566437,2566439,2566440,2566441,2566443,2566444,2566445,2566447],"Bamboo Sapling":[2566698,2566699],"Banner":[2566912,2566913,2566914,2566915,2566916,2566917,2566918,2566919,2566920,2566921,2566922,2566923,2566924,2566925,2566926,2566927,2566928,2566929,2566930,2566931,2566932,2566933,2566934,2566935,2566936,2566937,2566938,2566939,2566940,2566941,2566942,2566943,2566944,2566945,2566946,2566947,2566948,2566949,2566950,2566951,2566952,2566953,2566954,2566955,2566956,2566957,2566958,2566959,2566960,2566961,2566962,2566963,2566964,2566965,2566966,2566967,2566968,2566969,2566970,2566971,2566972,2566973,2566974,2566975,2566976,2566977,2566978,2566979,2566980,2566981,2566982,2566983,2566984,2566985,2566986,2566987,2566988,2566989,2566990,2566991,2566992,2566993,2566994,2566995,2566996,2566997,2566998,2566999,2567000,2567001,2567002,2567003,2567004,2567005,2567006,2567007,2567008,2567009,2567010,2567011,2567012,2567013,2567014,2567015,2567016,2567017,2567018,2567019,2567020,2567021,2567022,2567023,2567024,2567025,2567026,2567027,2567028,2567029,2567030,2567031,2567032,2567033,2567034,2567035,2567036,2567037,2567038,2567039,2567040,2567041,2567042,2567043,2567044,2567045,2567046,2567047,2567048,2567049,2567050,2567051,2567052,2567053,2567054,2567055,2567056,2567057,2567058,2567059,2567060,2567061,2567062,2567063,2567064,2567065,2567066,2567067,2567068,2567069,2567070,2567071,2567072,2567073,2567074,2567075,2567076,2567077,2567078,2567079,2567080,2567081,2567082,2567083,2567084,2567085,2567086,2567087,2567088,2567089,2567090,2567091,2567092,2567093,2567094,2567095,2567096,2567097,2567098,2567099,2567100,2567101,2567102,2567103,2567104,2567105,2567106,2567107,2567108,2567109,2567110,2567111,2567112,2567113,2567114,2567115,2567116,2567117,2567118,2567119,2567120,2567121,2567122,2567123,2567124,2567125,2567126,2567127,2567128,2567129,2567130,2567131,2567132,2567133,2567134,2567135,2567136,2567137,2567138,2567139,2567140,2567141,2567142,2567143,2567144,2567145,2567146,2567147,2567148,2567149,2567150,2567151,2567152,2567153,2567154,2567155,2567156,2567157,2567158,2567159,2567160,2567161,2567162,2567163,2567164,2567165,2567166,2567167],"Barium":[2595996],"Barrel":[2567200,2567201,2567204,2567205,2567206,2567207,2567208,2567209,2567212,2567213,2567214,2567215],"Barrier":[2567469],"Basalt":[2698796,2698798,2698799],"Beacon":[2567726],"Bed Block":[2567936,2567937,2567938,2567939,2567940,2567941,2567942,2567943,2567944,2567945,2567946,2567947,2567948,2567949,2567950,2567951,2567952,2567953,2567954,2567955,2567956,2567957,2567958,2567959,2567960,2567961,2567962,2567963,2567964,2567965,2567966,2567967,2567968,2567969,2567970,2567971,2567972,2567973,2567974,2567975,2567976,2567977,2567978,2567979,2567980,2567981,2567982,2567983,2567984,2567985,2567986,2567987,2567988,2567989,2567990,2567991,2567992,2567993,2567994,2567995,2567996,2567997,2567998,2567999,2568000,2568001,2568002,2568003,2568004,2568005,2568006,2568007,2568008,2568009,2568010,2568011,2568012,2568013,2568014,2568015,2568016,2568017,2568018,2568019,2568020,2568021,2568022,2568023,2568024,2568025,2568026,2568027,2568028,2568029,2568030,2568031,2568032,2568033,2568034,2568035,2568036,2568037,2568038,2568039,2568040,2568041,2568042,2568043,2568044,2568045,2568046,2568047,2568048,2568049,2568050,2568051,2568052,2568053,2568054,2568055,2568056,2568057,2568058,2568059,2568060,2568061,2568062,2568063,2568064,2568065,2568066,2568067,2568068,2568069,2568070,2568071,2568072,2568073,2568074,2568075,2568076,2568077,2568078,2568079,2568080,2568081,2568082,2568083,2568084,2568085,2568086,2568087,2568088,2568089,2568090,2568091,2568092,2568093,2568094,2568095,2568096,2568097,2568098,2568099,2568100,2568101,2568102,2568103,2568104,2568105,2568106,2568107,2568108,2568109,2568110,2568111,2568112,2568113,2568114,2568115,2568116,2568117,2568118,2568119,2568120,2568121,2568122,2568123,2568124,2568125,2568126,2568127,2568128,2568129,2568130,2568131,2568132,2568133,2568134,2568135,2568136,2568137,2568138,2568139,2568140,2568141,2568142,2568143,2568144,2568145,2568146,2568147,2568148,2568149,2568150,2568151,2568152,2568153,2568154,2568155,2568156,2568157,2568158,2568159,2568160,2568161,2568162,2568163,2568164,2568165,2568166,2568167,2568168,2568169,2568170,2568171,2568172,2568173,2568174,2568175,2568176,2568177,2568178,2568179,2568180,2568181,2568182,2568183,2568184,2568185,2568186,2568187,2568188,2568189,2568190,2568191],"Bedrock":[2568240,2568241],"Beetroot Block":[2568496,2568497,2568498,2568499,2568500,2568501,2568502,2568503],"Bell":[2568752,2568753,2568754,2568755,2568756,2568757,2568758,2568759,2568760,2568761,2568762,2568763,2568764,2568765,2568766,2568767],"Berkelium":[2596253],"Beryllium":[2596510],"Birch Button":[2569008,2569009,2569010,2569011,2569014,2569015,2569016,2569017,2569018,2569019,2569022,2569023],"Birch Door":[2569248,2569249,2569250,2569251,2569252,2569253,2569254,2569255,2569256,2569257,2569258,2569259,2569260,2569261,2569262,2569263,2569264,2569265,2569266,2569267,2569268,2569269,2569270,2569271,2569272,2569273,2569274,2569275,2569276,2569277,2569278,2569279],"Birch Fence":[2569525],"Birch Fence Gate":[2569776,2569777,2569778,2569779,2569780,2569781,2569782,2569783,2569784,2569785,2569786,2569787,2569788,2569789,2569790,2569791],"Birch Leaves":[2570036,2570037,2570038,2570039],"Birch Log":[2570296,2570297,2570298,2570299,2570300,2570301],"Birch Planks":[2570553],"Birch Pressure Plate":[2570810,2570811],"Birch Sapling":[2571066,2571067],"Birch Sign":[2571312,2571313,2571314,2571315,2571316,2571317,2571318,2571319,2571320,2571321,2571322,2571323,2571324,2571325,2571326,2571327],"Birch Slab":[2571580,2571581,2571583],"Birch Stairs":[2571832,2571833,2571834,2571835,2571836,2571837,2571838,2571839],"Birch Trapdoor":[2572080,2572081,2572082,2572083,2572084,2572085,2572086,2572087,2572088,2572089,2572090,2572091,2572092,2572093,2572094,2572095],"Birch Wall Sign":[2572352,2572353,2572354,2572355],"Birch Wood":[2572608,2572609,2572610,2572611,2572612,2572613],"Bismuth":[2596767],"Blackstone":[2699569],"Blackstone Slab":[2699824,2699826,2699827],"Blackstone Stairs":[2700080,2700081,2700082,2700083,2700084,2700085,2700086,2700087],"Blackstone Wall":[2700288,2700289,2700290,2700291,2700292,2700293,2700294,2700295,2700296,2700297,2700298,2700299,2700300,2700301,2700302,2700303,2700304,2700305,2700306,2700307,2700308,2700309,2700310,2700311,2700312,2700313,2700314,2700315,2700316,2700317,2700318,2700319,2700320,2700321,2700322,2700323,2700324,2700325,2700326,2700327,2700328,2700329,2700330,2700331,2700332,2700333,2700334,2700335,2700336,2700337,2700338,2700339,2700340,2700341,2700342,2700343,2700344,2700345,2700346,2700347,2700348,2700349,2700350,2700351,2700388,2700400,2700401,2700402,2700403,2700404,2700405,2700406,2700407,2700408,2700409,2700410,2700411,2700412,2700413,2700414,2700415,2700416,2700417,2700418,2700419,2700420,2700421,2700422,2700423,2700424,2700425,2700426,2700427,2700428,2700429,2700430,2700431,2700432,2700433,2700434,2700435,2700436,2700437,2700438,2700439,2700440,2700441,2700442,2700443,2700444,2700445,2700446,2700447,2700448,2700449,2700450,2700451,2700452,2700453,2700454,2700455,2700456,2700457,2700458,2700459,2700460,2700461,2700462,2700463,2700464,2700465,2700466,2700467,2700468,2700469,2700470,2700471,2700472,2700473,2700474,2700475,2700476,2700477,2700478,2700479,2700516,2700528,2700529,2700530,2700531,2700532,2700533,2700534,2700535,2700536,2700537,2700538,2700539,2700540,2700541,2700542,2700543],"Blast Furnace":[2573120,2573121,2573122,2573123,2573124,2573125,2573126,2573127],"Blue Ice":[2573637],"Blue Orchid":[2573894],"Blue Torch":[2574146,2574147,2574148,2574149,2574150],"Bohrium":[2597024],"Bone Block":[2574408,2574409,2574410],"Bookshelf":[2574665],"Boron":[2597281],"Brewing Stand":[2574920,2574921,2574922,2574923,2574924,2574925,2574926,2574927],"Brick Slab":[2575177,2575178,2575179],"Brick Stairs":[2575432,2575433,2575434,2575435,2575436,2575437,2575438,2575439],"Brick Wall":[2575616,2575617,2575618,2575619,2575620,2575621,2575622,2575623,2575624,2575625,2575626,2575627,2575628,2575629,2575630,2575631,2575645,2575680,2575681,2575682,2575683,2575684,2575685,2575686,2575687,2575688,2575689,2575690,2575691,2575692,2575693,2575694,2575695,2575696,2575697,2575698,2575699,2575700,2575701,2575702,2575703,2575704,2575705,2575706,2575707,2575708,2575709,2575710,2575711,2575712,2575713,2575714,2575715,2575716,2575717,2575718,2575719,2575720,2575721,2575722,2575723,2575724,2575725,2575726,2575727,2575728,2575729,2575730,2575731,2575732,2575733,2575734,2575735,2575736,2575737,2575738,2575739,2575740,2575741,2575742,2575743,2575744,2575745,2575746,2575747,2575748,2575749,2575750,2575751,2575752,2575753,2575754,2575755,2575756,2575757,2575758,2575759,2575773,2575808,2575809,2575810,2575811,2575812,2575813,2575814,2575815,2575816,2575817,2575818,2575819,2575820,2575821,2575822,2575823,2575824,2575825,2575826,2575827,2575828,2575829,2575830,2575831,2575832,2575833,2575834,2575835,2575836,2575837,2575838,2575839,2575840,2575841,2575842,2575843,2575844,2575845,2575846,2575847,2575848,2575849,2575850,2575851,2575852,2575853,2575854,2575855,2575856,2575857,2575858,2575859,2575860,2575861,2575862,2575863,2575864,2575865,2575866,2575867,2575868,2575869,2575870,2575871],"Bricks":[2575950],"Bromine":[2597538],"Brown Mushroom":[2576464],"Brown Mushroom Block":[2576720,2576721,2576722,2576723,2576724,2576725,2576726,2576727,2576728,2576729,2576731],"Cactus":[2576976,2576977,2576978,2576979,2576980,2576981,2576982,2576983,2576984,2576985,2576986,2576987,2576988,2576989,2576990,2576991],"Cadmium":[2597795],"Cake":[2577232,2577233,2577234,2577235,2577237,2577238,2577239],"Cake With Candle":[2729638,2729639],"Cake With Dyed Candle":[2729888,2729889,2729890,2729891,2729892,2729893,2729894,2729895,2729896,2729897,2729898,2729899,2729900,2729901,2729902,2729903,2729904,2729905,2729906,2729907,2729908,2729909,2729910,2729911,2729912,2729913,2729914,2729915,2729916,2729917,2729918,2729919],"Calcite":[2704709],"Calcium":[2598052],"Californium":[2598309],"Candle":[2729120,2729121,2729122,2729123,2729124,2729125,2729126,2729127],"Carbon":[2598566],"Carpet":[2577488,2577489,2577490,2577491,2577492,2577493,2577494,2577495,2577496,2577497,2577498,2577499,2577500,2577501,2577502,2577503],"Carrot Block":[2577744,2577745,2577746,2577747,2577748,2577749,2577750,2577751],"Cartography Table":[2730666],"Carved Pumpkin":[2578004,2578005,2578006,2578007],"Cauldron":[2731694],"Cave Vines":[2736512,2736513,2736514,2736515,2736516,2736517,2736518,2736519,2736520,2736521,2736522,2736523,2736524,2736525,2736526,2736527,2736528,2736529,2736530,2736531,2736532,2736533,2736534,2736535,2736536,2736537,2736544,2736545,2736546,2736547,2736548,2736549,2736550,2736551,2736552,2736553,2736554,2736555,2736556,2736557,2736558,2736559,2736560,2736561,2736562,2736563,2736564,2736565,2736566,2736567,2736568,2736569,2736576,2736577,2736578,2736579,2736580,2736581,2736582,2736583,2736584,2736585,2736586,2736587,2736588,2736589,2736590,2736591,2736592,2736593,2736594,2736595,2736596,2736597,2736598,2736599,2736600,2736601,2736608,2736609,2736610,2736611,2736612,2736613,2736614,2736615,2736616,2736617,2736618,2736619,2736620,2736621,2736622,2736623,2736624,2736625,2736626,2736627,2736628,2736629,2736630,2736631,2736632,2736633],"Cerium":[2598823],"Cesium":[2599080],"Chain":[2734776,2734778,2734779],"Cherry Button":[2737088,2737089,2737090,2737091,2737094,2737095,2737096,2737097,2737098,2737099,2737102,2737103],"Cherry Door":[2737344,2737345,2737346,2737347,2737348,2737349,2737350,2737351,2737352,2737353,2737354,2737355,2737356,2737357,2737358,2737359,2737360,2737361,2737362,2737363,2737364,2737365,2737366,2737367,2737368,2737369,2737370,2737371,2737372,2737373,2737374,2737375],"Cherry Fence":[2737605],"Cherry Fence Gate":[2737856,2737857,2737858,2737859,2737860,2737861,2737862,2737863,2737864,2737865,2737866,2737867,2737868,2737869,2737870,2737871],"Cherry Leaves":[2738116,2738117,2738118,2738119],"Cherry Log":[2738376,2738377,2738378,2738379,2738380,2738381],"Cherry Planks":[2738633],"Cherry Pressure Plate":[2738890,2738891],"Cherry Sign":[2739392,2739393,2739394,2739395,2739396,2739397,2739398,2739399,2739400,2739401,2739402,2739403,2739404,2739405,2739406,2739407],"Cherry Slab":[2739660,2739661,2739663],"Cherry Stairs":[2739912,2739913,2739914,2739915,2739916,2739917,2739918,2739919],"Cherry Trapdoor":[2740160,2740161,2740162,2740163,2740164,2740165,2740166,2740167,2740168,2740169,2740170,2740171,2740172,2740173,2740174,2740175],"Cherry Wall Sign":[2740432,2740433,2740434,2740435],"Cherry Wood":[2740688,2740689,2740690,2740691,2740692,2740693],"Chest":[2578520,2578521,2578522,2578523],"Chiseled Deepslate":[2710106],"Chiseled Nether Bricks":[2710363],"Chiseled Polished Blackstone":[2702139],"Chiseled Quartz Block":[2578776,2578777,2578779],"Chiseled Red Sandstone":[2579034],"Chiseled Sandstone":[2579291],"Chiseled Stone Bricks":[2579548],"Chlorine":[2599337],"Chorus Flower":[2732976,2732977,2732978,2732979,2732982,2732983],"Chorus Plant":[2733236],"Chromium":[2599594],"Clay Block":[2579805],"Coal Block":[2580062],"Coal Ore":[2580319],"Cobalt":[2599851],"Cobbled Deepslate":[2707793],"Cobbled Deepslate Slab":[2708048,2708050,2708051],"Cobbled Deepslate Stairs":[2708304,2708305,2708306,2708307,2708308,2708309,2708310,2708311],"Cobbled Deepslate Wall":[2708484,2708496,2708497,2708498,2708499,2708500,2708501,2708502,2708503,2708504,2708505,2708506,2708507,2708508,2708509,2708510,2708511,2708544,2708545,2708546,2708547,2708548,2708549,2708550,2708551,2708552,2708553,2708554,2708555,2708556,2708557,2708558,2708559,2708560,2708561,2708562,2708563,2708564,2708565,2708566,2708567,2708568,2708569,2708570,2708571,2708572,2708573,2708574,2708575,2708576,2708577,2708578,2708579,2708580,2708581,2708582,2708583,2708584,2708585,2708586,2708587,2708588,2708589,2708590,2708591,2708592,2708593,2708594,2708595,2708596,2708597,2708598,2708599,2708600,2708601,2708602,2708603,2708604,2708605,2708606,2708607,2708612,2708624,2708625,2708626,2708627,2708628,2708629,2708630,2708631,2708632,2708633,2708634,2708635,2708636,2708637,2708638,2708639,2708672,2708673,2708674,2708675,2708676,2708677,2708678,2708679,2708680,2708681,2708682,2708683,2708684,2708685,2708686,2708687,2708688,2708689,2708690,2708691,2708692,2708693,2708694,2708695,2708696,2708697,2708698,2708699,2708700,2708701,2708702,2708703,2708704,2708705,2708706,2708707,2708708,2708709,2708710,2708711,2708712,2708713,2708714,2708715,2708716,2708717,2708718,2708719,2708720,2708721,2708722,2708723,2708724,2708725,2708726,2708727,2708728,2708729,2708730,2708731,2708732,2708733,2708734,2708735],"Cobblestone":[2580576],"Cobblestone Slab":[2580832,2580833,2580835],"Cobblestone Stairs":[2581088,2581089,2581090,2581091,2581092,2581093,2581094,2581095],"Cobblestone Wall":[2581280,2581281,2581282,2581283,2581284,2581285,2581286,2581287,2581288,2581289,2581290,2581291,2581292,2581293,2581294,2581295,2581299,2581312,2581313,2581314,2581315,2581316,2581317,2581318,2581319,2581320,2581321,2581322,2581323,2581324,2581325,2581326,2581327,2581328,2581329,2581330,2581331,2581332,2581333,2581334,2581335,2581336,2581337,2581338,2581339,2581340,2581341,2581342,2581343,2581344,2581345,2581346,2581347,2581348,2581349,2581350,2581351,2581352,2581353,2581354,2581355,2581356,2581357,2581358,2581359,2581360,2581361,2581362,2581363,2581364,2581365,2581366,2581367,2581368,2581369,2581370,2581371,2581372,2581373,2581374,2581375,2581408,2581409,2581410,2581411,2581412,2581413,2581414,2581415,2581416,2581417,2581418,2581419,2581420,2581421,2581422,2581423,2581427,2581440,2581441,2581442,2581443,2581444,2581445,2581446,2581447,2581448,2581449,2581450,2581451,2581452,2581453,2581454,2581455,2581456,2581457,2581458,2581459,2581460,2581461,2581462,2581463,2581464,2581465,2581466,2581467,2581468,2581469,2581470,2581471,2581472,2581473,2581474,2581475,2581476,2581477,2581478,2581479,2581480,2581481,2581482,2581483,2581484,2581485,2581486,2581487,2581488,2581489,2581490,2581491,2581492,2581493,2581494,2581495,2581496,2581497,2581498,2581499,2581500,2581501,2581502,2581503],"Cobweb":[2581604],"Cocoa Block":[2581856,2581857,2581858,2581859,2581860,2581861,2581862,2581863,2581868,2581869,2581870,2581871],"Compound Creator":[2582116,2582117,2582118,2582119],"Concrete":[2582368,2582369,2582370,2582371,2582372,2582373,2582374,2582375,2582376,2582377,2582378,2582379,2582380,2582381,2582382,2582383],"Concrete Powder":[2582624,2582625,2582626,2582627,2582628,2582629,2582630,2582631,2582632,2582633,2582634,2582635,2582636,2582637,2582638,2582639],"Copernicium":[2600365],"Copper":[2600622],"Copper Block":[2728096,2728097,2728098,2728099,2728100,2728101,2728102,2728103],"Copper Ore":[2725012],"Coral":[2582880,2582881,2582882,2582883,2582885,2582888,2582889,2582890,2582891,2582893],"Coral Block":[2583136,2583137,2583138,2583139,2583142,2583144,2583145,2583146,2583147,2583150],"Coral Fan":[2583392,2583393,2583394,2583395,2583399,2583400,2583401,2583402,2583403,2583407,2583408,2583409,2583410,2583411,2583415,2583416,2583417,2583418,2583419,2583423],"Cornflower":[2583660],"Cracked Deepslate Bricks":[2706251],"Cracked Deepslate Tiles":[2707536],"Cracked Nether Bricks":[2710620],"Cracked Polished Blackstone Bricks":[2703424],"Cracked Stone Bricks":[2583917],"Crafting Table":[2584174],"Crimson Button":[2717298,2717299,2717300,2717301,2717302,2717303,2717306,2717307,2717308,2717309,2717310,2717311],"Crimson Door":[2718816,2718817,2718818,2718819,2718820,2718821,2718822,2718823,2718824,2718825,2718826,2718827,2718828,2718829,2718830,2718831,2718832,2718833,2718834,2718835,2718836,2718837,2718838,2718839,2718840,2718841,2718842,2718843,2718844,2718845,2718846,2718847],"Crimson Fence":[2713447],"Crimson Fence Gate":[2719600,2719601,2719602,2719603,2719604,2719605,2719606,2719607,2719608,2719609,2719610,2719611,2719612,2719613,2719614,2719615],"Crimson Hyphae":[2715760,2715761,2715762,2715763,2715764,2715765],"Crimson Planks":[2712676],"Crimson Pressure Plate":[2718072,2718073],"Crimson Sign":[2721152,2721153,2721154,2721155,2721156,2721157,2721158,2721159,2721160,2721161,2721162,2721163,2721164,2721165,2721166,2721167],"Crimson Slab":[2714216,2714218,2714219],"Crimson Stairs":[2720384,2720385,2720386,2720387,2720388,2720389,2720390,2720391],"Crimson Stem":[2714984,2714985,2714988,2714989,2714990,2714991],"Crimson Trapdoor":[2716528,2716529,2716530,2716531,2716532,2716533,2716534,2716535,2716536,2716537,2716538,2716539,2716540,2716541,2716542,2716543],"Crimson Wall Sign":[2721928,2721929,2721930,2721931],"Crying Obsidian":[2727325],"Curium":[2600879],"Cut Copper Block":[2728352,2728353,2728354,2728355,2728356,2728357,2728358,2728359],"Cut Copper Slab Slab":[2728608,2728609,2728610,2728611,2728612,2728613,2728614,2728615,2728616,2728617,2728618,2728619,2728620,2728621,2728622,2728623,2728624,2728625,2728626,2728627,2728628,2728629,2728630,2728631],"Cut Copper Stairs":[2728832,2728833,2728834,2728835,2728836,2728837,2728838,2728839,2728840,2728841,2728842,2728843,2728844,2728845,2728846,2728847,2728848,2728849,2728850,2728851,2728852,2728853,2728854,2728855,2728856,2728857,2728858,2728859,2728860,2728861,2728862,2728863,2728864,2728865,2728866,2728867,2728868,2728869,2728870,2728871,2728872,2728873,2728874,2728875,2728876,2728877,2728878,2728879,2728880,2728881,2728882,2728883,2728884,2728885,2728886,2728887,2728888,2728889,2728890,2728891,2728892,2728893,2728894,2728895],"Cut Red Sandstone":[2584431],"Cut Red Sandstone Slab":[2584688,2584689,2584690],"Cut Sandstone":[2584945],"Cut Sandstone Slab":[2585200,2585202,2585203],"Dandelion":[2585716],"Dark Oak Button":[2585968,2585969,2585972,2585973,2585974,2585975,2585976,2585977,2585980,2585981,2585982,2585983],"Dark Oak Door":[2586208,2586209,2586210,2586211,2586212,2586213,2586214,2586215,2586216,2586217,2586218,2586219,2586220,2586221,2586222,2586223,2586224,2586225,2586226,2586227,2586228,2586229,2586230,2586231,2586232,2586233,2586234,2586235,2586236,2586237,2586238,2586239],"Dark Oak Fence":[2586487],"Dark Oak Fence Gate":[2586736,2586737,2586738,2586739,2586740,2586741,2586742,2586743,2586744,2586745,2586746,2586747,2586748,2586749,2586750,2586751],"Dark Oak Leaves":[2587000,2587001,2587002,2587003],"Dark Oak Log":[2587256,2587257,2587258,2587259,2587262,2587263],"Dark Oak Planks":[2587515],"Dark Oak Pressure Plate":[2587772,2587773],"Dark Oak Sapling":[2588028,2588029],"Dark Oak Sign":[2588272,2588273,2588274,2588275,2588276,2588277,2588278,2588279,2588280,2588281,2588282,2588283,2588284,2588285,2588286,2588287],"Dark Oak Slab":[2588541,2588542,2588543],"Dark Oak Stairs":[2588800,2588801,2588802,2588803,2588804,2588805,2588806,2588807],"Dark Oak Trapdoor":[2589056,2589057,2589058,2589059,2589060,2589061,2589062,2589063,2589064,2589065,2589066,2589067,2589068,2589069,2589070,2589071],"Dark Oak Wall Sign":[2589312,2589313,2589314,2589315],"Dark Oak Wood":[2589568,2589569,2589570,2589571,2589574,2589575],"Dark Prismarine":[2589828],"Dark Prismarine Slab":[2590084,2590085,2590087],"Dark Prismarine Stairs":[2590336,2590337,2590338,2590339,2590340,2590341,2590342,2590343],"Darmstadtium":[2601136],"Daylight Sensor":[2590592,2590593,2590594,2590595,2590596,2590597,2590598,2590599,2590600,2590601,2590602,2590603,2590604,2590605,2590606,2590607,2590608,2590609,2590610,2590611,2590612,2590613,2590614,2590615,2590616,2590617,2590618,2590619,2590620,2590621,2590622,2590623],"Dead Bush":[2590856],"Deepslate":[2704964,2704966,2704967],"Deepslate Brick Slab":[2705480,2705481,2705482],"Deepslate Brick Stairs":[2705736,2705737,2705738,2705739,2705740,2705741,2705742,2705743],"Deepslate Brick Wall":[2705920,2705921,2705922,2705923,2705924,2705925,2705926,2705927,2705928,2705929,2705930,2705931,2705932,2705933,2705934,2705935,2705946,2705984,2705985,2705986,2705987,2705988,2705989,2705990,2705991,2705992,2705993,2705994,2705995,2705996,2705997,2705998,2705999,2706000,2706001,2706002,2706003,2706004,2706005,2706006,2706007,2706008,2706009,2706010,2706011,2706012,2706013,2706014,2706015,2706016,2706017,2706018,2706019,2706020,2706021,2706022,2706023,2706024,2706025,2706026,2706027,2706028,2706029,2706030,2706031,2706032,2706033,2706034,2706035,2706036,2706037,2706038,2706039,2706040,2706041,2706042,2706043,2706044,2706045,2706046,2706047,2706048,2706049,2706050,2706051,2706052,2706053,2706054,2706055,2706056,2706057,2706058,2706059,2706060,2706061,2706062,2706063,2706074,2706112,2706113,2706114,2706115,2706116,2706117,2706118,2706119,2706120,2706121,2706122,2706123,2706124,2706125,2706126,2706127,2706128,2706129,2706130,2706131,2706132,2706133,2706134,2706135,2706136,2706137,2706138,2706139,2706140,2706141,2706142,2706143,2706144,2706145,2706146,2706147,2706148,2706149,2706150,2706151,2706152,2706153,2706154,2706155,2706156,2706157,2706158,2706159,2706160,2706161,2706162,2706163,2706164,2706165,2706166,2706167,2706168,2706169,2706170,2706171,2706172,2706173,2706174,2706175],"Deepslate Bricks":[2705223],"Deepslate Coal Ore":[2722956],"Deepslate Copper Ore":[2724755],"Deepslate Diamond Ore":[2723213],"Deepslate Emerald Ore":[2723470],"Deepslate Gold Ore":[2724498],"Deepslate Iron Ore":[2724241],"Deepslate Lapis Lazuli Ore":[2723727],"Deepslate Redstone Ore":[2723984,2723985],"Deepslate Tile Slab":[2706764,2706765,2706767],"Deepslate Tile Stairs":[2707016,2707017,2707018,2707019,2707020,2707021,2707022,2707023],"Deepslate Tile Wall":[2707200,2707201,2707202,2707203,2707204,2707205,2707206,2707207,2707208,2707209,2707210,2707211,2707212,2707213,2707214,2707215,2707231,2707264,2707265,2707266,2707267,2707268,2707269,2707270,2707271,2707272,2707273,2707274,2707275,2707276,2707277,2707278,2707279,2707280,2707281,2707282,2707283,2707284,2707285,2707286,2707287,2707288,2707289,2707290,2707291,2707292,2707293,2707294,2707295,2707296,2707297,2707298,2707299,2707300,2707301,2707302,2707303,2707304,2707305,2707306,2707307,2707308,2707309,2707310,2707311,2707312,2707313,2707314,2707315,2707316,2707317,2707318,2707319,2707320,2707321,2707322,2707323,2707324,2707325,2707326,2707327,2707328,2707329,2707330,2707331,2707332,2707333,2707334,2707335,2707336,2707337,2707338,2707339,2707340,2707341,2707342,2707343,2707359,2707392,2707393,2707394,2707395,2707396,2707397,2707398,2707399,2707400,2707401,2707402,2707403,2707404,2707405,2707406,2707407,2707408,2707409,2707410,2707411,2707412,2707413,2707414,2707415,2707416,2707417,2707418,2707419,2707420,2707421,2707422,2707423,2707424,2707425,2707426,2707427,2707428,2707429,2707430,2707431,2707432,2707433,2707434,2707435,2707436,2707437,2707438,2707439,2707440,2707441,2707442,2707443,2707444,2707445,2707446,2707447,2707448,2707449,2707450,2707451,2707452,2707453,2707454,2707455],"Deepslate Tiles":[2706508],"Detector Rail":[2591104,2591105,2591106,2591107,2591108,2591109,2591112,2591113,2591114,2591115,2591116,2591117],"Diamond Block":[2591370],"Diamond Ore":[2591627],"Diorite":[2591884],"Diorite Slab":[2592140,2592141,2592143],"Diorite Stairs":[2592392,2592393,2592394,2592395,2592396,2592397,2592398,2592399],"Diorite Wall":[2592512,2592513,2592514,2592515,2592516,2592517,2592518,2592519,2592520,2592521,2592522,2592523,2592524,2592525,2592526,2592527,2592528,2592529,2592530,2592531,2592532,2592533,2592534,2592535,2592536,2592537,2592538,2592539,2592540,2592541,2592542,2592543,2592544,2592545,2592546,2592547,2592548,2592549,2592550,2592551,2592552,2592553,2592554,2592555,2592556,2592557,2592558,2592559,2592560,2592561,2592562,2592563,2592564,2592565,2592566,2592567,2592568,2592569,2592570,2592571,2592572,2592573,2592574,2592575,2592576,2592577,2592578,2592579,2592580,2592581,2592582,2592583,2592584,2592585,2592586,2592587,2592588,2592589,2592590,2592591,2592607,2592640,2592641,2592642,2592643,2592644,2592645,2592646,2592647,2592648,2592649,2592650,2592651,2592652,2592653,2592654,2592655,2592656,2592657,2592658,2592659,2592660,2592661,2592662,2592663,2592664,2592665,2592666,2592667,2592668,2592669,2592670,2592671,2592672,2592673,2592674,2592675,2592676,2592677,2592678,2592679,2592680,2592681,2592682,2592683,2592684,2592685,2592686,2592687,2592688,2592689,2592690,2592691,2592692,2592693,2592694,2592695,2592696,2592697,2592698,2592699,2592700,2592701,2592702,2592703,2592704,2592705,2592706,2592707,2592708,2592709,2592710,2592711,2592712,2592713,2592714,2592715,2592716,2592717,2592718,2592719,2592735],"Dirt":[2592912,2592913,2592914],"Double Tallgrass":[2593168,2593169],"Dragon Egg":[2593426],"Dried Kelp Block":[2593683],"Dubnium":[2601393],"Dyed Candle":[2729344,2729345,2729346,2729347,2729348,2729349,2729350,2729351,2729352,2729353,2729354,2729355,2729356,2729357,2729358,2729359,2729360,2729361,2729362,2729363,2729364,2729365,2729366,2729367,2729368,2729369,2729370,2729371,2729372,2729373,2729374,2729375,2729376,2729377,2729378,2729379,2729380,2729381,2729382,2729383,2729384,2729385,2729386,2729387,2729388,2729389,2729390,2729391,2729392,2729393,2729394,2729395,2729396,2729397,2729398,2729399,2729400,2729401,2729402,2729403,2729404,2729405,2729406,2729407,2729408,2729409,2729410,2729411,2729412,2729413,2729414,2729415,2729416,2729417,2729418,2729419,2729420,2729421,2729422,2729423,2729424,2729425,2729426,2729427,2729428,2729429,2729430,2729431,2729432,2729433,2729434,2729435,2729436,2729437,2729438,2729439,2729440,2729441,2729442,2729443,2729444,2729445,2729446,2729447,2729448,2729449,2729450,2729451,2729452,2729453,2729454,2729455,2729456,2729457,2729458,2729459,2729460,2729461,2729462,2729463,2729464,2729465,2729466,2729467,2729468,2729469,2729470,2729471],"Dyed Shulker Box":[2593936,2593937,2593938,2593939,2593940,2593941,2593942,2593943,2593944,2593945,2593946,2593947,2593948,2593949,2593950,2593951],"Dysprosium":[2601650],"Einsteinium":[2601907],"Element Constructor":[2600108,2600109,2600110,2600111],"Emerald Block":[2624781],"Emerald Ore":[2625038],"Enchanting Table":[2625295],"End Portal Frame":[2625552,2625553,2625554,2625555,2625556,2625557,2625558,2625559],"End Rod":[2625808,2625809,2625810,2625811,2625812,2625813],"End Stone":[2626066],"End Stone Brick Slab":[2626321,2626322,2626323],"End Stone Brick Stairs":[2626576,2626577,2626578,2626579,2626580,2626581,2626582,2626583],"End Stone Brick Wall":[2626816,2626817,2626818,2626819,2626820,2626821,2626822,2626823,2626824,2626825,2626826,2626827,2626828,2626829,2626830,2626831,2626832,2626833,2626834,2626835,2626836,2626837,2626838,2626839,2626840,2626841,2626842,2626843,2626844,2626845,2626846,2626847,2626848,2626849,2626850,2626851,2626852,2626853,2626854,2626855,2626856,2626857,2626858,2626859,2626860,2626861,2626862,2626863,2626864,2626865,2626866,2626867,2626868,2626869,2626870,2626871,2626872,2626873,2626874,2626875,2626876,2626877,2626878,2626879,2626885,2626896,2626897,2626898,2626899,2626900,2626901,2626902,2626903,2626904,2626905,2626906,2626907,2626908,2626909,2626910,2626911,2626944,2626945,2626946,2626947,2626948,2626949,2626950,2626951,2626952,2626953,2626954,2626955,2626956,2626957,2626958,2626959,2626960,2626961,2626962,2626963,2626964,2626965,2626966,2626967,2626968,2626969,2626970,2626971,2626972,2626973,2626974,2626975,2626976,2626977,2626978,2626979,2626980,2626981,2626982,2626983,2626984,2626985,2626986,2626987,2626988,2626989,2626990,2626991,2626992,2626993,2626994,2626995,2626996,2626997,2626998,2626999,2627000,2627001,2627002,2627003,2627004,2627005,2627006,2627007,2627013,2627024,2627025,2627026,2627027,2627028,2627029,2627030,2627031,2627032,2627033,2627034,2627035,2627036,2627037,2627038,2627039],"End Stone Bricks":[2627094],"Ender Chest":[2627348,2627349,2627350,2627351],"Erbium":[2602164],"Europium":[2602421],"Fake Wooden Slab":[2627608,2627609,2627610],"Farmland":[2627864,2627865,2627866,2627867,2627868,2627869,2627870,2627871],"Fermium":[2602678],"Fern":[2628122],"Fire Block":[2628368,2628369,2628370,2628371,2628372,2628373,2628374,2628375,2628376,2628377,2628378,2628379,2628380,2628381,2628382,2628383],"Flerovium":[2602935],"Fletching Table":[2628636],"Flower Pot":[2628893],"Flowering Azalea Leaves":[2736060,2736061,2736062,2736063],"Fluorine":[2603192],"Francium":[2603449],"Froglight":[2734001,2734002,2734003,2734005,2734006,2734007,2734013,2734014,2734015],"Frosted Ice":[2629148,2629149,2629150,2629151],"Furnace":[2629400,2629401,2629402,2629403,2629404,2629405,2629406,2629407],"Gadolinium":[2603706],"Gallium":[2603963],"Germanium":[2604220],"Gilded Blackstone":[2727582],"Glass":[2629664],"Glass Pane":[2629921],"Glazed Terracotta":[2697984,2697985,2697986,2697987,2697988,2697989,2697990,2697991,2697992,2697993,2697994,2697995,2697996,2697997,2697998,2697999,2698000,2698001,2698002,2698003,2698004,2698005,2698006,2698007,2698008,2698009,2698010,2698011,2698012,2698013,2698014,2698015,2698016,2698017,2698018,2698019,2698020,2698021,2698022,2698023,2698024,2698025,2698026,2698027,2698028,2698029,2698030,2698031,2698032,2698033,2698034,2698035,2698036,2698037,2698038,2698039,2698040,2698041,2698042,2698043,2698044,2698045,2698046,2698047],"Glow Item Frame":[2735280,2735281,2735284,2735285,2735286,2735287,2735288,2735289,2735292,2735293,2735294,2735295],"Glow Lichen":[2736832,2736833,2736834,2736835,2736836,2736837,2736838,2736839,2736840,2736841,2736842,2736843,2736844,2736845,2736846,2736847,2736848,2736849,2736850,2736851,2736852,2736853,2736854,2736855,2736856,2736857,2736858,2736859,2736860,2736861,2736862,2736863,2736864,2736865,2736866,2736867,2736868,2736869,2736870,2736871,2736872,2736873,2736874,2736875,2736876,2736877,2736878,2736879,2736880,2736881,2736882,2736883,2736884,2736885,2736886,2736887,2736888,2736889,2736890,2736891,2736892,2736893,2736894,2736895],"Glowing Obsidian":[2630178],"Glowstone":[2630435],"Gold":[2604477],"Gold Block":[2630692],"Gold Ore":[2630949],"Granite":[2631206],"Granite Slab":[2631461,2631462,2631463],"Granite Stairs":[2631720,2631721,2631722,2631723,2631724,2631725,2631726,2631727],"Granite Wall":[2631936,2631937,2631938,2631939,2631940,2631941,2631942,2631943,2631944,2631945,2631946,2631947,2631948,2631949,2631950,2631951,2631952,2631953,2631954,2631955,2631956,2631957,2631958,2631959,2631960,2631961,2631962,2631963,2631964,2631965,2631966,2631967,2631968,2631969,2631970,2631971,2631972,2631973,2631974,2631975,2631976,2631977,2631978,2631979,2631980,2631981,2631982,2631983,2631984,2631985,2631986,2631987,2631988,2631989,2631990,2631991,2631992,2631993,2631994,2631995,2631996,2631997,2631998,2631999,2632032,2632033,2632034,2632035,2632036,2632037,2632038,2632039,2632040,2632041,2632042,2632043,2632044,2632045,2632046,2632047,2632057,2632064,2632065,2632066,2632067,2632068,2632069,2632070,2632071,2632072,2632073,2632074,2632075,2632076,2632077,2632078,2632079,2632080,2632081,2632082,2632083,2632084,2632085,2632086,2632087,2632088,2632089,2632090,2632091,2632092,2632093,2632094,2632095,2632096,2632097,2632098,2632099,2632100,2632101,2632102,2632103,2632104,2632105,2632106,2632107,2632108,2632109,2632110,2632111,2632112,2632113,2632114,2632115,2632116,2632117,2632118,2632119,2632120,2632121,2632122,2632123,2632124,2632125,2632126,2632127,2632160,2632161,2632162,2632163,2632164,2632165,2632166,2632167,2632168,2632169,2632170,2632171,2632172,2632173,2632174,2632175,2632185],"Grass":[2632234],"Grass Path":[2632491],"Gravel":[2632748],"Green Torch":[2633514,2633515,2633516,2633517,2633518],"Hafnium":[2604734],"Hanging Roots":[2730409],"Hardened Clay":[2633776],"Hardened Glass":[2634033],"Hardened Glass Pane":[2634290],"Hassium":[2604991],"Hay Bale":[2634545,2634546,2634547],"Heat Block":[2578263],"Helium":[2605248],"Holmium":[2605505],"Honeycomb Block":[2722699],"Hopper":[2634800,2634801,2634804,2634806,2634807,2634808,2634809,2634812,2634814,2634815],"Hydrogen":[2605762],"Ice":[2635061],"Indium":[2606019],"Infested Chiseled Stone Brick":[2635318],"Infested Cobblestone":[2635575],"Infested Cracked Stone Brick":[2635832],"Infested Mossy Stone Brick":[2636089],"Infested Stone":[2636346],"Infested Stone Brick":[2636603],"Invisible Bedrock":[2637374],"Iodine":[2606276],"Iridium":[2606533],"Iron":[2606790],"Iron Bars":[2637888],"Iron Block":[2637631],"Iron Door":[2638144,2638145,2638146,2638147,2638148,2638149,2638150,2638151,2638152,2638153,2638154,2638155,2638156,2638157,2638158,2638159,2638160,2638161,2638162,2638163,2638164,2638165,2638166,2638167,2638168,2638169,2638170,2638171,2638172,2638173,2638174,2638175],"Iron Ore":[2638402],"Iron Trapdoor":[2638656,2638657,2638658,2638659,2638660,2638661,2638662,2638663,2638664,2638665,2638666,2638667,2638668,2638669,2638670,2638671],"Item Frame":[2638912,2638913,2638916,2638917,2638918,2638919,2638920,2638921,2638924,2638925,2638926,2638927],"Jack o'Lantern":[2647396,2647397,2647398,2647399],"Jukebox":[2639173],"Jungle Button":[2639426,2639427,2639428,2639429,2639430,2639431,2639434,2639435,2639436,2639437,2639438,2639439],"Jungle Door":[2639680,2639681,2639682,2639683,2639684,2639685,2639686,2639687,2639688,2639689,2639690,2639691,2639692,2639693,2639694,2639695,2639696,2639697,2639698,2639699,2639700,2639701,2639702,2639703,2639704,2639705,2639706,2639707,2639708,2639709,2639710,2639711],"Jungle Fence":[2639944],"Jungle Fence Gate":[2640192,2640193,2640194,2640195,2640196,2640197,2640198,2640199,2640200,2640201,2640202,2640203,2640204,2640205,2640206,2640207],"Jungle Leaves":[2640456,2640457,2640458,2640459],"Jungle Log":[2640712,2640713,2640714,2640715,2640718,2640719],"Jungle Planks":[2640972],"Jungle Pressure Plate":[2641228,2641229],"Jungle Sapling":[2641486,2641487],"Jungle Sign":[2641728,2641729,2641730,2641731,2641732,2641733,2641734,2641735,2641736,2641737,2641738,2641739,2641740,2641741,2641742,2641743],"Jungle Slab":[2642000,2642001,2642002],"Jungle Stairs":[2642256,2642257,2642258,2642259,2642260,2642261,2642262,2642263],"Jungle Trapdoor":[2642512,2642513,2642514,2642515,2642516,2642517,2642518,2642519,2642520,2642521,2642522,2642523,2642524,2642525,2642526,2642527],"Jungle Wall Sign":[2642768,2642769,2642770,2642771],"Jungle Wood":[2643024,2643025,2643028,2643029,2643030,2643031],"Krypton":[2607047],"Lab Table":[2643284,2643285,2643286,2643287],"Ladder":[2643540,2643541,2643542,2643543],"Lantern":[2643798,2643799],"Lanthanum":[2607304],"Lapis Lazuli Block":[2644056],"Lapis Lazuli Ore":[2644313],"Large Fern":[2644570,2644571],"Lava":[2644800,2644801,2644802,2644803,2644804,2644805,2644806,2644807,2644808,2644809,2644810,2644811,2644812,2644813,2644814,2644815,2644816,2644817,2644818,2644819,2644820,2644821,2644822,2644823,2644824,2644825,2644826,2644827,2644828,2644829,2644830,2644831],"Lava Cauldron":[2732208,2732209,2732210,2732211,2732212,2732213],"Lawrencium":[2607561],"Lead":[2607818],"Lectern":[2645080,2645081,2645082,2645083,2645084,2645085,2645086,2645087],"Legacy Stonecutter":[2645341],"Lever":[2645584,2645585,2645586,2645587,2645588,2645589,2645590,2645591,2645592,2645593,2645594,2645595,2645596,2645597,2645598,2645599],"Light Block":[2703680,2703681,2703682,2703683,2703684,2703685,2703686,2703687,2703688,2703689,2703690,2703691,2703692,2703693,2703694,2703695],"Lightning Rod":[2727834,2727835,2727836,2727837,2727838,2727839],"Lilac":[2646368,2646369],"Lily Pad":[2646883],"Lily of the Valley":[2646626],"Lithium":[2608075],"Livermorium":[2608332],"Loom":[2647652,2647653,2647654,2647655],"Lutetium":[2608589],"Magma Block":[2648168],"Magnesium":[2608846],"Manganese":[2609103],"Mangrove Button":[2717040,2717041,2717044,2717045,2717046,2717047,2717048,2717049,2717052,2717053,2717054,2717055],"Mangrove Door":[2718560,2718561,2718562,2718563,2718564,2718565,2718566,2718567,2718568,2718569,2718570,2718571,2718572,2718573,2718574,2718575,2718576,2718577,2718578,2718579,2718580,2718581,2718582,2718583,2718584,2718585,2718586,2718587,2718588,2718589,2718590,2718591],"Mangrove Fence":[2713190],"Mangrove Fence Gate":[2719344,2719345,2719346,2719347,2719348,2719349,2719350,2719351,2719352,2719353,2719354,2719355,2719356,2719357,2719358,2719359],"Mangrove Leaves":[2735548,2735549,2735550,2735551],"Mangrove Log":[2714728,2714729,2714732,2714733,2714734,2714735],"Mangrove Planks":[2712419],"Mangrove Pressure Plate":[2717816,2717817],"Mangrove Roots":[2733493],"Mangrove Sign":[2720896,2720897,2720898,2720899,2720900,2720901,2720902,2720903,2720904,2720905,2720906,2720907,2720908,2720909,2720910,2720911],"Mangrove Slab":[2713960,2713961,2713963],"Mangrove Stairs":[2720128,2720129,2720130,2720131,2720132,2720133,2720134,2720135],"Mangrove Trapdoor":[2716272,2716273,2716274,2716275,2716276,2716277,2716278,2716279,2716280,2716281,2716282,2716283,2716284,2716285,2716286,2716287],"Mangrove Wall Sign":[2721668,2721669,2721670,2721671],"Mangrove Wood":[2715498,2715499,2715500,2715501,2715502,2715503],"Material Reducer":[2648424,2648425,2648426,2648427],"Meitnerium":[2609360],"Melon Block":[2648682],"Melon Stem":[2648896,2648897,2648898,2648899,2648900,2648901,2648902,2648903,2648904,2648905,2648906,2648907,2648908,2648909,2648910,2648911,2648928,2648929,2648930,2648931,2648932,2648933,2648934,2648935,2648944,2648945,2648946,2648947,2648948,2648949,2648950,2648951,2648952,2648953,2648954,2648955,2648956,2648957,2648958,2648959],"Mendelevium":[2609617],"Mercury":[2609874],"Mob Head":[2649152,2649153,2649154,2649156,2649157,2649158,2649159,2649160,2649161,2649162,2649164,2649165,2649166,2649167,2649184,2649185,2649186,2649188,2649189,2649190,2649191,2649200,2649201,2649202,2649204,2649205,2649206,2649207,2649208,2649209,2649210,2649212,2649213,2649214,2649215],"Molybdenum":[2610131],"Monster Spawner":[2649453],"Moscovium":[2610388],"Mossy Cobblestone":[2649710],"Mossy Cobblestone Slab":[2649965,2649966,2649967],"Mossy Cobblestone Stairs":[2650224,2650225,2650226,2650227,2650228,2650229,2650230,2650231],"Mossy Cobblestone Wall":[2650401,2650416,2650417,2650418,2650419,2650420,2650421,2650422,2650423,2650424,2650425,2650426,2650427,2650428,2650429,2650430,2650431,2650432,2650433,2650434,2650435,2650436,2650437,2650438,2650439,2650440,2650441,2650442,2650443,2650444,2650445,2650446,2650447,2650448,2650449,2650450,2650451,2650452,2650453,2650454,2650455,2650456,2650457,2650458,2650459,2650460,2650461,2650462,2650463,2650464,2650465,2650466,2650467,2650468,2650469,2650470,2650471,2650472,2650473,2650474,2650475,2650476,2650477,2650478,2650479,2650480,2650481,2650482,2650483,2650484,2650485,2650486,2650487,2650488,2650489,2650490,2650491,2650492,2650493,2650494,2650495,2650529,2650544,2650545,2650546,2650547,2650548,2650549,2650550,2650551,2650552,2650553,2650554,2650555,2650556,2650557,2650558,2650559,2650560,2650561,2650562,2650563,2650564,2650565,2650566,2650567,2650568,2650569,2650570,2650571,2650572,2650573,2650574,2650575,2650576,2650577,2650578,2650579,2650580,2650581,2650582,2650583,2650584,2650585,2650586,2650587,2650588,2650589,2650590,2650591,2650592,2650593,2650594,2650595,2650596,2650597,2650598,2650599,2650600,2650601,2650602,2650603,2650604,2650605,2650606,2650607,2650608,2650609,2650610,2650611,2650612,2650613,2650614,2650615,2650616,2650617,2650618,2650619,2650620,2650621,2650622,2650623],"Mossy Stone Brick Slab":[2650736,2650738,2650739],"Mossy Stone Brick Stairs":[2650992,2650993,2650994,2650995,2650996,2650997,2650998,2650999],"Mossy Stone Brick Wall":[2651172,2651184,2651185,2651186,2651187,2651188,2651189,2651190,2651191,2651192,2651193,2651194,2651195,2651196,2651197,2651198,2651199,2651200,2651201,2651202,2651203,2651204,2651205,2651206,2651207,2651208,2651209,2651210,2651211,2651212,2651213,2651214,2651215,2651216,2651217,2651218,2651219,2651220,2651221,2651222,2651223,2651224,2651225,2651226,2651227,2651228,2651229,2651230,2651231,2651232,2651233,2651234,2651235,2651236,2651237,2651238,2651239,2651240,2651241,2651242,2651243,2651244,2651245,2651246,2651247,2651248,2651249,2651250,2651251,2651252,2651253,2651254,2651255,2651256,2651257,2651258,2651259,2651260,2651261,2651262,2651263,2651300,2651312,2651313,2651314,2651315,2651316,2651317,2651318,2651319,2651320,2651321,2651322,2651323,2651324,2651325,2651326,2651327,2651328,2651329,2651330,2651331,2651332,2651333,2651334,2651335,2651336,2651337,2651338,2651339,2651340,2651341,2651342,2651343,2651344,2651345,2651346,2651347,2651348,2651349,2651350,2651351,2651352,2651353,2651354,2651355,2651356,2651357,2651358,2651359,2651360,2651361,2651362,2651363,2651364,2651365,2651366,2651367,2651368,2651369,2651370,2651371,2651372,2651373,2651374,2651375,2651376,2651377,2651378,2651379,2651380,2651381,2651382,2651383,2651384,2651385,2651386,2651387,2651388,2651389,2651390,2651391],"Mossy Stone Bricks":[2651509],"Mud":[2725526],"Mud Brick Slab":[2726040,2726041,2726042],"Mud Brick Stairs":[2726296,2726297,2726298,2726299,2726300,2726301,2726302,2726303],"Mud Brick Wall":[2726400,2726401,2726402,2726403,2726404,2726405,2726406,2726407,2726408,2726409,2726410,2726411,2726412,2726413,2726414,2726415,2726416,2726417,2726418,2726419,2726420,2726421,2726422,2726423,2726424,2726425,2726426,2726427,2726428,2726429,2726430,2726431,2726432,2726433,2726434,2726435,2726436,2726437,2726438,2726439,2726440,2726441,2726442,2726443,2726444,2726445,2726446,2726447,2726448,2726449,2726450,2726451,2726452,2726453,2726454,2726455,2726456,2726457,2726458,2726459,2726460,2726461,2726462,2726463,2726474,2726480,2726481,2726482,2726483,2726484,2726485,2726486,2726487,2726488,2726489,2726490,2726491,2726492,2726493,2726494,2726495,2726528,2726529,2726530,2726531,2726532,2726533,2726534,2726535,2726536,2726537,2726538,2726539,2726540,2726541,2726542,2726543,2726544,2726545,2726546,2726547,2726548,2726549,2726550,2726551,2726552,2726553,2726554,2726555,2726556,2726557,2726558,2726559,2726560,2726561,2726562,2726563,2726564,2726565,2726566,2726567,2726568,2726569,2726570,2726571,2726572,2726573,2726574,2726575,2726576,2726577,2726578,2726579,2726580,2726581,2726582,2726583,2726584,2726585,2726586,2726587,2726588,2726589,2726590,2726591,2726602,2726608,2726609,2726610,2726611,2726612,2726613,2726614,2726615,2726616,2726617,2726618,2726619,2726620,2726621,2726622,2726623],"Mud Bricks":[2725783],"Muddy Mangrove Roots":[2733748,2733750,2733751],"Mushroom Stem":[2651766],"Mycelium":[2652023],"Neodymium":[2610645],"Neon":[2610902],"Neptunium":[2611159],"Nether Brick Fence":[2652280],"Nether Brick Slab":[2652536,2652537,2652539],"Nether Brick Stairs":[2652792,2652793,2652794,2652795,2652796,2652797,2652798,2652799],"Nether Brick Wall":[2652971,2652976,2652977,2652978,2652979,2652980,2652981,2652982,2652983,2652984,2652985,2652986,2652987,2652988,2652989,2652990,2652991,2652992,2652993,2652994,2652995,2652996,2652997,2652998,2652999,2653000,2653001,2653002,2653003,2653004,2653005,2653006,2653007,2653008,2653009,2653010,2653011,2653012,2653013,2653014,2653015,2653016,2653017,2653018,2653019,2653020,2653021,2653022,2653023,2653024,2653025,2653026,2653027,2653028,2653029,2653030,2653031,2653032,2653033,2653034,2653035,2653036,2653037,2653038,2653039,2653040,2653041,2653042,2653043,2653044,2653045,2653046,2653047,2653048,2653049,2653050,2653051,2653052,2653053,2653054,2653055,2653099,2653104,2653105,2653106,2653107,2653108,2653109,2653110,2653111,2653112,2653113,2653114,2653115,2653116,2653117,2653118,2653119,2653120,2653121,2653122,2653123,2653124,2653125,2653126,2653127,2653128,2653129,2653130,2653131,2653132,2653133,2653134,2653135,2653136,2653137,2653138,2653139,2653140,2653141,2653142,2653143,2653144,2653145,2653146,2653147,2653148,2653149,2653150,2653151,2653152,2653153,2653154,2653155,2653156,2653157,2653158,2653159,2653160,2653161,2653162,2653163,2653164,2653165,2653166,2653167,2653168,2653169,2653170,2653171,2653172,2653173,2653174,2653175,2653176,2653177,2653178,2653179,2653180,2653181,2653182,2653183],"Nether Bricks":[2653308],"Nether Gold Ore":[2725269],"Nether Portal":[2653564,2653565],"Nether Quartz Ore":[2653822],"Nether Reactor Core":[2654079],"Nether Wart":[2654336,2654337,2654338,2654339],"Nether Wart Block":[2654593],"Netherite Block":[2731180],"Netherrack":[2654850],"Nickel":[2611416],"Nihonium":[2611673],"Niobium":[2611930],"Nitrogen":[2612187],"Nobelium":[2612444],"Note Block":[2655107],"Oak Button":[2655360,2655361,2655364,2655365,2655366,2655367,2655368,2655369,2655372,2655373,2655374,2655375],"Oak Door":[2655616,2655617,2655618,2655619,2655620,2655621,2655622,2655623,2655624,2655625,2655626,2655627,2655628,2655629,2655630,2655631,2655632,2655633,2655634,2655635,2655636,2655637,2655638,2655639,2655640,2655641,2655642,2655643,2655644,2655645,2655646,2655647],"Oak Fence":[2655878],"Oak Fence Gate":[2656128,2656129,2656130,2656131,2656132,2656133,2656134,2656135,2656136,2656137,2656138,2656139,2656140,2656141,2656142,2656143],"Oak Leaves":[2656392,2656393,2656394,2656395],"Oak Log":[2656648,2656649,2656650,2656651,2656652,2656653],"Oak Planks":[2656906],"Oak Pressure Plate":[2657162,2657163],"Oak Sapling":[2657420,2657421],"Oak Sign":[2657664,2657665,2657666,2657667,2657668,2657669,2657670,2657671,2657672,2657673,2657674,2657675,2657676,2657677,2657678,2657679],"Oak Slab":[2657932,2657934,2657935],"Oak Stairs":[2658184,2658185,2658186,2658187,2658188,2658189,2658190,2658191],"Oak Trapdoor":[2658448,2658449,2658450,2658451,2658452,2658453,2658454,2658455,2658456,2658457,2658458,2658459,2658460,2658461,2658462,2658463],"Oak Wall Sign":[2658704,2658705,2658706,2658707],"Oak Wood":[2658960,2658961,2658962,2658963,2658966,2658967],"Obsidian":[2659219],"Oganesson":[2612701],"Orange Tulip":[2659733],"Osmium":[2612958],"Oxeye Daisy":[2659990],"Oxygen":[2613215],"Packed Ice":[2660247],"Packed Mud":[2726811],"Palladium":[2613472],"Peony":[2660504,2660505],"Phosphorus":[2613729],"Pink Tulip":[2661018],"Platinum":[2613986],"Plutonium":[2614243],"Podzol":[2661275],"Polished Andesite":[2661532],"Polished Andesite Slab":[2661788,2661789,2661791],"Polished Andesite Stairs":[2662040,2662041,2662042,2662043,2662044,2662045,2662046,2662047],"Polished Basalt":[2699053,2699054,2699055],"Polished Blackstone":[2700597],"Polished Blackstone Brick Slab":[2702652,2702653,2702655],"Polished Blackstone Brick Stairs":[2702904,2702905,2702906,2702907,2702908,2702909,2702910,2702911],"Polished Blackstone Brick Wall":[2703104,2703105,2703106,2703107,2703108,2703109,2703110,2703111,2703112,2703113,2703114,2703115,2703116,2703117,2703118,2703119,2703120,2703121,2703122,2703123,2703124,2703125,2703126,2703127,2703128,2703129,2703130,2703131,2703132,2703133,2703134,2703135,2703136,2703137,2703138,2703139,2703140,2703141,2703142,2703143,2703144,2703145,2703146,2703147,2703148,2703149,2703150,2703151,2703152,2703153,2703154,2703155,2703156,2703157,2703158,2703159,2703160,2703161,2703162,2703163,2703164,2703165,2703166,2703167,2703215,2703216,2703217,2703218,2703219,2703220,2703221,2703222,2703223,2703224,2703225,2703226,2703227,2703228,2703229,2703230,2703231,2703232,2703233,2703234,2703235,2703236,2703237,2703238,2703239,2703240,2703241,2703242,2703243,2703244,2703245,2703246,2703247,2703248,2703249,2703250,2703251,2703252,2703253,2703254,2703255,2703256,2703257,2703258,2703259,2703260,2703261,2703262,2703263,2703264,2703265,2703266,2703267,2703268,2703269,2703270,2703271,2703272,2703273,2703274,2703275,2703276,2703277,2703278,2703279,2703280,2703281,2703282,2703283,2703284,2703285,2703286,2703287,2703288,2703289,2703290,2703291,2703292,2703293,2703294,2703295,2703343,2703344,2703345,2703346,2703347,2703348,2703349,2703350,2703351,2703352,2703353,2703354,2703355,2703356,2703357,2703358,2703359],"Polished Blackstone Bricks":[2702396],"Polished Blackstone Button":[2700850,2700851,2700852,2700853,2700854,2700855,2700858,2700859,2700860,2700861,2700862,2700863],"Polished Blackstone Pressure Plate":[2701110,2701111],"Polished Blackstone Slab":[2701368,2701369,2701370],"Polished Blackstone Stairs":[2701624,2701625,2701626,2701627,2701628,2701629,2701630,2701631],"Polished Blackstone Wall":[2701824,2701825,2701826,2701827,2701828,2701829,2701830,2701831,2701832,2701833,2701834,2701835,2701836,2701837,2701838,2701839,2701840,2701841,2701842,2701843,2701844,2701845,2701846,2701847,2701848,2701849,2701850,2701851,2701852,2701853,2701854,2701855,2701856,2701857,2701858,2701859,2701860,2701861,2701862,2701863,2701864,2701865,2701866,2701867,2701868,2701869,2701870,2701871,2701872,2701873,2701874,2701875,2701876,2701877,2701878,2701879,2701880,2701881,2701882,2701883,2701884,2701885,2701886,2701887,2701930,2701936,2701937,2701938,2701939,2701940,2701941,2701942,2701943,2701944,2701945,2701946,2701947,2701948,2701949,2701950,2701951,2701952,2701953,2701954,2701955,2701956,2701957,2701958,2701959,2701960,2701961,2701962,2701963,2701964,2701965,2701966,2701967,2701968,2701969,2701970,2701971,2701972,2701973,2701974,2701975,2701976,2701977,2701978,2701979,2701980,2701981,2701982,2701983,2701984,2701985,2701986,2701987,2701988,2701989,2701990,2701991,2701992,2701993,2701994,2701995,2701996,2701997,2701998,2701999,2702000,2702001,2702002,2702003,2702004,2702005,2702006,2702007,2702008,2702009,2702010,2702011,2702012,2702013,2702014,2702015,2702058,2702064,2702065,2702066,2702067,2702068,2702069,2702070,2702071,2702072,2702073,2702074,2702075,2702076,2702077,2702078,2702079],"Polished Deepslate":[2708821],"Polished Deepslate Slab":[2709076,2709078,2709079],"Polished Deepslate Stairs":[2709328,2709329,2709330,2709331,2709332,2709333,2709334,2709335],"Polished Deepslate Wall":[2709512,2709520,2709521,2709522,2709523,2709524,2709525,2709526,2709527,2709528,2709529,2709530,2709531,2709532,2709533,2709534,2709535,2709568,2709569,2709570,2709571,2709572,2709573,2709574,2709575,2709576,2709577,2709578,2709579,2709580,2709581,2709582,2709583,2709584,2709585,2709586,2709587,2709588,2709589,2709590,2709591,2709592,2709593,2709594,2709595,2709596,2709597,2709598,2709599,2709600,2709601,2709602,2709603,2709604,2709605,2709606,2709607,2709608,2709609,2709610,2709611,2709612,2709613,2709614,2709615,2709616,2709617,2709618,2709619,2709620,2709621,2709622,2709623,2709624,2709625,2709626,2709627,2709628,2709629,2709630,2709631,2709640,2709648,2709649,2709650,2709651,2709652,2709653,2709654,2709655,2709656,2709657,2709658,2709659,2709660,2709661,2709662,2709663,2709696,2709697,2709698,2709699,2709700,2709701,2709702,2709703,2709704,2709705,2709706,2709707,2709708,2709709,2709710,2709711,2709712,2709713,2709714,2709715,2709716,2709717,2709718,2709719,2709720,2709721,2709722,2709723,2709724,2709725,2709726,2709727,2709728,2709729,2709730,2709731,2709732,2709733,2709734,2709735,2709736,2709737,2709738,2709739,2709740,2709741,2709742,2709743,2709744,2709745,2709746,2709747,2709748,2709749,2709750,2709751,2709752,2709753,2709754,2709755,2709756,2709757,2709758,2709759],"Polished Diorite":[2662303],"Polished Diorite Slab":[2662560,2662561,2662562],"Polished Diorite Stairs":[2662816,2662817,2662818,2662819,2662820,2662821,2662822,2662823],"Polished Granite":[2663074],"Polished Granite Slab":[2663329,2663330,2663331],"Polished Granite Stairs":[2663584,2663585,2663586,2663587,2663588,2663589,2663590,2663591],"Polonium":[2614500],"Poppy":[2663845],"Potassium":[2614757],"Potato Block":[2664096,2664097,2664098,2664099,2664100,2664101,2664102,2664103],"Potion Cauldron":[2732464,2732465,2732466,2732467,2732468,2732469],"Powered Rail":[2664354,2664355,2664356,2664357,2664358,2664359,2664362,2664363,2664364,2664365,2664366,2664367],"Praseodymium":[2615014],"Prismarine":[2664616],"Prismarine Bricks":[2664873],"Prismarine Bricks Slab":[2665128,2665130,2665131],"Prismarine Bricks Stairs":[2665384,2665385,2665386,2665387,2665388,2665389,2665390,2665391],"Prismarine Slab":[2665644,2665645,2665646],"Prismarine Stairs":[2665896,2665897,2665898,2665899,2665900,2665901,2665902,2665903],"Prismarine Wall":[2665984,2665985,2665986,2665987,2665988,2665989,2665990,2665991,2665992,2665993,2665994,2665995,2665996,2665997,2665998,2665999,2666000,2666001,2666002,2666003,2666004,2666005,2666006,2666007,2666008,2666009,2666010,2666011,2666012,2666013,2666014,2666015,2666016,2666017,2666018,2666019,2666020,2666021,2666022,2666023,2666024,2666025,2666026,2666027,2666028,2666029,2666030,2666031,2666032,2666033,2666034,2666035,2666036,2666037,2666038,2666039,2666040,2666041,2666042,2666043,2666044,2666045,2666046,2666047,2666080,2666081,2666082,2666083,2666084,2666085,2666086,2666087,2666088,2666089,2666090,2666091,2666092,2666093,2666094,2666095,2666110,2666112,2666113,2666114,2666115,2666116,2666117,2666118,2666119,2666120,2666121,2666122,2666123,2666124,2666125,2666126,2666127,2666128,2666129,2666130,2666131,2666132,2666133,2666134,2666135,2666136,2666137,2666138,2666139,2666140,2666141,2666142,2666143,2666144,2666145,2666146,2666147,2666148,2666149,2666150,2666151,2666152,2666153,2666154,2666155,2666156,2666157,2666158,2666159,2666160,2666161,2666162,2666163,2666164,2666165,2666166,2666167,2666168,2666169,2666170,2666171,2666172,2666173,2666174,2666175,2666208,2666209,2666210,2666211,2666212,2666213,2666214,2666215,2666216,2666217,2666218,2666219,2666220,2666221,2666222,2666223,2666238],"Promethium":[2615271],"Protactinium":[2615528],"Pumpkin":[2666415],"Pumpkin Stem":[2666640,2666641,2666642,2666643,2666644,2666645,2666646,2666647,2666648,2666649,2666650,2666651,2666652,2666653,2666654,2666655,2666656,2666657,2666658,2666659,2666660,2666661,2666662,2666663,2666664,2666665,2666666,2666667,2666668,2666669,2666670,2666671,2666680,2666681,2666682,2666683,2666684,2666685,2666686,2666687],"Purple Torch":[2667184,2667185,2667187,2667190,2667191],"Purpur Block":[2667443],"Purpur Pillar":[2667700,2667701,2667702],"Purpur Slab":[2667956,2667957,2667959],"Purpur Stairs":[2668208,2668209,2668210,2668211,2668212,2668213,2668214,2668215],"Quartz Block":[2668471],"Quartz Bricks":[2709849],"Quartz Pillar":[2668728,2668729,2668730],"Quartz Slab":[2668984,2668985,2668987],"Quartz Stairs":[2669240,2669241,2669242,2669243,2669244,2669245,2669246,2669247],"Radium":[2615785],"Radon":[2616042],"Rail":[2669490,2669491,2669496,2669497,2669498,2669499,2669500,2669501,2669502,2669503],"Raw Copper Block":[2703938],"Raw Gold Block":[2704195],"Raw Iron Block":[2704452],"Red Mushroom":[2670013],"Red Mushroom Block":[2670260,2670262,2670263,2670264,2670265,2670266,2670267,2670268,2670269,2670270,2670271],"Red Nether Brick Slab":[2670525,2670526,2670527],"Red Nether Brick Stairs":[2670784,2670785,2670786,2670787,2670788,2670789,2670790,2670791],"Red Nether Brick Wall":[2670848,2670849,2670850,2670851,2670852,2670853,2670854,2670855,2670856,2670857,2670858,2670859,2670860,2670861,2670862,2670863,2670865,2670912,2670913,2670914,2670915,2670916,2670917,2670918,2670919,2670920,2670921,2670922,2670923,2670924,2670925,2670926,2670927,2670928,2670929,2670930,2670931,2670932,2670933,2670934,2670935,2670936,2670937,2670938,2670939,2670940,2670941,2670942,2670943,2670944,2670945,2670946,2670947,2670948,2670949,2670950,2670951,2670952,2670953,2670954,2670955,2670956,2670957,2670958,2670959,2670960,2670961,2670962,2670963,2670964,2670965,2670966,2670967,2670968,2670969,2670970,2670971,2670972,2670973,2670974,2670975,2670976,2670977,2670978,2670979,2670980,2670981,2670982,2670983,2670984,2670985,2670986,2670987,2670988,2670989,2670990,2670991,2670993,2671040,2671041,2671042,2671043,2671044,2671045,2671046,2671047,2671048,2671049,2671050,2671051,2671052,2671053,2671054,2671055,2671056,2671057,2671058,2671059,2671060,2671061,2671062,2671063,2671064,2671065,2671066,2671067,2671068,2671069,2671070,2671071,2671072,2671073,2671074,2671075,2671076,2671077,2671078,2671079,2671080,2671081,2671082,2671083,2671084,2671085,2671086,2671087,2671088,2671089,2671090,2671091,2671092,2671093,2671094,2671095,2671096,2671097,2671098,2671099,2671100,2671101,2671102,2671103],"Red Nether Bricks":[2671298],"Red Sand":[2671555],"Red Sandstone":[2671812],"Red Sandstone Slab":[2672068,2672069,2672071],"Red Sandstone Stairs":[2672320,2672321,2672322,2672323,2672324,2672325,2672326,2672327],"Red Sandstone Wall":[2672384,2672385,2672386,2672387,2672388,2672389,2672390,2672391,2672392,2672393,2672394,2672395,2672396,2672397,2672398,2672399,2672407,2672448,2672449,2672450,2672451,2672452,2672453,2672454,2672455,2672456,2672457,2672458,2672459,2672460,2672461,2672462,2672463,2672464,2672465,2672466,2672467,2672468,2672469,2672470,2672471,2672472,2672473,2672474,2672475,2672476,2672477,2672478,2672479,2672480,2672481,2672482,2672483,2672484,2672485,2672486,2672487,2672488,2672489,2672490,2672491,2672492,2672493,2672494,2672495,2672496,2672497,2672498,2672499,2672500,2672501,2672502,2672503,2672504,2672505,2672506,2672507,2672508,2672509,2672510,2672511,2672512,2672513,2672514,2672515,2672516,2672517,2672518,2672519,2672520,2672521,2672522,2672523,2672524,2672525,2672526,2672527,2672535,2672576,2672577,2672578,2672579,2672580,2672581,2672582,2672583,2672584,2672585,2672586,2672587,2672588,2672589,2672590,2672591,2672592,2672593,2672594,2672595,2672596,2672597,2672598,2672599,2672600,2672601,2672602,2672603,2672604,2672605,2672606,2672607,2672608,2672609,2672610,2672611,2672612,2672613,2672614,2672615,2672616,2672617,2672618,2672619,2672620,2672621,2672622,2672623,2672624,2672625,2672626,2672627,2672628,2672629,2672630,2672631,2672632,2672633,2672634,2672635,2672636,2672637,2672638,2672639],"Red Torch":[2672841,2672842,2672843,2672844,2672845],"Red Tulip":[2673097],"Redstone":[2674896,2674897,2674898,2674899,2674900,2674901,2674902,2674903,2674904,2674905,2674906,2674907,2674908,2674909,2674910,2674911],"Redstone Block":[2673354],"Redstone Comparator":[2673600,2673601,2673602,2673603,2673604,2673605,2673606,2673607,2673608,2673609,2673610,2673611,2673612,2673613,2673614,2673615],"Redstone Lamp":[2673868,2673869],"Redstone Ore":[2674124,2674125],"Redstone Repeater":[2674368,2674369,2674370,2674371,2674372,2674373,2674374,2674375,2674376,2674377,2674378,2674379,2674380,2674381,2674382,2674383,2674384,2674385,2674386,2674387,2674388,2674389,2674390,2674391,2674392,2674393,2674394,2674395,2674396,2674397,2674398,2674399],"Redstone Torch":[2674626,2674627,2674628,2674629,2674630,2674634,2674635,2674636,2674637,2674638],"Reinforced Deepslate":[2736320],"Rhenium":[2616299],"Rhodium":[2616556],"Roentgenium":[2616813],"Rose Bush":[2675410,2675411],"Rubidium":[2617070],"Ruthenium":[2617327],"Rutherfordium":[2617584],"Samarium":[2617841],"Sand":[2675667],"Sandstone":[2675924],"Sandstone Slab":[2676180,2676181,2676183],"Sandstone Stairs":[2676432,2676433,2676434,2676435,2676436,2676437,2676438,2676439],"Sandstone Wall":[2676487,2676496,2676497,2676498,2676499,2676500,2676501,2676502,2676503,2676504,2676505,2676506,2676507,2676508,2676509,2676510,2676511,2676544,2676545,2676546,2676547,2676548,2676549,2676550,2676551,2676552,2676553,2676554,2676555,2676556,2676557,2676558,2676559,2676560,2676561,2676562,2676563,2676564,2676565,2676566,2676567,2676568,2676569,2676570,2676571,2676572,2676573,2676574,2676575,2676576,2676577,2676578,2676579,2676580,2676581,2676582,2676583,2676584,2676585,2676586,2676587,2676588,2676589,2676590,2676591,2676592,2676593,2676594,2676595,2676596,2676597,2676598,2676599,2676600,2676601,2676602,2676603,2676604,2676605,2676606,2676607,2676615,2676624,2676625,2676626,2676627,2676628,2676629,2676630,2676631,2676632,2676633,2676634,2676635,2676636,2676637,2676638,2676639,2676672,2676673,2676674,2676675,2676676,2676677,2676678,2676679,2676680,2676681,2676682,2676683,2676684,2676685,2676686,2676687,2676688,2676689,2676690,2676691,2676692,2676693,2676694,2676695,2676696,2676697,2676698,2676699,2676700,2676701,2676702,2676703,2676704,2676705,2676706,2676707,2676708,2676709,2676710,2676711,2676712,2676713,2676714,2676715,2676716,2676717,2676718,2676719,2676720,2676721,2676722,2676723,2676724,2676725,2676726,2676727,2676728,2676729,2676730,2676731,2676732,2676733,2676734,2676735],"Scandium":[2618098],"Sculk":[2735035],"Sea Lantern":[2676952],"Sea Pickle":[2677208,2677209,2677210,2677211,2677212,2677213,2677214,2677215],"Seaborgium":[2618355],"Selenium":[2618612],"Shroomlight":[2712162],"Shulker Box":[2677466],"Silicon":[2618869],"Silver":[2619126],"Slime Block":[2677723],"Smithing Table":[2730923],"Smoker":[2677976,2677977,2677978,2677979,2677980,2677981,2677982,2677983],"Smooth Basalt":[2699312],"Smooth Quartz Block":[2678237],"Smooth Quartz Slab":[2678492,2678494,2678495],"Smooth Quartz Stairs":[2678744,2678745,2678746,2678747,2678748,2678749,2678750,2678751],"Smooth Red Sandstone":[2679008],"Smooth Red Sandstone Slab":[2679264,2679265,2679267],"Smooth Red Sandstone Stairs":[2679520,2679521,2679522,2679523,2679524,2679525,2679526,2679527],"Smooth Sandstone":[2679779],"Smooth Sandstone Slab":[2680036,2680037,2680038],"Smooth Sandstone Stairs":[2680288,2680289,2680290,2680291,2680292,2680293,2680294,2680295],"Smooth Stone":[2680550],"Smooth Stone Slab":[2680805,2680806,2680807],"Snow Block":[2681064],"Snow Layer":[2681320,2681321,2681322,2681323,2681324,2681325,2681326,2681327],"Sodium":[2619383],"Soul Fire":[2711905],"Soul Lantern":[2711390,2711391],"Soul Sand":[2681578],"Soul Soil":[2711648],"Soul Torch":[2711130,2711131,2711132,2711133,2711135],"Sponge":[2681834,2681835],"Spore Blossom":[2731437],"Spruce Button":[2682080,2682081,2682084,2682085,2682086,2682087,2682088,2682089,2682092,2682093,2682094,2682095],"Spruce Door":[2682336,2682337,2682338,2682339,2682340,2682341,2682342,2682343,2682344,2682345,2682346,2682347,2682348,2682349,2682350,2682351,2682352,2682353,2682354,2682355,2682356,2682357,2682358,2682359,2682360,2682361,2682362,2682363,2682364,2682365,2682366,2682367],"Spruce Fence":[2682606],"Spruce Fence Gate":[2682848,2682849,2682850,2682851,2682852,2682853,2682854,2682855,2682856,2682857,2682858,2682859,2682860,2682861,2682862,2682863],"Spruce Leaves":[2683120,2683121,2683122,2683123],"Spruce Log":[2683376,2683377,2683378,2683379,2683380,2683381],"Spruce Planks":[2683634],"Spruce Pressure Plate":[2683890,2683891],"Spruce Sapling":[2684148,2684149],"Spruce Sign":[2684400,2684401,2684402,2684403,2684404,2684405,2684406,2684407,2684408,2684409,2684410,2684411,2684412,2684413,2684414,2684415],"Spruce Slab":[2684660,2684662,2684663],"Spruce Stairs":[2684912,2684913,2684914,2684915,2684916,2684917,2684918,2684919],"Spruce Trapdoor":[2685168,2685169,2685170,2685171,2685172,2685173,2685174,2685175,2685176,2685177,2685178,2685179,2685180,2685181,2685182,2685183],"Spruce Wall Sign":[2685432,2685433,2685434,2685435],"Spruce Wood":[2685688,2685689,2685690,2685691,2685694,2685695],"Stained Clay":[2685936,2685937,2685938,2685939,2685940,2685941,2685942,2685943,2685944,2685945,2685946,2685947,2685948,2685949,2685950,2685951],"Stained Glass":[2686192,2686193,2686194,2686195,2686196,2686197,2686198,2686199,2686200,2686201,2686202,2686203,2686204,2686205,2686206,2686207],"Stained Glass Pane":[2686448,2686449,2686450,2686451,2686452,2686453,2686454,2686455,2686456,2686457,2686458,2686459,2686460,2686461,2686462,2686463],"Stained Hardened Glass":[2686704,2686705,2686706,2686707,2686708,2686709,2686710,2686711,2686712,2686713,2686714,2686715,2686716,2686717,2686718,2686719],"Stained Hardened Glass Pane":[2686960,2686961,2686962,2686963,2686964,2686965,2686966,2686967,2686968,2686969,2686970,2686971,2686972,2686973,2686974,2686975],"Stone":[2686976],"Stone Brick Slab":[2687232,2687233,2687235],"Stone Brick Stairs":[2687488,2687489,2687490,2687491,2687492,2687493,2687494,2687495],"Stone Brick Wall":[2687744,2687745,2687746,2687747,2687748,2687749,2687750,2687751,2687752,2687753,2687754,2687755,2687756,2687757,2687758,2687759,2687760,2687761,2687762,2687763,2687764,2687765,2687766,2687767,2687768,2687769,2687770,2687771,2687772,2687773,2687774,2687775,2687776,2687777,2687778,2687779,2687780,2687781,2687782,2687783,2687784,2687785,2687786,2687787,2687788,2687789,2687790,2687791,2687792,2687793,2687794,2687795,2687796,2687797,2687798,2687799,2687800,2687801,2687802,2687803,2687804,2687805,2687806,2687807,2687808,2687809,2687810,2687811,2687812,2687813,2687814,2687815,2687816,2687817,2687818,2687819,2687820,2687821,2687822,2687823,2687827,2687872,2687873,2687874,2687875,2687876,2687877,2687878,2687879,2687880,2687881,2687882,2687883,2687884,2687885,2687886,2687887,2687888,2687889,2687890,2687891,2687892,2687893,2687894,2687895,2687896,2687897,2687898,2687899,2687900,2687901,2687902,2687903,2687904,2687905,2687906,2687907,2687908,2687909,2687910,2687911,2687912,2687913,2687914,2687915,2687916,2687917,2687918,2687919,2687920,2687921,2687922,2687923,2687924,2687925,2687926,2687927,2687928,2687929,2687930,2687931,2687932,2687933,2687934,2687935,2687936,2687937,2687938,2687939,2687940,2687941,2687942,2687943,2687944,2687945,2687946,2687947,2687948,2687949,2687950,2687951,2687955],"Stone Bricks":[2688004],"Stone Button":[2688256,2688257,2688260,2688261,2688262,2688263,2688264,2688265,2688268,2688269,2688270,2688271],"Stone Pressure Plate":[2688518,2688519],"Stone Slab":[2688773,2688774,2688775],"Stone Stairs":[2689032,2689033,2689034,2689035,2689036,2689037,2689038,2689039],"Stonecutter":[2689288,2689289,2689290,2689291],"Strontium":[2619640],"Sugarcane":[2692624,2692625,2692626,2692627,2692628,2692629,2692630,2692631,2692632,2692633,2692634,2692635,2692636,2692637,2692638,2692639],"Sulfur":[2619897],"Sunflower":[2692886,2692887],"Sweet Berry Bush":[2693144,2693145,2693146,2693147],"TNT":[2693656,2693657,2693658,2693659],"Tall Grass":[2693401],"Tantalum":[2620154],"Technetium":[2620411],"Tellurium":[2620668],"Tennessine":[2620925],"Terbium":[2621182],"Thallium":[2621439],"Thorium":[2621440],"Thulium":[2621697],"Tin":[2621954],"Tinted Glass":[2722442],"Titanium":[2622211],"Torch":[2693912,2693913,2693914,2693918,2693919],"Trapped Chest":[2694172,2694173,2694174,2694175],"Tripwire":[2694416,2694417,2694418,2694419,2694420,2694421,2694422,2694423,2694424,2694425,2694426,2694427,2694428,2694429,2694430,2694431],"Tripwire Hook":[2694672,2694673,2694674,2694675,2694676,2694677,2694678,2694679,2694680,2694681,2694682,2694683,2694684,2694685,2694686,2694687],"Tuff":[2710877],"Tungsten":[2622468],"Twisting Vines":[2734240,2734241,2734248,2734249,2734250,2734251,2734252,2734253,2734254,2734255,2734256,2734257,2734258,2734259,2734260,2734261,2734262,2734263,2734264,2734265,2734266,2734267,2734268,2734269,2734270,2734271],"Underwater Torch":[2694938,2694939,2694940,2694941,2694942],"Uranium":[2622725],"Vanadium":[2622982],"Vines":[2695200,2695201,2695202,2695203,2695204,2695205,2695206,2695207,2695208,2695209,2695210,2695211,2695212,2695213,2695214,2695215],"Wall Banner":[2695424,2695425,2695426,2695427,2695428,2695429,2695430,2695431,2695432,2695433,2695434,2695435,2695436,2695437,2695438,2695439,2695440,2695441,2695442,2695443,2695444,2695445,2695446,2695447,2695448,2695449,2695450,2695451,2695452,2695453,2695454,2695455,2695456,2695457,2695458,2695459,2695460,2695461,2695462,2695463,2695464,2695465,2695466,2695467,2695468,2695469,2695470,2695471,2695472,2695473,2695474,2695475,2695476,2695477,2695478,2695479,2695480,2695481,2695482,2695483,2695484,2695485,2695486,2695487],"Wall Coral Fan":[2695680,2695681,2695682,2695683,2695686,2695688,2695689,2695690,2695691,2695694,2695696,2695697,2695698,2695699,2695702,2695704,2695705,2695706,2695707,2695710,2695712,2695713,2695714,2695715,2695718,2695720,2695721,2695722,2695723,2695726,2695728,2695729,2695730,2695731,2695734,2695736,2695737,2695738,2695739,2695742],"Warped Button":[2717554,2717555,2717556,2717557,2717558,2717559,2717562,2717563,2717564,2717565,2717566,2717567],"Warped Door":[2719072,2719073,2719074,2719075,2719076,2719077,2719078,2719079,2719080,2719081,2719082,2719083,2719084,2719085,2719086,2719087,2719088,2719089,2719090,2719091,2719092,2719093,2719094,2719095,2719096,2719097,2719098,2719099,2719100,2719101,2719102,2719103],"Warped Fence":[2713704],"Warped Fence Gate":[2719872,2719873,2719874,2719875,2719876,2719877,2719878,2719879,2719880,2719881,2719882,2719883,2719884,2719885,2719886,2719887],"Warped Hyphae":[2716016,2716017,2716018,2716019,2716020,2716021],"Warped Planks":[2712933],"Warped Pressure Plate":[2718330,2718331],"Warped Sign":[2721408,2721409,2721410,2721411,2721412,2721413,2721414,2721415,2721416,2721417,2721418,2721419,2721420,2721421,2721422,2721423],"Warped Slab":[2714473,2714474,2714475],"Warped Stairs":[2720640,2720641,2720642,2720643,2720644,2720645,2720646,2720647],"Warped Stem":[2715242,2715243,2715244,2715245,2715246,2715247],"Warped Trapdoor":[2716784,2716785,2716786,2716787,2716788,2716789,2716790,2716791,2716792,2716793,2716794,2716795,2716796,2716797,2716798,2716799],"Warped Wall Sign":[2722184,2722185,2722186,2722187],"Warped Wart Block":[2727068],"Water":[2695968,2695969,2695970,2695971,2695972,2695973,2695974,2695975,2695976,2695977,2695978,2695979,2695980,2695981,2695982,2695983,2695984,2695985,2695986,2695987,2695988,2695989,2695990,2695991,2695992,2695993,2695994,2695995,2695996,2695997,2695998,2695999],"Water Cauldron":[2731946,2731947,2731948,2731949,2731950,2731951],"Weeping Vines":[2734496,2734497,2734504,2734505,2734506,2734507,2734508,2734509,2734510,2734511,2734512,2734513,2734514,2734515,2734516,2734517,2734518,2734519,2734520,2734521,2734522,2734523,2734524,2734525,2734526,2734527],"Weighted Pressure Plate Heavy":[2696224,2696225,2696226,2696227,2696228,2696229,2696230,2696231,2696232,2696233,2696234,2696235,2696236,2696237,2696238,2696239],"Weighted Pressure Plate Light":[2696480,2696481,2696482,2696483,2696484,2696485,2696486,2696487,2696488,2696489,2696490,2696491,2696492,2696493,2696494,2696495],"Wheat Block":[2696736,2696737,2696738,2696739,2696740,2696741,2696742,2696743],"White Tulip":[2697256],"Wither Rose":[2730152],"Wool":[2697504,2697505,2697506,2697507,2697508,2697509,2697510,2697511,2697512,2697513,2697514,2697515,2697516,2697517,2697518,2697519],"Xenon":[2623239],"Ytterbium":[2623496],"Yttrium":[2623753],"Zinc":[2624267],"Zirconium":[2624524],"ate!upd":[2637117],"reserved6":[2675153],"update!":[2636860]},"stateDataBits":8} \ No newline at end of file From 8c8794ec71279e395caa76d2b6fa751c0f903aa1 Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:41:46 -0500 Subject: [PATCH 06/25] Allow use ConsumingItemAnimation with Living entities (#5897) --- src/entity/animation/ConsumingItemAnimation.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/entity/animation/ConsumingItemAnimation.php b/src/entity/animation/ConsumingItemAnimation.php index aa6152a57..49c8a0a51 100644 --- a/src/entity/animation/ConsumingItemAnimation.php +++ b/src/entity/animation/ConsumingItemAnimation.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\entity\animation; -use pocketmine\entity\Human; +use pocketmine\entity\Living; use pocketmine\item\Item; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\ActorEventPacket; @@ -32,7 +32,7 @@ use pocketmine\network\mcpe\protocol\types\ActorEvent; final class ConsumingItemAnimation implements Animation{ public function __construct( - private Human $human, //TODO: maybe this can be expanded to more than just player entities? + private Living $entity, private Item $item ){} @@ -40,7 +40,7 @@ final class ConsumingItemAnimation implements Animation{ [$netId, $netData] = TypeConverter::getInstance()->getItemTranslator()->toNetworkId($this->item); return [ //TODO: need to check the data values - ActorEventPacket::create($this->human->getId(), ActorEvent::EATING_ITEM, ($netId << 16) | $netData) + ActorEventPacket::create($this->entity->getId(), ActorEvent::EATING_ITEM, ($netId << 16) | $netData) ]; } } From fb6a7d279f41035043c8221af86abde9ced3a046 Mon Sep 17 00:00:00 2001 From: ShockedPlot7560 Date: Mon, 17 Jul 2023 12:13:45 +0200 Subject: [PATCH 07/25] Implement fortune enchantment (#5757) --- src/block/Beetroot.php | 4 +- src/block/Carrot.php | 4 +- src/block/CoalOre.php | 3 +- src/block/CopperOre.php | 5 +- src/block/DiamondOre.php | 3 +- src/block/DoubleTallGrass.php | 7 +- src/block/EmeraldOre.php | 3 +- src/block/GildedBlackstone.php | 3 +- src/block/Glowstone.php | 5 +- src/block/Gravel.php | 4 +- src/block/LapisOre.php | 3 +- src/block/Leaves.php | 11 +- src/block/Melon.php | 5 +- src/block/NetherGoldOre.php | 4 +- src/block/NetherQuartzOre.php | 3 +- src/block/NetherVines.php | 3 +- src/block/NetherWartPlant.php | 3 +- src/block/Potato.php | 4 +- src/block/RedstoneOre.php | 3 +- src/block/SeaLantern.php | 4 +- src/block/SweetBerryBush.php | 16 +- src/block/TallGrass.php | 11 +- src/block/Wheat.php | 4 +- src/block/utils/FortuneDropHelper.php | 150 ++++++++++++++++++ src/data/bedrock/EnchantmentIdMap.php | 1 + .../enchantment/StringToEnchantmentParser.php | 1 + src/item/enchantment/VanillaEnchantments.php | 2 + 27 files changed, 220 insertions(+), 49 deletions(-) create mode 100644 src/block/utils/FortuneDropHelper.php diff --git a/src/block/Beetroot.php b/src/block/Beetroot.php index b87a841ea..cf92fdda2 100644 --- a/src/block/Beetroot.php +++ b/src/block/Beetroot.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; class Beetroot extends Crops{ @@ -33,7 +33,7 @@ class Beetroot extends Crops{ if($this->age >= self::MAX_AGE){ return [ VanillaItems::BEETROOT(), - VanillaItems::BEETROOT_SEEDS()->setCount(mt_rand(0, 3)) + VanillaItems::BEETROOT_SEEDS()->setCount(FortuneDropHelper::binomial($item, 0)) ]; } diff --git a/src/block/Carrot.php b/src/block/Carrot.php index 895b0a37d..7d8947afa 100644 --- a/src/block/Carrot.php +++ b/src/block/Carrot.php @@ -23,15 +23,15 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; class Carrot extends Crops{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::CARROT()->setCount($this->age >= self::MAX_AGE ? mt_rand(1, 4) : 1) + VanillaItems::CARROT()->setCount($this->age >= self::MAX_AGE ? FortuneDropHelper::binomial($item, 1) : 1) ]; } diff --git a/src/block/CoalOre.php b/src/block/CoalOre.php index 47a0e255d..19032b011 100644 --- a/src/block/CoalOre.php +++ b/src/block/CoalOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,7 @@ class CoalOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::COAL() + VanillaItems::COAL()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1)) ]; } diff --git a/src/block/CopperOre.php b/src/block/CopperOre.php index ad02cc50f..3b8ef12a0 100644 --- a/src/block/CopperOre.php +++ b/src/block/CopperOre.php @@ -23,13 +23,16 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; final class CopperOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ - return [VanillaItems::RAW_COPPER()]; + return [ + VanillaItems::RAW_COPPER()->setCount(FortuneDropHelper::weighted($item, min: 2, maxBase: 5)), + ]; } public function isAffectedBySilkTouch() : bool{ return true; } diff --git a/src/block/DiamondOre.php b/src/block/DiamondOre.php index 8407bdf15..b0486dcfb 100644 --- a/src/block/DiamondOre.php +++ b/src/block/DiamondOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,7 @@ class DiamondOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::DIAMOND() + VanillaItems::DIAMOND()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1)) ]; } diff --git a/src/block/DoubleTallGrass.php b/src/block/DoubleTallGrass.php index fc37442f5..e90f2ec61 100644 --- a/src/block/DoubleTallGrass.php +++ b/src/block/DoubleTallGrass.php @@ -23,9 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; -use pocketmine\item\VanillaItems; -use function mt_rand; class DoubleTallGrass extends DoublePlant{ @@ -34,8 +33,8 @@ class DoubleTallGrass extends DoublePlant{ } public function getDropsForIncompatibleTool(Item $item) : array{ - if($this->top && mt_rand(0, 7) === 0){ - return [VanillaItems::WHEAT_SEEDS()]; + if($this->top){ + return FortuneDropHelper::grass($item); } return []; } diff --git a/src/block/EmeraldOre.php b/src/block/EmeraldOre.php index 6e997223d..8e5d96191 100644 --- a/src/block/EmeraldOre.php +++ b/src/block/EmeraldOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,7 @@ class EmeraldOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::EMERALD() + VanillaItems::EMERALD()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1)) ]; } diff --git a/src/block/GildedBlackstone.php b/src/block/GildedBlackstone.php index e01d6bfdc..75c822f8e 100644 --- a/src/block/GildedBlackstone.php +++ b/src/block/GildedBlackstone.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -30,7 +31,7 @@ use function mt_rand; final class GildedBlackstone extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ - if(mt_rand(1, 10) === 1){ + if(FortuneDropHelper::bonusChanceDivisor($item, 10, 3)){ return [VanillaItems::GOLD_NUGGET()->setCount(mt_rand(2, 5))]; } diff --git a/src/block/Glowstone.php b/src/block/Glowstone.php index 3b567aa5b..1fead9abe 100644 --- a/src/block/Glowstone.php +++ b/src/block/Glowstone.php @@ -23,9 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; +use function min; class Glowstone extends Transparent{ @@ -35,7 +36,7 @@ class Glowstone extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::GLOWSTONE_DUST()->setCount(mt_rand(2, 4)) + VanillaItems::GLOWSTONE_DUST()->setCount(min(4, FortuneDropHelper::discrete($item, 2, 4))) ]; } diff --git a/src/block/Gravel.php b/src/block/Gravel.php index 4bff2208f..6445ce30e 100644 --- a/src/block/Gravel.php +++ b/src/block/Gravel.php @@ -25,15 +25,15 @@ namespace pocketmine\block; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; class Gravel extends Opaque implements Fallable{ use FallableTrait; public function getDropsForCompatibleTool(Item $item) : array{ - if(mt_rand(1, 10) === 1){ + if(FortuneDropHelper::bonusChanceDivisor($item, 10, 3)){ return [ VanillaItems::FLINT() ]; diff --git a/src/block/LapisOre.php b/src/block/LapisOre.php index 656b0a895..ce54321a4 100644 --- a/src/block/LapisOre.php +++ b/src/block/LapisOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,7 @@ class LapisOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::LAPIS_LAZULI()->setCount(mt_rand(4, 8)) + VanillaItems::LAPIS_LAZULI()->setCount(FortuneDropHelper::weighted($item, min: 4, maxBase: 9)) ]; } diff --git a/src/block/Leaves.php b/src/block/Leaves.php index dc5e9ce80..235190454 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\block\utils\LeavesType; use pocketmine\block\utils\SupportType; use pocketmine\data\runtime\RuntimeDataDescriber; @@ -138,7 +139,8 @@ class Leaves extends Transparent{ } $drops = []; - if(mt_rand(1, 20) === 1){ //Saplings + if(FortuneDropHelper::bonusChanceDivisor($item, 20, 4)){ //Saplings + // TODO: according to the wiki, the jungle saplings have a different drop rate $sapling = (match($this->leavesType){ LeavesType::ACACIA() => VanillaBlocks::ACACIA_SAPLING(), LeavesType::BIRCH() => VanillaBlocks::BIRCH_SAPLING(), @@ -155,10 +157,13 @@ class Leaves extends Transparent{ $drops[] = $sapling; } } - if(($this->leavesType->equals(LeavesType::OAK()) || $this->leavesType->equals(LeavesType::DARK_OAK())) && mt_rand(1, 200) === 1){ //Apples + if( + ($this->leavesType->equals(LeavesType::OAK()) || $this->leavesType->equals(LeavesType::DARK_OAK())) && + FortuneDropHelper::bonusChanceDivisor($item, 200, 20) + ){ //Apples $drops[] = VanillaItems::APPLE(); } - if(mt_rand(1, 50) === 1){ + if(FortuneDropHelper::bonusChanceDivisor($item, 50, 5)){ $drops[] = VanillaItems::STICK()->setCount(mt_rand(1, 2)); } diff --git a/src/block/Melon.php b/src/block/Melon.php index 42d54c0ab..4a32332e1 100644 --- a/src/block/Melon.php +++ b/src/block/Melon.php @@ -23,15 +23,16 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; +use function min; class Melon extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::MELON()->setCount(mt_rand(3, 7)) + VanillaItems::MELON()->setCount(min(9, FortuneDropHelper::discrete($item, 3, 7))) ]; } diff --git a/src/block/NetherGoldOre.php b/src/block/NetherGoldOre.php index 7782f4fc4..fd6745df4 100644 --- a/src/block/NetherGoldOre.php +++ b/src/block/NetherGoldOre.php @@ -23,14 +23,14 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; final class NetherGoldOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ - return [VanillaItems::GOLD_NUGGET()->setCount(mt_rand(2, 6))]; + return [VanillaItems::GOLD_NUGGET()->setCount(FortuneDropHelper::weighted($item, min: 2, maxBase: 6))]; } public function isAffectedBySilkTouch() : bool{ return true; } diff --git a/src/block/NetherQuartzOre.php b/src/block/NetherQuartzOre.php index c2ab20491..0981974ee 100644 --- a/src/block/NetherQuartzOre.php +++ b/src/block/NetherQuartzOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,7 @@ class NetherQuartzOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::NETHER_QUARTZ() + VanillaItems::NETHER_QUARTZ()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1)) ]; } diff --git a/src/block/NetherVines.php b/src/block/NetherVines.php index adf611785..ac075f667 100644 --- a/src/block/NetherVines.php +++ b/src/block/NetherVines.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\block\utils\SupportType; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\entity\Entity; @@ -179,7 +180,7 @@ class NetherVines extends Flowable{ } public function getDropsForCompatibleTool(Item $item) : array{ - if(($item->getBlockToolType() & BlockToolType::SHEARS) !== 0 || mt_rand(1, 3) === 1){ + if(($item->getBlockToolType() & BlockToolType::SHEARS) !== 0 || FortuneDropHelper::bonusChanceFixed($item, 1 / 3, 2 / 9)){ return [$this->asItem()]; } return []; diff --git a/src/block/NetherWartPlant.php b/src/block/NetherWartPlant.php index 76de2a470..6a8fe1f7a 100644 --- a/src/block/NetherWartPlant.php +++ b/src/block/NetherWartPlant.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; @@ -85,7 +86,7 @@ class NetherWartPlant extends Flowable{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - $this->asItem()->setCount($this->age === self::MAX_AGE ? mt_rand(2, 4) : 1) + $this->asItem()->setCount($this->age === self::MAX_AGE ? FortuneDropHelper::discrete($item, 2, 4) : 1) ]; } } diff --git a/src/block/Potato.php b/src/block/Potato.php index 47d39f612..4d1bbf979 100644 --- a/src/block/Potato.php +++ b/src/block/Potato.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,8 @@ class Potato extends Crops{ public function getDropsForCompatibleTool(Item $item) : array{ $result = [ - VanillaItems::POTATO()->setCount($this->age >= self::MAX_AGE ? mt_rand(1, 5) : 1) + //min/max would be 2-5 in Java + VanillaItems::POTATO()->setCount($this->age >= self::MAX_AGE ? FortuneDropHelper::binomial($item, 1) : 1) ]; if($this->age >= self::MAX_AGE && mt_rand(0, 49) === 0){ $result[] = VanillaItems::POISONOUS_POTATO(); diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index 74708c2bd..75f5063ee 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\item\Item; use pocketmine\item\VanillaItems; @@ -81,7 +82,7 @@ class RedstoneOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::REDSTONE_DUST()->setCount(mt_rand(4, 5)) + VanillaItems::REDSTONE_DUST()->setCount(FortuneDropHelper::discrete($item, 4, 5)) ]; } diff --git a/src/block/SeaLantern.php b/src/block/SeaLantern.php index 27ed73f0d..ff0c97d73 100644 --- a/src/block/SeaLantern.php +++ b/src/block/SeaLantern.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; +use function min; class SeaLantern extends Transparent{ @@ -34,7 +36,7 @@ class SeaLantern extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::PRISMARINE_CRYSTALS()->setCount(3) + VanillaItems::PRISMARINE_CRYSTALS()->setCount(min(5, FortuneDropHelper::discrete($item, 2, 3))) ]; } diff --git a/src/block/SweetBerryBush.php b/src/block/SweetBerryBush.php index b75a343ec..5ead39390 100644 --- a/src/block/SweetBerryBush.php +++ b/src/block/SweetBerryBush.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\entity\Entity; use pocketmine\entity\Living; @@ -108,13 +109,14 @@ class SweetBerryBush extends Flowable{ } public function getDropsForCompatibleTool(Item $item) : array{ - if(($dropAmount = $this->getBerryDropAmount()) > 0){ - return [ - $this->asItem()->setCount($dropAmount) - ]; - } - - return []; + $count = match($this->age){ + self::STAGE_MATURE => FortuneDropHelper::discrete($item, 2, 3), + self::STAGE_BUSH_SOME_BERRIES => FortuneDropHelper::discrete($item, 1, 2), + default => 0 + }; + return [ + $this->asItem()->setCount($count) + ]; } public function onNearbyBlockChange() : void{ diff --git a/src/block/TallGrass.php b/src/block/TallGrass.php index e8f533325..019b911bc 100644 --- a/src/block/TallGrass.php +++ b/src/block/TallGrass.php @@ -23,13 +23,12 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; -use pocketmine\item\VanillaItems; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; -use function mt_rand; class TallGrass extends Flowable{ @@ -56,13 +55,7 @@ class TallGrass extends Flowable{ } public function getDropsForIncompatibleTool(Item $item) : array{ - if(mt_rand(0, 15) === 0){ - return [ - VanillaItems::WHEAT_SEEDS() - ]; - } - - return []; + return FortuneDropHelper::grass($item); } public function getFlameEncouragement() : int{ diff --git a/src/block/Wheat.php b/src/block/Wheat.php index 15701c976..92f155f76 100644 --- a/src/block/Wheat.php +++ b/src/block/Wheat.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; class Wheat extends Crops{ @@ -33,7 +33,7 @@ class Wheat extends Crops{ if($this->age >= self::MAX_AGE){ return [ VanillaItems::WHEAT(), - VanillaItems::WHEAT_SEEDS()->setCount(mt_rand(0, 3)) + VanillaItems::WHEAT_SEEDS()->setCount(FortuneDropHelper::binomial($item, 0)) ]; }else{ return [ diff --git a/src/block/utils/FortuneDropHelper.php b/src/block/utils/FortuneDropHelper.php new file mode 100644 index 000000000..4bce36138 --- /dev/null +++ b/src/block/utils/FortuneDropHelper.php @@ -0,0 +1,150 @@ +getEnchantmentLevel(VanillaEnchantments::FORTUNE()); + + return mt_rand($min, + $fortuneLevel > 0 && mt_rand() / mt_getrandmax() > 2 / ($fortuneLevel + 2) ? + $maxBase * ($fortuneLevel + 1) : + $maxBase + ); + } + + /** + * Increases the drop amount according to a binomial distribution. The function will roll maxBase+level times, and add 1 + * if a random number between 0-1 is less than the given probability. Each level of fortune adds one extra roll. + * + * As many as maxBase+level items can be dropped. This applies even if the fortune level is 0. + * + * @param float $chance The chance of adding 1 to the amount for each roll, must be in the range 0-1 + * @param int $min Minimum amount + * @param int $minRolls Number of rolls if fortune level is 0, added to fortune level to calculate total rolls + * + * @return int the number of items to drop + */ + public static function binomial(Item $usedItem, int $min, int $minRolls = 3, float $chance = 4 / 7) : int{ + $fortuneLevel = $usedItem->getEnchantmentLevel(VanillaEnchantments::FORTUNE()); + + $count = $min; + $rolls = $minRolls + $fortuneLevel; + for($i = 0; $i < $rolls; ++$i){ + if(mt_rand() / mt_getrandmax() < $chance){ + ++$count; + } + } + + return $count; + } + + /** + * Grass have a fixed chance to drop wheat seed. + * Fortune level increases the maximum number of seeds that can be dropped. + * A discrete uniform distribution is used to determine the number of seeds dropped. + * + * TODO: I'm not sure this really belongs here, but it's preferable not to duplicate this code between grass and + * tall grass. + * + * @return Item[] + */ + public static function grass(Item $usedItem) : array{ + if(FortuneDropHelper::bonusChanceDivisor($usedItem, 8, 2)){ + return [ + VanillaItems::WHEAT_SEEDS() + ]; + } + + return []; + } + + /** + * Adds the fortune level to the base max and picks a random number between the minimim and adjusted maximum. + * Each amount in the range has an equal chance of being picked. + * + * @param int $maxBase Maximum base amount, as if the fortune level was 0 + * + * @return int the number of items to drop + */ + public static function discrete(Item $usedItem, int $min, int $maxBase) : int{ + if($maxBase < $min){ + throw new \InvalidArgumentException("Minimum base drop amount must be less than or equal to maximum base drop amount"); + } + + $max = $maxBase + $usedItem->getEnchantmentLevel(VanillaEnchantments::FORTUNE()); + return mt_rand($min, $max); + } + + /** + * Calculates a chance of getting an extra bonus drop by reducing the chance divisor by a given amount per fortune + * level. + * + * @param int $divisorBase The number to divide 1 by to get the chance, as if the fortune level was 0 + * @param int $divisorSubtractPerLevel The amount to subtract from the divisor for each level of fortune + * + * @return bool whether the bonus drop should be added + */ + public static function bonusChanceDivisor(Item $usedItem, int $divisorBase, int $divisorSubtractPerLevel) : bool{ + $fortuneLevel = $usedItem->getEnchantmentLevel(VanillaEnchantments::FORTUNE()); + return mt_rand(1, max(1, $divisorBase - ($fortuneLevel * $divisorSubtractPerLevel))) === 1; + } + + /** + * Calculates a chance of getting an extra bonus drop by increasing the chance by a fixed amount per fortune level. + * + * @param float $chanceBase The base chance of getting a bonus drop, as if the fortune level was 0 + * @param float $addedChancePerLevel The amount to add to the chance for each level of fortune + */ + public static function bonusChanceFixed(Item $usedItem, float $chanceBase, float $addedChancePerLevel) : bool{ + $fortuneLevel = $usedItem->getEnchantmentLevel(VanillaEnchantments::FORTUNE()); + $chance = min(1, $chanceBase + ($fortuneLevel * $addedChancePerLevel)); + return mt_rand() / mt_getrandmax() < $chance; + } +} diff --git a/src/data/bedrock/EnchantmentIdMap.php b/src/data/bedrock/EnchantmentIdMap.php index d7f436fa3..1d974ed6e 100644 --- a/src/data/bedrock/EnchantmentIdMap.php +++ b/src/data/bedrock/EnchantmentIdMap.php @@ -62,6 +62,7 @@ final class EnchantmentIdMap{ $this->register(EnchantmentIds::FIRE_ASPECT, VanillaEnchantments::FIRE_ASPECT()); $this->register(EnchantmentIds::EFFICIENCY, VanillaEnchantments::EFFICIENCY()); + $this->register(EnchantmentIds::FORTUNE, VanillaEnchantments::FORTUNE()); $this->register(EnchantmentIds::SILK_TOUCH, VanillaEnchantments::SILK_TOUCH()); $this->register(EnchantmentIds::UNBREAKING, VanillaEnchantments::UNBREAKING()); diff --git a/src/item/enchantment/StringToEnchantmentParser.php b/src/item/enchantment/StringToEnchantmentParser.php index e76e71642..cd57eb203 100644 --- a/src/item/enchantment/StringToEnchantmentParser.php +++ b/src/item/enchantment/StringToEnchantmentParser.php @@ -43,6 +43,7 @@ final class StringToEnchantmentParser extends StringToTParser{ $result->register("fire_aspect", fn() => VanillaEnchantments::FIRE_ASPECT()); $result->register("fire_protection", fn() => VanillaEnchantments::FIRE_PROTECTION()); $result->register("flame", fn() => VanillaEnchantments::FLAME()); + $result->register("fortune", fn() => VanillaEnchantments::FORTUNE()); $result->register("infinity", fn() => VanillaEnchantments::INFINITY()); $result->register("knockback", fn() => VanillaEnchantments::KNOCKBACK()); $result->register("mending", fn() => VanillaEnchantments::MENDING()); diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index 2be5eed71..ac2f5c57e 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -39,6 +39,7 @@ use pocketmine\utils\RegistryTrait; * @method static FireAspectEnchantment FIRE_ASPECT() * @method static ProtectionEnchantment FIRE_PROTECTION() * @method static Enchantment FLAME() + * @method static Enchantment FORTUNE() * @method static Enchantment INFINITY() * @method static KnockbackEnchantment KNOCKBACK() * @method static Enchantment MENDING() @@ -85,6 +86,7 @@ final class VanillaEnchantments{ self::register("FIRE_ASPECT", new FireAspectEnchantment(KnownTranslationFactory::enchantment_fire(), Rarity::RARE, ItemFlags::SWORD, ItemFlags::NONE, 2)); self::register("EFFICIENCY", new Enchantment(KnownTranslationFactory::enchantment_digging(), Rarity::COMMON, ItemFlags::DIG, ItemFlags::SHEARS, 5)); + self::register("FORTUNE", new Enchantment(KnownTranslationFactory::enchantment_lootBonusDigger(), Rarity::RARE, ItemFlags::DIG, ItemFlags::NONE, 3)); self::register("SILK_TOUCH", new Enchantment(KnownTranslationFactory::enchantment_untouching(), Rarity::MYTHIC, ItemFlags::DIG, ItemFlags::SHEARS, 1)); self::register("UNBREAKING", new Enchantment(KnownTranslationFactory::enchantment_durability(), Rarity::UNCOMMON, ItemFlags::DIG | ItemFlags::ARMOR | ItemFlags::FISHING_ROD | ItemFlags::BOW, ItemFlags::TOOL | ItemFlags::CARROT_STICK | ItemFlags::ELYTRA, 3)); From 83d11c7429a9bc961c052e6d0a10a0ea9638b154 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Mon, 17 Jul 2023 18:30:52 +0300 Subject: [PATCH 08/25] Implemented Big & Small dripleaf (#5835) --- build/generate-runtime-enum-serializers.php | 2 + src/block/BaseBigDripleaf.php | 136 ++++++++++++++ src/block/BigDripleafHead.php | 132 ++++++++++++++ src/block/BigDripleafStem.php | 41 +++++ src/block/BlockTypeIds.php | 5 +- src/block/SmallDripleaf.php | 170 ++++++++++++++++++ src/block/VanillaBlocks.php | 7 + src/block/utils/DripleafState.php | 65 +++++++ .../convert/BlockObjectToStateSerializer.php | 27 +++ .../BlockStateToObjectDeserializer.php | 22 +++ src/data/runtime/RuntimeEnumDescriber.php | 2 + .../runtime/RuntimeEnumDeserializerTrait.php | 10 ++ .../runtime/RuntimeEnumSerializerTrait.php | 10 ++ .../RuntimeEnumSizeCalculatorTrait.php | 4 + src/item/StringToItemParser.php | 2 + src/world/sound/DripleafTiltDownSound.php | 35 ++++ src/world/sound/DripleafTiltUpSound.php | 35 ++++ .../block_factory_consistency_check.json | 2 +- 18 files changed, 705 insertions(+), 2 deletions(-) create mode 100644 src/block/BaseBigDripleaf.php create mode 100644 src/block/BigDripleafHead.php create mode 100644 src/block/BigDripleafStem.php create mode 100644 src/block/SmallDripleaf.php create mode 100644 src/block/utils/DripleafState.php create mode 100644 src/world/sound/DripleafTiltDownSound.php create mode 100644 src/world/sound/DripleafTiltUpSound.php diff --git a/build/generate-runtime-enum-serializers.php b/build/generate-runtime-enum-serializers.php index 1273e26f8..805ed18e1 100644 --- a/build/generate-runtime-enum-serializers.php +++ b/build/generate-runtime-enum-serializers.php @@ -27,6 +27,7 @@ use pocketmine\block\utils\BellAttachmentType; use pocketmine\block\utils\CopperOxidation; use pocketmine\block\utils\CoralType; use pocketmine\block\utils\DirtType; +use pocketmine\block\utils\DripleafState; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\FroglightType; use pocketmine\block\utils\LeverFacing; @@ -145,6 +146,7 @@ $enumsUsed = [ CopperOxidation::getAll(), CoralType::getAll(), DirtType::getAll(), + DripleafState::getAll(), DyeColor::getAll(), FroglightType::getAll(), LeverFacing::getAll(), diff --git a/src/block/BaseBigDripleaf.php b/src/block/BaseBigDripleaf.php new file mode 100644 index 000000000..dcd81af0a --- /dev/null +++ b/src/block/BaseBigDripleaf.php @@ -0,0 +1,136 @@ +isHead() === $head) || + $block->getTypeId() === BlockTypeIds::CLAY || + $block->hasTypeTag(BlockTypeTags::DIRT) || + $block->hasTypeTag(BlockTypeTags::MUD); + } + + public function onNearbyBlockChange() : void{ + if( + (!$this->isHead() && !$this->getSide(Facing::UP) instanceof BaseBigDripleaf) || + !$this->canBeSupportedBy($this->getSide(Facing::DOWN), false) + ){ + $this->position->getWorld()->useBreakOn($this->position); + } + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + $block = $blockReplace->getSide(Facing::DOWN); + if(!$this->canBeSupportedBy($block, true)){ + return false; + } + if($player !== null){ + $this->facing = Facing::opposite($player->getHorizontalFacing()); + } + if($block instanceof BaseBigDripleaf){ + $this->facing = $block->getFacing(); + $tx->addBlock($block->getPosition(), VanillaBlocks::BIG_DRIPLEAF_STEM()->setFacing($this->facing)); + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ + if($item instanceof Fertilizer && $this->grow($player)){ + $item->pop(); + return true; + } + return false; + } + + private function seekToHead() : ?BaseBigDripleaf{ + if($this->isHead()){ + return $this; + } + $step = 1; + while(($next = $this->getSide(Facing::UP, $step)) instanceof BaseBigDripleaf){ + if($next->isHead()){ + return $next; + } + $step++; + } + return null; + } + + private function grow(?Player $player) : bool{ + $head = $this->seekToHead(); + if($head === null){ + return false; + } + $pos = $head->getPosition(); + $up = $pos->up(); + $world = $pos->getWorld(); + if( + !$world->isInWorld($up->getFloorX(), $up->getFloorY(), $up->getFloorZ()) || + $world->getBlock($up)->getTypeId() !== BlockTypeIds::AIR + ){ + return false; + } + + $tx = new BlockTransaction($world); + + $tx->addBlock($pos, VanillaBlocks::BIG_DRIPLEAF_STEM()->setFacing($head->getFacing())); + $tx->addBlock($up, VanillaBlocks::BIG_DRIPLEAF_HEAD()->setFacing($head->getFacing())); + + $ev = new StructureGrowEvent($head, $tx, $player); + $ev->call(); + + if(!$ev->isCancelled()){ + return $tx->apply(); + } + return false; + } + + public function getFlameEncouragement() : int{ + return 15; + } + + public function getFlammability() : int{ + return 100; + } + + public function getSupportType(int $facing) : SupportType{ + return SupportType::NONE(); + } +} diff --git a/src/block/BigDripleafHead.php b/src/block/BigDripleafHead.php new file mode 100644 index 000000000..d5bd226ca --- /dev/null +++ b/src/block/BigDripleafHead.php @@ -0,0 +1,132 @@ +leafState = DripleafState::STABLE(); + parent::__construct($idInfo, $name, $typeInfo); + } + + protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{ + parent::describeBlockOnlyState($w); + $w->dripleafState($this->leafState); + } + + protected function isHead() : bool{ + return true; + } + + public function getLeafState() : DripleafState{ + return $this->leafState; + } + + /** @return $this */ + public function setLeafState(DripleafState $leafState) : self{ + $this->leafState = $leafState; + return $this; + } + + public function hasEntityCollision() : bool{ + return true; + } + + private function setTiltAndScheduleTick(DripleafState $tilt) : void{ + $this->position->getWorld()->setBlock($this->position, $this->setLeafState($tilt)); + $delay = $tilt->getScheduledUpdateDelayTicks(); + if($delay !== null){ + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, $delay); + } + } + + private function getLeafTopOffset() : float{ + return match($this->leafState){ + DripleafState::STABLE(), DripleafState::UNSTABLE() => 1 / 16, + DripleafState::PARTIAL_TILT() => 3 / 16, + default => 0 + }; + } + + public function onEntityInside(Entity $entity) : bool{ + if(!$entity instanceof Projectile && $this->leafState->equals(DripleafState::STABLE())){ + //the entity must be standing on top of the leaf - do not collapse if the entity is standing underneath + $intersection = AxisAlignedBB::one() + ->offset($this->position->x, $this->position->y, $this->position->z) + ->trim(Facing::DOWN, 1 - $this->getLeafTopOffset()); + if($entity->getBoundingBox()->intersectsWith($intersection)){ + $this->setTiltAndScheduleTick(DripleafState::UNSTABLE()); + return false; + } + } + return true; + } + + public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{ + if(!$this->leafState->equals(DripleafState::FULL_TILT())){ + $this->setTiltAndScheduleTick(DripleafState::FULL_TILT()); + $this->position->getWorld()->addSound($this->position, new DripleafTiltDownSound()); + } + } + + public function onScheduledUpdate() : void{ + if(!$this->leafState->equals(DripleafState::STABLE())){ + if($this->leafState->equals(DripleafState::FULL_TILT())){ + $this->position->getWorld()->setBlock($this->position, $this->setLeafState(DripleafState::STABLE())); + $this->position->getWorld()->addSound($this->position, new DripleafTiltUpSound()); + }else{ + $this->setTiltAndScheduleTick(match($this->leafState->id()){ + DripleafState::UNSTABLE()->id() => DripleafState::PARTIAL_TILT(), + DripleafState::PARTIAL_TILT()->id() => DripleafState::FULL_TILT(), + default => throw new AssumptionFailedError("All types should be covered") + }); + $this->position->getWorld()->addSound($this->position, new DripleafTiltDownSound()); + } + } + } + + protected function recalculateCollisionBoxes() : array{ + if(!$this->leafState->equals(DripleafState::FULL_TILT())){ + return [ + AxisAlignedBB::one() + ->trim(Facing::DOWN, 11 / 16) + ->trim(Facing::UP, $this->getLeafTopOffset()) + ]; + } + return []; + } +} diff --git a/src/block/BigDripleafStem.php b/src/block/BigDripleafStem.php new file mode 100644 index 000000000..d44c47ccb --- /dev/null +++ b/src/block/BigDripleafStem.php @@ -0,0 +1,41 @@ +asItem(); + } +} diff --git a/src/block/BlockTypeIds.php b/src/block/BlockTypeIds.php index b48a1ed03..fe2101e1f 100644 --- a/src/block/BlockTypeIds.php +++ b/src/block/BlockTypeIds.php @@ -733,8 +733,11 @@ final class BlockTypeIds{ public const CHERRY_TRAPDOOR = 10703; public const CHERRY_WALL_SIGN = 10704; public const CHERRY_WOOD = 10705; + public const SMALL_DRIPLEAF = 10706; + public const BIG_DRIPLEAF_HEAD = 10707; + public const BIG_DRIPLEAF_STEM = 10708; - public const FIRST_UNUSED_BLOCK_ID = 10706; + public const FIRST_UNUSED_BLOCK_ID = 10709; private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID; diff --git a/src/block/SmallDripleaf.php b/src/block/SmallDripleaf.php new file mode 100644 index 000000000..e08e6f6e9 --- /dev/null +++ b/src/block/SmallDripleaf.php @@ -0,0 +1,170 @@ +horizontalFacing($this->facing); + $w->bool($this->top); + } + + public function isTop() : bool{ + return $this->top; + } + + /** @return $this */ + public function setTop(bool $top) : self{ + $this->top = $top; + return $this; + } + + private function canBeSupportedBy(Block $block) : bool{ + //TODO: Moss + //TODO: Small Dripleaf also can be placed on dirt, coarse dirt, farmland, grass blocks, + // podzol, rooted dirt, mycelium, and mud if these blocks are underwater (needs waterlogging) + return $block->getTypeId() === BlockTypeIds::CLAY; + } + + public function onNearbyBlockChange() : void{ + if(!$this->top && !$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + $this->position->getWorld()->useBreakOn($this->position); + return; + } + $face = $this->top ? Facing::DOWN : Facing::UP; + if(!$this->getSide($face)->hasSameTypeId($this)){ + $this->position->getWorld()->useBreakOn($this->position); + } + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + $block = $blockReplace->getSide(Facing::UP); + if($block->getTypeId() !== BlockTypeIds::AIR || !$this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + return false; + } + if($player !== null){ + $this->facing = Facing::opposite($player->getHorizontalFacing()); + } + + $tx->addBlock($block->getPosition(), VanillaBlocks::SMALL_DRIPLEAF() + ->setFacing($this->facing) + ->setTop(true) + ); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ + if($item instanceof Fertilizer && $this->grow($player)){ + $item->pop(); + return true; + } + return false; + } + + private function canGrowTo(Position $pos) : bool{ + $world = $pos->getWorld(); + if(!$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ())){ + return false; + } + $block = $world->getBlock($pos); + return $block->hasSameTypeId($this) || $block->getTypeId() === BlockTypeIds::AIR; + } + + private function grow(?Player $player) : bool{ + $bottomBlock = $this->top ? $this->getSide(Facing::DOWN) : $this; + if(!$this->hasSameTypeId($bottomBlock)){ + return false; + } + $world = $this->position->getWorld(); + $tx = new BlockTransaction($world); + $height = mt_rand(2, 5); + $grown = 0; + for($i = 0; $i < $height; $i++){ + $pos = $bottomBlock->getSide(Facing::UP, $i)->getPosition(); + if(!$this->canGrowTo($pos)){ + break; + } + $block = ++$grown < $height && $this->canGrowTo($pos->getSide(Facing::UP)) ? + VanillaBlocks::BIG_DRIPLEAF_STEM() : + VanillaBlocks::BIG_DRIPLEAF_HEAD(); + $tx->addBlock($pos, $block->setFacing($this->facing)); + } + if($grown > 1){ + $ev = new StructureGrowEvent($bottomBlock, $tx, $player); + $ev->call(); + if(!$ev->isCancelled()){ + return $tx->apply(); + } + } + + return false; + } + + public function getAffectedBlocks() : array{ + $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); + if($other->hasSameTypeId($this)){ + return [$this, $other]; + } + return parent::getAffectedBlocks(); + } + + public function getDropsForCompatibleTool(Item $item) : array{ + if(!$this->top){ + return [$this->asItem()]; + } + return []; + } + + public function getFlameEncouragement() : int{ + return 15; + } + + public function getFlammability() : int{ + return 100; + } + + public function getSupportType(int $facing) : SupportType{ + return SupportType::NONE(); + } + + protected function recalculateCollisionBoxes() : array{ + return []; + } +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index a45e18a1e..9f2996abd 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -113,6 +113,8 @@ use function mb_strtolower; * @method static Bedrock BEDROCK() * @method static Beetroot BEETROOTS() * @method static Bell BELL() + * @method static BigDripleafHead BIG_DRIPLEAF_HEAD() + * @method static BigDripleafStem BIG_DRIPLEAF_STEM() * @method static WoodenButton BIRCH_BUTTON() * @method static WoodenDoor BIRCH_DOOR() * @method static WoodenFence BIRCH_FENCE() @@ -658,6 +660,7 @@ use function mb_strtolower; * @method static Opaque SHROOMLIGHT() * @method static ShulkerBox SHULKER_BOX() * @method static Slime SLIME() + * @method static SmallDripleaf SMALL_DRIPLEAF() * @method static SmithingTable SMITHING_TABLE() * @method static Furnace SMOKER() * @method static Opaque SMOOTH_BASALT() @@ -1598,6 +1601,10 @@ final class VanillaBlocks{ self::register("hanging_roots", new HangingRoots(new BID(Ids::HANGING_ROOTS), "Hanging Roots", new Info(BreakInfo::instant(ToolType::SHEARS, 1)))); self::register("cave_vines", new CaveVines(new BID(Ids::CAVE_VINES), "Cave Vines", new Info(BreakInfo::instant()))); + + self::register("small_dripleaf", new SmallDripleaf(new BID(Ids::SMALL_DRIPLEAF), "Small Dripleaf", new Info(BreakInfo::instant(BlockToolType::SHEARS, toolHarvestLevel: 1)))); + self::register("big_dripleaf_head", new BigDripleafHead(new BID(Ids::BIG_DRIPLEAF_HEAD), "Big Dripleaf", new Info(BreakInfo::instant()))); + self::register("big_dripleaf_stem", new BigDripleafStem(new BID(Ids::BIG_DRIPLEAF_STEM), "Big Dripleaf Stem", new Info(BreakInfo::instant()))); } private static function registerBlocksR18() : void{ diff --git a/src/block/utils/DripleafState.php b/src/block/utils/DripleafState.php new file mode 100644 index 000000000..3c2e20a13 --- /dev/null +++ b/src/block/utils/DripleafState.php @@ -0,0 +1,65 @@ +Enum___construct($enumName); + } + + public function getScheduledUpdateDelayTicks() : ?int{ + return $this->scheduledUpdateDelayTicks; + } + +} diff --git a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php index 0ba6496dd..8ec9a1ddc 100644 --- a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php +++ b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php @@ -31,6 +31,8 @@ use pocketmine\block\Barrel; use pocketmine\block\Bed; use pocketmine\block\Beetroot; use pocketmine\block\Bell; +use pocketmine\block\BigDripleafHead; +use pocketmine\block\BigDripleafStem; use pocketmine\block\Block; use pocketmine\block\BoneBlock; use pocketmine\block\BrewingStand; @@ -115,6 +117,7 @@ use pocketmine\block\SeaPickle; use pocketmine\block\SimplePillar; use pocketmine\block\SimplePressurePlate; use pocketmine\block\Slab; +use pocketmine\block\SmallDripleaf; use pocketmine\block\SnowLayer; use pocketmine\block\Sponge; use pocketmine\block\StainedGlass; @@ -138,6 +141,7 @@ use pocketmine\block\UnderwaterTorch; use pocketmine\block\utils\BrewingStandSlot; use pocketmine\block\utils\CoralType; use pocketmine\block\utils\DirtType; +use pocketmine\block\utils\DripleafState; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\FroglightType; use pocketmine\block\utils\LeverFacing; @@ -958,6 +962,24 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ->writeLegacyHorizontalFacing($block->getFacing()); }); + $this->map(Blocks::BIG_DRIPLEAF_HEAD(), function(BigDripleafHead $block) : Writer{ + return Writer::create(Ids::BIG_DRIPLEAF) + ->writeLegacyHorizontalFacing($block->getFacing()) + ->writeString(StateNames::BIG_DRIPLEAF_TILT, match($block->getLeafState()->id()){ + DripleafState::STABLE()->id() => StringValues::BIG_DRIPLEAF_TILT_NONE, + DripleafState::UNSTABLE()->id() => StringValues::BIG_DRIPLEAF_TILT_UNSTABLE, + DripleafState::PARTIAL_TILT()->id() => StringValues::BIG_DRIPLEAF_TILT_PARTIAL_TILT, + DripleafState::FULL_TILT()->id() => StringValues::BIG_DRIPLEAF_TILT_FULL_TILT, + default => throw new BlockStateSerializeException("Invalid Dripleaf tilt type " . $block->getLeafState()->name()) + }) + ->writeBool(StateNames::BIG_DRIPLEAF_HEAD, true); + }); + $this->map(Blocks::BIG_DRIPLEAF_STEM(), function(BigDripleafStem $block) : Writer{ + return Writer::create(Ids::BIG_DRIPLEAF) + ->writeLegacyHorizontalFacing($block->getFacing()) + ->writeString(StateNames::BIG_DRIPLEAF_TILT, StringValues::BIG_DRIPLEAF_TILT_NONE) + ->writeBool(StateNames::BIG_DRIPLEAF_HEAD, false); + }); $this->map(Blocks::BIRCH_SAPLING(), fn(Sapling $block) => Helper::encodeSapling($block, StringValues::SAPLING_TYPE_BIRCH)); $this->mapSlab(Blocks::BLACKSTONE_SLAB(), Ids::BLACKSTONE_SLAB, Ids::BLACKSTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::BLACKSTONE_STAIRS(), Ids::BLACKSTONE_STAIRS); @@ -1454,6 +1476,11 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ->writeBool(StateNames::DEAD_BIT, !$block->isUnderwater()) ->writeInt(StateNames::CLUSTER_COUNT, $block->getCount() - 1); }); + $this->map(Blocks::SMALL_DRIPLEAF(), function(SmallDripleaf $block) : Writer{ + return Writer::create(Ids::SMALL_DRIPLEAF_BLOCK) + ->writeLegacyHorizontalFacing($block->getFacing()) + ->writeBool(StateNames::UPPER_BLOCK_BIT, $block->isTop()); + }); $this->map(Blocks::SMOKER(), fn(Furnace $block) => Helper::encodeFurnace($block, Ids::SMOKER, Ids::LIT_SMOKER)); $this->map(Blocks::SMOOTH_QUARTZ(), fn() => Helper::encodeQuartz(StringValues::CHISEL_TYPE_SMOOTH, Axis::Y)); $this->map(Blocks::SMOOTH_QUARTZ_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab4($block, StringValues::STONE_SLAB_TYPE_4_SMOOTH_QUARTZ)); diff --git a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php index 65b896523..08c9b5914 100644 --- a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php +++ b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php @@ -35,6 +35,7 @@ use pocketmine\block\utils\BrewingStandSlot; use pocketmine\block\utils\CopperOxidation; use pocketmine\block\utils\CoralType; use pocketmine\block\utils\DirtType; +use pocketmine\block\utils\DripleafState; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\FroglightType; use pocketmine\block\utils\LeverFacing; @@ -826,6 +827,22 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ ->setFacing($in->readLegacyHorizontalFacing()) ->setAttachmentType($in->readBellAttachmentType()); }); + $this->map(Ids::BIG_DRIPLEAF, function(Reader $in) : Block{ + if($in->readBool(StateNames::BIG_DRIPLEAF_HEAD)){ + return Blocks::BIG_DRIPLEAF_HEAD() + ->setFacing($in->readLegacyHorizontalFacing()) + ->setLeafState(match($type = $in->readString(StateNames::BIG_DRIPLEAF_TILT)){ + StringValues::BIG_DRIPLEAF_TILT_NONE => DripleafState::STABLE(), + StringValues::BIG_DRIPLEAF_TILT_UNSTABLE => DripleafState::UNSTABLE(), + StringValues::BIG_DRIPLEAF_TILT_PARTIAL_TILT => DripleafState::PARTIAL_TILT(), + StringValues::BIG_DRIPLEAF_TILT_FULL_TILT => DripleafState::FULL_TILT(), + default => throw $in->badValueException(StateNames::BIG_DRIPLEAF_TILT, $type), + }); + }else{ + $in->ignored(StateNames::BIG_DRIPLEAF_TILT); + return Blocks::BIG_DRIPLEAF_STEM()->setFacing($in->readLegacyHorizontalFacing()); + } + }); $this->mapSlab(Ids::BLACKSTONE_SLAB, Ids::BLACKSTONE_DOUBLE_SLAB, fn() => Blocks::BLACKSTONE_SLAB()); $this->mapStairs(Ids::BLACKSTONE_STAIRS, fn() => Blocks::BLACKSTONE_STAIRS()); $this->map(Ids::BLACKSTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::BLACKSTONE_WALL(), $in)); @@ -1332,6 +1349,11 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ ->setFacing($in->readHorizontalFacing()) ->setLit(false); }); + $this->map(Ids::SMALL_DRIPLEAF_BLOCK, function(Reader $in) : Block{ + return Blocks::SMALL_DRIPLEAF() + ->setFacing($in->readLegacyHorizontalFacing()) + ->setTop($in->readBool(StateNames::UPPER_BLOCK_BIT)); + }); $this->mapStairs(Ids::SMOOTH_QUARTZ_STAIRS, fn() => Blocks::SMOOTH_QUARTZ_STAIRS()); $this->mapStairs(Ids::SMOOTH_RED_SANDSTONE_STAIRS, fn() => Blocks::SMOOTH_RED_SANDSTONE_STAIRS()); $this->mapStairs(Ids::SMOOTH_SANDSTONE_STAIRS, fn() => Blocks::SMOOTH_SANDSTONE_STAIRS()); diff --git a/src/data/runtime/RuntimeEnumDescriber.php b/src/data/runtime/RuntimeEnumDescriber.php index 643ecd301..7103017f7 100644 --- a/src/data/runtime/RuntimeEnumDescriber.php +++ b/src/data/runtime/RuntimeEnumDescriber.php @@ -37,6 +37,8 @@ interface RuntimeEnumDescriber{ public function dirtType(\pocketmine\block\utils\DirtType &$value) : void; + public function dripleafState(\pocketmine\block\utils\DripleafState &$value) : void; + public function dyeColor(\pocketmine\block\utils\DyeColor &$value) : void; public function froglightType(\pocketmine\block\utils\FroglightType &$value) : void; diff --git a/src/data/runtime/RuntimeEnumDeserializerTrait.php b/src/data/runtime/RuntimeEnumDeserializerTrait.php index 4774304a9..7d80a6f54 100644 --- a/src/data/runtime/RuntimeEnumDeserializerTrait.php +++ b/src/data/runtime/RuntimeEnumDeserializerTrait.php @@ -71,6 +71,16 @@ trait RuntimeEnumDeserializerTrait{ }; } + public function dripleafState(\pocketmine\block\utils\DripleafState &$value) : void{ + $value = match($this->readInt(2)){ + 0 => \pocketmine\block\utils\DripleafState::FULL_TILT(), + 1 => \pocketmine\block\utils\DripleafState::PARTIAL_TILT(), + 2 => \pocketmine\block\utils\DripleafState::STABLE(), + 3 => \pocketmine\block\utils\DripleafState::UNSTABLE(), + default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for DripleafState") + }; + } + public function dyeColor(\pocketmine\block\utils\DyeColor &$value) : void{ $value = match($this->readInt(4)){ 0 => \pocketmine\block\utils\DyeColor::BLACK(), diff --git a/src/data/runtime/RuntimeEnumSerializerTrait.php b/src/data/runtime/RuntimeEnumSerializerTrait.php index c570046c6..8c3d67118 100644 --- a/src/data/runtime/RuntimeEnumSerializerTrait.php +++ b/src/data/runtime/RuntimeEnumSerializerTrait.php @@ -71,6 +71,16 @@ trait RuntimeEnumSerializerTrait{ }); } + public function dripleafState(\pocketmine\block\utils\DripleafState &$value) : void{ + $this->writeInt(2, match($value){ + \pocketmine\block\utils\DripleafState::FULL_TILT() => 0, + \pocketmine\block\utils\DripleafState::PARTIAL_TILT() => 1, + \pocketmine\block\utils\DripleafState::STABLE() => 2, + \pocketmine\block\utils\DripleafState::UNSTABLE() => 3, + default => throw new \pocketmine\utils\AssumptionFailedError("All DripleafState cases should be covered") + }); + } + public function dyeColor(\pocketmine\block\utils\DyeColor &$value) : void{ $this->writeInt(4, match($value){ \pocketmine\block\utils\DyeColor::BLACK() => 0, diff --git a/src/data/runtime/RuntimeEnumSizeCalculatorTrait.php b/src/data/runtime/RuntimeEnumSizeCalculatorTrait.php index 3c8d189e1..2ab62f03e 100644 --- a/src/data/runtime/RuntimeEnumSizeCalculatorTrait.php +++ b/src/data/runtime/RuntimeEnumSizeCalculatorTrait.php @@ -47,6 +47,10 @@ trait RuntimeEnumSizeCalculatorTrait{ $this->addBits(2); } + public function dripleafState(\pocketmine\block\utils\DripleafState &$value) : void{ + $this->addBits(2); + } + public function dyeColor(\pocketmine\block\utils\DyeColor &$value) : void{ $this->addBits(4); } diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index e5e5252e1..ea9923c21 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -155,6 +155,7 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("beetroot_block", fn() => Blocks::BEETROOTS()); $result->registerBlock("beetroots", fn() => Blocks::BEETROOTS()); $result->registerBlock("bell", fn() => Blocks::BELL()); + $result->registerBlock("big_dripleaf", fn() => Blocks::BIG_DRIPLEAF_HEAD()); $result->registerBlock("birch_button", fn() => Blocks::BIRCH_BUTTON()); $result->registerBlock("birch_door", fn() => Blocks::BIRCH_DOOR()); $result->registerBlock("birch_door_block", fn() => Blocks::BIRCH_DOOR()); @@ -972,6 +973,7 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("slabs", fn() => Blocks::SMOOTH_STONE_SLAB()); $result->registerBlock("slime", fn() => Blocks::SLIME()); $result->registerBlock("slime_block", fn() => Blocks::SLIME()); + $result->registerBlock("small_dripleaf", fn() => Blocks::SMALL_DRIPLEAF()); $result->registerBlock("smoker", fn() => Blocks::SMOKER()); $result->registerBlock("smooth_basalt", fn() => Blocks::SMOOTH_BASALT()); $result->registerBlock("smooth_quartz", fn() => Blocks::SMOOTH_QUARTZ()); diff --git a/src/world/sound/DripleafTiltDownSound.php b/src/world/sound/DripleafTiltDownSound.php new file mode 100644 index 000000000..1366f1b71 --- /dev/null +++ b/src/world/sound/DripleafTiltDownSound.php @@ -0,0 +1,35 @@ + Date: Tue, 18 Jul 2023 14:31:20 +0300 Subject: [PATCH 09/25] Stem: fixed supporting block check issue (#5907) This bug was introduced in https://github.com/pmmp/PocketMine-MP/commit/dca752c72f8daeb669dacebf67b0e093cbe366c4 --- src/block/Stem.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/block/Stem.php b/src/block/Stem.php index b0d49b28e..252b28aeb 100644 --- a/src/block/Stem.php +++ b/src/block/Stem.php @@ -55,6 +55,7 @@ abstract class Stem extends Crops{ if($this->facing !== Facing::UP && !$this->getSide($this->facing)->hasSameTypeId($this->getPlant())){ $this->position->getWorld()->setBlock($this->position, $this->setFacing(Facing::UP)); } + parent::onNearbyBlockChange(); } public function onRandomTick() : void{ From a74ab756bd67edde77828a618e2dea05ae0f2748 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jul 2023 12:45:30 +0100 Subject: [PATCH 10/25] AsyncTask: strip out task cancellation functionality closes #5854 Cancelling task runs doesn't make any sense. - It breaks sequential task execution - later tasks might depend on state from earlier tasks - It doesn't actually cancel the task - at best, it prevents it from running, but cannot interrupt it (though interrupting a task does not make sense either) We don't use this "feature" in the core anymore since 22b5e5db5e822ac94ed3978ea75bbadcfa8e7f4f, as this was causing unexpected behaviour for plugins anyway, along with the occasional shutdown crash due to inconsistent worker states. --- src/scheduler/AsyncPool.php | 2 +- src/scheduler/AsyncTask.php | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index a326bc87f..7540294ef 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -259,7 +259,7 @@ class AsyncPool{ if($task->isTerminated()){ $this->checkCrashedWorker($worker, $task); throw new AssumptionFailedError("checkCrashedWorker() should have thrown an exception, making this unreachable"); - }elseif(!$task->hasCancelledRun()){ + }else{ /* * It's possible for a task to submit a progress update and then finish before the progress * update is detected by the parent thread, so here we consume any missed updates. diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index 9d69bda5b..ba5cc424c 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -72,17 +72,14 @@ abstract class AsyncTask extends Runnable{ private ?ThreadSafeArray $progressUpdates = null; private ThreadSafe|string|int|bool|null|float $result = null; - private bool $cancelRun = false; - private bool $submitted = false; + private bool $submitted = false; private bool $finished = false; public function run() : void{ $this->result = null; - if(!$this->cancelRun){ - $this->onRun(); - } + $this->onRun(); $this->finished = true; $worker = NativeThread::getCurrentThread(); @@ -123,12 +120,18 @@ abstract class AsyncTask extends Runnable{ $this->result = is_scalar($result) || is_null($result) || $result instanceof ThreadSafe ? $result : new NonThreadSafeValue($result); } + /** + * @deprecated + */ public function cancelRun() : void{ - $this->cancelRun = true; + //NOOP } + /** + * @deprecated + */ public function hasCancelledRun() : bool{ - return $this->cancelRun; + return false; } public function setSubmitted() : void{ From 537721fe7d845bd369fe456ae0f28fc40e8ff4ef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 13:34:42 +0100 Subject: [PATCH 11/25] Replace Closure::fromCallable() usages with first-class callables PHP 8.1 <3 --- src/block/Liquid.php | 2 +- src/crafting/CraftingManagerFromDataHelper.php | 11 ++++------- src/network/mcpe/InventoryManager.php | 2 +- src/network/mcpe/NetworkSession.php | 4 ++-- src/world/World.php | 6 +++--- src/world/format/io/WorldProviderManager.php | 8 ++++---- .../phpstan/rules/UnsafeForeachArrayOfStringRule.php | 2 +- 7 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 98f1d5627..a56f666a2 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -312,7 +312,7 @@ abstract class Liquid extends Transparent{ } if($adjacentDecay <= self::MAX_DECAY){ - $calculator = new MinimumCostFlowCalculator($world, $this->getFlowDecayPerBlock(), \Closure::fromCallable([$this, 'canFlowInto'])); + $calculator = new MinimumCostFlowCalculator($world, $this->getFlowDecayPerBlock(), $this->canFlowInto(...)); foreach($calculator->getOptimalFlowDirections($this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ()) as $facing){ $this->flowIntoBlock($world->getBlock($this->position->getSide($facing)), $adjacentDecay, false); } diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php index 0a28ca328..812ff83e0 100644 --- a/src/crafting/CraftingManagerFromDataHelper.php +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -209,9 +209,6 @@ final class CraftingManagerFromDataHelper{ public static function make(string $directoryPath) : CraftingManager{ $result = new CraftingManager(); - $ingredientDeserializerFunc = \Closure::fromCallable([self::class, "deserializeIngredient"]); - $itemDeserializerFunc = \Closure::fromCallable([self::class, 'deserializeItemStack']); - foreach(self::loadJsonArrayOfObjectsFile(Path::join($directoryPath, 'shapeless_crafting.json'), ShapelessRecipeData::class) as $recipe){ $recipeType = match($recipe->block){ "crafting_table" => ShapelessRecipeType::CRAFTING(), @@ -225,7 +222,7 @@ final class CraftingManagerFromDataHelper{ } $inputs = []; foreach($recipe->input as $inputData){ - $input = $ingredientDeserializerFunc($inputData); + $input = self::deserializeIngredient($inputData); if($input === null){ //unknown input item continue 2; } @@ -233,7 +230,7 @@ final class CraftingManagerFromDataHelper{ } $outputs = []; foreach($recipe->output as $outputData){ - $output = $itemDeserializerFunc($outputData); + $output = self::deserializeItemStack($outputData); if($output === null){ //unknown output item continue 2; } @@ -251,7 +248,7 @@ final class CraftingManagerFromDataHelper{ } $inputs = []; foreach(Utils::stringifyKeys($recipe->input) as $symbol => $inputData){ - $input = $ingredientDeserializerFunc($inputData); + $input = self::deserializeIngredient($inputData); if($input === null){ //unknown input item continue 2; } @@ -259,7 +256,7 @@ final class CraftingManagerFromDataHelper{ } $outputs = []; foreach($recipe->output as $outputData){ - $output = $itemDeserializerFunc($outputData); + $output = self::deserializeItemStack($outputData); if($output === null){ //unknown output item continue 2; } diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index a94dbe946..316abfd3e 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -108,7 +108,7 @@ class InventoryManager{ private NetworkSession $session ){ $this->containerOpenCallbacks = new ObjectSet(); - $this->containerOpenCallbacks->add(\Closure::fromCallable([self::class, 'createContainerOpen'])); + $this->containerOpenCallbacks->add(self::createContainerOpen(...)); $this->add(ContainerIds::INVENTORY, $this->player->getInventory()); $this->add(ContainerIds::OFFHAND, $this->player->getOffHandInventory()); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index b10e7f25a..252db34cf 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -225,13 +225,13 @@ class NetworkSession{ $this->logger->setPrefix($this->getLogPrefix()); $this->manager->markLoginReceived($this); }, - \Closure::fromCallable([$this, "setAuthenticationStatus"]) + $this->setAuthenticationStatus(...) )); } protected function createPlayer() : void{ $this->server->createPlayer($this, $this->info, $this->authenticated, $this->cachedOfflinePlayerData)->onCompletion( - \Closure::fromCallable([$this, 'onPlayerCreated']), + $this->onPlayerCreated(...), function() : void{ //TODO: this should never actually occur... right? $this->logger->error("Failed to create player"); diff --git a/src/world/World.php b/src/world/World.php index deb03ef6d..f556d2e1f 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1610,7 +1610,7 @@ class World implements ChunkManager{ * the current weather and time of day. */ public function getHighestAdjacentFullLightAt(int $x, int $y, int $z) : int{ - return $this->getHighestAdjacentLight($x, $y, $z, \Closure::fromCallable([$this, 'getFullLightAt'])); + return $this->getHighestAdjacentLight($x, $y, $z, $this->getFullLightAt(...)); } /** @@ -1706,7 +1706,7 @@ class World implements ChunkManager{ * Returns the highest potential level of sky light in the positions adjacent to the specified block coordinates. */ public function getHighestAdjacentPotentialBlockSkyLight(int $x, int $y, int $z) : int{ - return $this->getHighestAdjacentLight($x, $y, $z, \Closure::fromCallable([$this, 'getPotentialBlockSkyLightAt'])); + return $this->getHighestAdjacentLight($x, $y, $z, $this->getPotentialBlockSkyLightAt(...)); } /** @@ -1721,7 +1721,7 @@ class World implements ChunkManager{ * Returns the highest block light level available in the positions adjacent to the specified block coordinates. */ public function getHighestAdjacentBlockLight(int $x, int $y, int $z) : int{ - return $this->getHighestAdjacentLight($x, $y, $z, \Closure::fromCallable([$this, 'getBlockLightAt'])); + return $this->getHighestAdjacentLight($x, $y, $z, $this->getBlockLightAt(...)); } private function executeQueuedLightUpdates() : void{ diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index 8a30bcb57..1767c539a 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -41,13 +41,13 @@ final class WorldProviderManager{ private WritableWorldProviderManagerEntry $default; public function __construct(){ - $leveldb = new WritableWorldProviderManagerEntry(\Closure::fromCallable([LevelDB::class, 'isValid']), fn(string $path, \Logger $logger) => new LevelDB($path, $logger), \Closure::fromCallable([LevelDB::class, 'generate'])); + $leveldb = new WritableWorldProviderManagerEntry(LevelDB::isValid(...), fn(string $path, \Logger $logger) => new LevelDB($path, $logger), LevelDB::generate(...)); $this->default = $leveldb; $this->addProvider($leveldb, "leveldb"); - $this->addProvider(new ReadOnlyWorldProviderManagerEntry(\Closure::fromCallable([Anvil::class, 'isValid']), fn(string $path, \Logger $logger) => new Anvil($path, $logger)), "anvil"); - $this->addProvider(new ReadOnlyWorldProviderManagerEntry(\Closure::fromCallable([McRegion::class, 'isValid']), fn(string $path, \Logger $logger) => new McRegion($path, $logger)), "mcregion"); - $this->addProvider(new ReadOnlyWorldProviderManagerEntry(\Closure::fromCallable([PMAnvil::class, 'isValid']), fn(string $path, \Logger $logger) => new PMAnvil($path, $logger)), "pmanvil"); + $this->addProvider(new ReadOnlyWorldProviderManagerEntry(Anvil::isValid(...), fn(string $path, \Logger $logger) => new Anvil($path, $logger)), "anvil"); + $this->addProvider(new ReadOnlyWorldProviderManagerEntry(McRegion::isValid(...), fn(string $path, \Logger $logger) => new McRegion($path, $logger)), "mcregion"); + $this->addProvider(new ReadOnlyWorldProviderManagerEntry(PMAnvil::isValid(...), fn(string $path, \Logger $logger) => new PMAnvil($path, $logger)), "pmanvil"); } /** diff --git a/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php b/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php index d53baa365..e42d32927 100644 --- a/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php +++ b/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php @@ -78,7 +78,7 @@ final class UnsafeForeachArrayOfStringRule implements Rule{ return $type; }); if($hasCastableKeyTypes && !$expectsIntKeyTypes){ - $func = \Closure::fromCallable([Utils::class, 'stringifyKeys']); + $func = Utils::stringifyKeys(...); return [ RuleErrorBuilder::message(sprintf( "Unsafe foreach on array with key type %s (they might be casted to int).", From 914dd90b3d2fb60b87cbd5f8b0fdeb1264c1173f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 13:56:48 +0100 Subject: [PATCH 12/25] Use first-class closures in more places --- src/Server.php | 2 +- src/network/mcpe/InventoryManager.php | 4 +--- src/network/mcpe/NetworkSession.php | 10 +++------- src/network/mcpe/cache/CraftingDataCache.php | 12 +++--------- src/utils/RegistryTrait.php | 4 +--- 5 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/Server.php b/src/Server.php index f604c93d7..530b8d469 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1009,7 +1009,7 @@ class Server{ $this->playerDataProvider = new DatFilePlayerDataProvider(Path::join($this->dataPath, "players")); - register_shutdown_function([$this, "crashDump"]); + register_shutdown_function($this->crashDump(...)); $loadErrorCount = 0; $this->pluginManager->loadPlugins($this->pluginPath, $loadErrorCount); diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 316abfd3e..254eff910 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -116,9 +116,7 @@ class InventoryManager{ $this->addComplex(UIInventorySlotOffset::CURSOR, $this->player->getCursorInventory()); $this->addComplex(UIInventorySlotOffset::CRAFTING2X2_INPUT, $this->player->getCraftingGrid()); - $this->player->getInventory()->getHeldItemIndexChangeListeners()->add(function() : void{ - $this->syncSelectedHotbarSlot(); - }); + $this->player->getInventory()->getHeldItemIndexChangeListeners()->add($this->syncSelectedHotbarSlot(...)); } private function associateIdWithInventory(int $id, Inventory $inventory) : void{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 252db34cf..dbd857b0f 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -197,7 +197,7 @@ class NetworkSession{ $this->setHandler(new SessionStartPacketHandler( $this, - fn() => $this->onSessionStartSuccess() + $this->onSessionStartSuccess(...) )); $this->manager->add($this); @@ -787,9 +787,7 @@ class NetworkSession{ $this->cipher = EncryptionContext::fakeGCM($encryptionKey); - $this->setHandler(new HandshakePacketHandler(function() : void{ - $this->onServerLoginSuccess(); - })); + $this->setHandler(new HandshakePacketHandler($this->onServerLoginSuccess(...))); $this->logger->debug("Enabled encryption"); })); }else{ @@ -818,9 +816,7 @@ class NetworkSession{ public function notifyTerrainReady() : void{ $this->logger->debug("Sending spawn notification, waiting for spawn response"); $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::PLAYER_SPAWN)); - $this->setHandler(new SpawnResponsePacketHandler(function() : void{ - $this->onClientSpawnResponse(); - })); + $this->setHandler(new SpawnResponsePacketHandler($this->onClientSpawnResponse(...))); } private function onClientSpawnResponse() : void{ diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index e6ac6167b..58aa94a88 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -95,12 +95,8 @@ final class CraftingDataCache{ $recipesWithTypeIds[] = new ProtocolShapelessRecipe( CraftingDataPacket::ENTRY_SHAPELESS, Binary::writeInt($index), - array_map(function(RecipeIngredient $item) use ($converter) : ProtocolRecipeIngredient{ - return $converter->coreRecipeIngredientToNet($item); - }, $recipe->getIngredientList()), - array_map(function(Item $item) use ($converter) : ItemStack{ - return $converter->coreItemStackToNet($item); - }, $recipe->getResults()), + array_map($converter->coreRecipeIngredientToNet(...), $recipe->getIngredientList()), + array_map($converter->coreItemStackToNet(...), $recipe->getResults()), $nullUUID, $typeTag, 50, @@ -118,9 +114,7 @@ final class CraftingDataCache{ CraftingDataPacket::ENTRY_SHAPED, Binary::writeInt($index), $inputs, - array_map(function(Item $item) use ($converter) : ItemStack{ - return $converter->coreItemStackToNet($item); - }, $recipe->getResults()), + array_map($converter->coreItemStackToNet(...), $recipe->getResults()), $nullUUID, CraftingRecipeBlockName::CRAFTING_TABLE, 50, diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index f8ffc1143..573f4737f 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -121,8 +121,6 @@ trait RegistryTrait{ */ private static function _registryGetAll() : array{ self::checkInit(); - return array_map(function(object $o) : object{ - return self::preprocessMember($o); - }, self::$members); + return array_map(self::preprocessMember(...), self::$members); } } From 3c34841dfc351f9ce795c71866538c7e26964f62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Jul 2023 14:00:35 +0100 Subject: [PATCH 13/25] CS --- src/network/mcpe/cache/CraftingDataCache.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 58aa94a88..aa70c7d35 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -25,21 +25,17 @@ namespace pocketmine\network\mcpe\cache; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\FurnaceType; -use pocketmine\crafting\RecipeIngredient; use pocketmine\crafting\ShapedRecipe; use pocketmine\crafting\ShapelessRecipe; use pocketmine\crafting\ShapelessRecipeType; -use pocketmine\item\Item; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\CraftingDataPacket; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\recipe\CraftingRecipeBlockName; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe as ProtocolFurnaceRecipe; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipeBlockName; use pocketmine\network\mcpe\protocol\types\recipe\IntIdMetaItemDescriptor; use pocketmine\network\mcpe\protocol\types\recipe\PotionContainerChangeRecipe as ProtocolPotionContainerChangeRecipe; use pocketmine\network\mcpe\protocol\types\recipe\PotionTypeRecipe as ProtocolPotionTypeRecipe; -use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient as ProtocolRecipeIngredient; use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe as ProtocolShapedRecipe; use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe as ProtocolShapelessRecipe; use pocketmine\timings\Timings; From 5899f2fc1d39175ce7bf0672cc6c09514779b5f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Jul 2023 15:02:25 +0100 Subject: [PATCH 14/25] Block: introduce new methods to reduce support type boilerplate checks this switches from a 'can be supported by' concept to a 'can stay at this position' paradigm, which requires way less boilerplate code. there may be further improvements we can make from here, such as adding traits, but this is a good first step. --- src/block/BaseRail.php | 4 ++-- src/block/Bed.php | 8 ++++---- src/block/Bell.php | 20 ++++++++++---------- src/block/Block.php | 5 +++++ src/block/Button.php | 8 ++++---- src/block/Candle.php | 3 +-- src/block/CaveVines.php | 8 ++++---- src/block/Coral.php | 8 ++++---- src/block/Door.php | 9 ++++----- src/block/FloorCoralFan.php | 8 ++++---- src/block/FlowerPot.php | 8 ++++---- src/block/GlowLichen.php | 4 ++-- src/block/ItemFrame.php | 8 ++++---- src/block/Ladder.php | 8 ++++---- src/block/Lantern.php | 11 ++++++----- src/block/Lever.php | 9 ++++----- src/block/NetherVines.php | 13 +++++-------- src/block/PressurePlate.php | 8 ++++---- src/block/RedstoneComparator.php | 8 ++++---- src/block/RedstoneRepeater.php | 8 ++++---- src/block/RedstoneWire.php | 8 ++++---- src/block/SnowLayer.php | 6 +++--- src/block/SporeBlossom.php | 8 ++++---- src/block/Torch.php | 17 +++++++---------- src/block/WallCoralFan.php | 8 ++++---- 25 files changed, 105 insertions(+), 108 deletions(-) diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index 971beffac..0bcb2f340 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -38,7 +38,7 @@ use function in_array; abstract class BaseRail extends Flowable{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($blockReplace->getSide(Facing::DOWN)->getSupportType(Facing::UP)->hasEdgeSupport()){ + if($blockReplace->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport()){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -222,7 +222,7 @@ abstract class BaseRail extends Flowable{ public function onNearbyBlockChange() : void{ $world = $this->position->getWorld(); - if(!$this->getSide(Facing::DOWN)->getSupportType(Facing::UP)->hasEdgeSupport()){ + if(!$this->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport()){ $world->useBreakOn($this->position); }else{ foreach($this->getCurrentShapeConnections() as $connection){ diff --git a/src/block/Bed.php b/src/block/Bed.php index 13b466026..312b21cd1 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -177,11 +177,11 @@ class Bed extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ $this->facing = $player !== null ? $player->getHorizontalFacing() : Facing::NORTH; $next = $this->getSide($this->getOtherHalfSide()); - if($next->canBeReplaced() && $this->canBeSupportedBy($next->getSide(Facing::DOWN))){ + if($next->canBeReplaced() && $this->canBeSupportedAt($next)){ $nextState = clone $this; $nextState->head = true; $tx->addBlock($blockReplace->position, $this)->addBlock($next->position, $nextState); @@ -208,8 +208,8 @@ class Bed extends Transparent{ return parent::getAffectedBlocks(); } - private function canBeSupportedBy(Block $block) : bool{ - return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block) : bool{ + return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE()); } public function getMaxStackSize() : int{ return 1; } diff --git a/src/block/Bell.php b/src/block/Bell.php index 753d6453d..0e2941d8e 100644 --- a/src/block/Bell.php +++ b/src/block/Bell.php @@ -87,13 +87,13 @@ final class Bell extends Transparent{ return $this; } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return !$block->getSupportType($face)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return !$block->getAdjacentSupportType($face)->equals(SupportType::NONE()); } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP){ - if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->down()), Facing::UP)){ + if(!$this->canBeSupportedAt($blockReplace, Facing::DOWN)){ return false; } if($player !== null){ @@ -101,18 +101,18 @@ final class Bell extends Transparent{ } $this->setAttachmentType(BellAttachmentType::FLOOR()); }elseif($face === Facing::DOWN){ - if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->up()), Facing::DOWN)){ + if(!$this->canBeSupportedAt($blockReplace, Facing::UP)){ return false; } $this->setAttachmentType(BellAttachmentType::CEILING()); }else{ $this->setFacing($face); - if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide(Facing::opposite($face))), $face)){ + if($this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ $this->setAttachmentType(BellAttachmentType::ONE_WALL()); }else{ return false; } - if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide($face)), Facing::opposite($face))){ + if($this->canBeSupportedAt($blockReplace, $face)){ $this->setAttachmentType(BellAttachmentType::TWO_WALLS()); } } @@ -121,10 +121,10 @@ final class Bell extends Transparent{ public function onNearbyBlockChange() : void{ if( - ($this->attachmentType->equals(BellAttachmentType::CEILING()) && !$this->canBeSupportedBy($this->getSide(Facing::UP), Facing::DOWN)) || - ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && !$this->canBeSupportedBy($this->getSide(Facing::DOWN), Facing::UP)) || - ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)) || - ($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedBy($this->getSide($this->facing), Facing::opposite($this->facing)) || !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing))) + ($this->attachmentType->equals(BellAttachmentType::CEILING()) && !$this->canBeSupportedAt($this, Facing::UP)) || + ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && !$this->canBeSupportedAt($this, Facing::DOWN)) || + ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedAt($this, Facing::opposite($this->facing))) || + ($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedAt($this, $this->facing) || !$this->canBeSupportedAt($this, Facing::opposite($this->facing)))) ){ $this->position->getWorld()->useBreakOn($this->position); } diff --git a/src/block/Block.php b/src/block/Block.php index b4203e6b6..0e045792f 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -41,6 +41,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemBlock; use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -863,6 +864,10 @@ class Block{ return SupportType::FULL(); } + protected function getAdjacentSupportType(int $facing) : SupportType{ + return $this->getSide($facing)->getSupportType(Facing::opposite($facing)); + } + public function isFullCube() : bool{ $bb = $this->getCollisionBoxes(); diff --git a/src/block/Button.php b/src/block/Button.php index 85d1d3e09..73bd1d556 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -52,7 +52,7 @@ abstract class Button extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ + if($this->canBeSupportedAt($blockReplace, $face)){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -83,12 +83,12 @@ abstract class Button extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)){ + if(!$this->canBeSupportedAt($this, $this->facing)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $support, int $face) : bool{ - return $support->getSupportType($face)->hasCenterSupport(); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $block->getAdjacentSupportType(Facing::opposite($face))->hasCenterSupport(); } } diff --git a/src/block/Candle.php b/src/block/Candle.php index 5936a0812..7009acef6 100644 --- a/src/block/Candle.php +++ b/src/block/Candle.php @@ -104,8 +104,7 @@ class Candle extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - $down = $blockReplace->getSide(Facing::DOWN); - if(!$down->getSupportType(Facing::UP)->hasCenterSupport()){ + if(!$blockReplace->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport()){ return false; } $existing = $this->getCandleIfCompatibleType($blockReplace); diff --git a/src/block/CaveVines.php b/src/block/CaveVines.php index 55f73fb65..e56b8b720 100644 --- a/src/block/CaveVines.php +++ b/src/block/CaveVines.php @@ -87,18 +87,18 @@ class CaveVines extends Flowable{ return $this->berries ? 14 : 0; } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::DOWN)->equals(SupportType::FULL()) || $block->hasSameTypeId($this); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::UP)->equals(SupportType::FULL()) || $block->hasSameTypeId($this); } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::UP))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::UP))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } $this->age = mt_rand(0, self::MAX_AGE); diff --git a/src/block/Coral.php b/src/block/Coral.php index b621a3ab0..837a81857 100644 --- a/src/block/Coral.php +++ b/src/block/Coral.php @@ -32,7 +32,7 @@ use pocketmine\world\BlockTransaction; final class Coral extends BaseCoral{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($tx->fetchBlock($blockReplace->getPosition()->down()))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); @@ -40,14 +40,14 @@ final class Coral extends BaseCoral{ public function onNearbyBlockChange() : void{ $world = $this->position->getWorld(); - if(!$this->canBeSupportedBy($world->getBlock($this->position->down()))){ + if(!$this->canBeSupportedAt($this)){ $world->useBreakOn($this->position); }else{ parent::onNearbyBlockChange(); } } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::UP)->hasCenterSupport(); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport(); } } diff --git a/src/block/Door.php b/src/block/Door.php index 06da8e68b..a03427d5a 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -106,7 +106,7 @@ class Door extends Transparent{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN)) && !$this->getSide(Facing::DOWN) instanceof Door){ //Replace with common break method + if(!$this->canBeSupportedAt($this) && !$this->getSide(Facing::DOWN) instanceof Door){ //Replace with common break method $this->position->getWorld()->useBreakOn($this->position); //this will delete both halves if they exist } } @@ -114,8 +114,7 @@ class Door extends Transparent{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP){ $blockUp = $this->getSide(Facing::UP); - $blockDown = $this->getSide(Facing::DOWN); - if(!$blockUp->canBeReplaced() || !$this->canBeSupportedBy($blockDown)){ + if(!$blockUp->canBeReplaced() || !$this->canBeSupportedAt($blockReplace)){ return false; } @@ -172,7 +171,7 @@ class Door extends Transparent{ return parent::getAffectedBlocks(); } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::UP)->hasEdgeSupport(); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport(); } } diff --git a/src/block/FloorCoralFan.php b/src/block/FloorCoralFan.php index efa560467..a267a0385 100644 --- a/src/block/FloorCoralFan.php +++ b/src/block/FloorCoralFan.php @@ -53,7 +53,7 @@ final class FloorCoralFan extends BaseCoral{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($tx->fetchBlock($blockReplace->getPosition()->down()))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } if($player !== null){ @@ -75,15 +75,15 @@ final class FloorCoralFan extends BaseCoral{ public function onNearbyBlockChange() : void{ $world = $this->position->getWorld(); - if(!$this->canBeSupportedBy($world->getBlock($this->position->down()))){ + if(!$this->canBeSupportedAt($this)){ $world->useBreakOn($this->position); }else{ parent::onNearbyBlockChange(); } } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::UP)->hasCenterSupport(); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport(); } public function asItem() : Item{ diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index 1c85ea0d8..4e4dbfa6e 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -90,7 +90,7 @@ class FlowerPot extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } @@ -98,13 +98,13 @@ class FlowerPot extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::UP)->hasCenterSupport(); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport(); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ diff --git a/src/block/GlowLichen.php b/src/block/GlowLichen.php index d1baaa7d2..39ce512a6 100644 --- a/src/block/GlowLichen.php +++ b/src/block/GlowLichen.php @@ -121,7 +121,7 @@ class GlowLichen extends Transparent{ $changed = false; foreach($this->faces as $face){ - if(!$this->getSide($face)->getSupportType(Facing::opposite($face))->equals(SupportType::FULL())){ + if(!$this->getAdjacentSupportType($face)->equals(SupportType::FULL())){ unset($this->faces[$face]); $changed = true; } @@ -275,7 +275,7 @@ class GlowLichen extends Transparent{ private function getAvailableFaces() : array{ $faces = []; foreach(Facing::ALL as $face){ - if(!$this->hasFace($face) && $this->getSide($face)->getSupportType(Facing::opposite($face))->equals(SupportType::FULL())){ + if(!$this->hasFace($face) && $this->getAdjacentSupportType($face)->equals(SupportType::FULL())){ $faces[$face] = $face; } } diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index f14720fe4..21bc5c20a 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -163,18 +163,18 @@ class ItemFrame extends Flowable{ return true; } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return !$block->getSupportType($face)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return !$block->getAdjacentSupportType($face)->equals(SupportType::NONE()); } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)){ + if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){ $this->position->getWorld()->useBreakOn($this->position); } } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ + if(!$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ return false; } diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 66e5f28cd..83adada82 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -70,7 +70,7 @@ class Ladder extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face) && Facing::axis($face) !== Axis::Y){ + if($this->canBeSupportedAt($blockReplace, Facing::opposite($face)) && Facing::axis($face) !== Axis::Y){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -79,12 +79,12 @@ class Ladder extends Transparent{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)){ //Replace with common break method + if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){ //Replace with common break method $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return $block->getSupportType($face)->equals(SupportType::FULL()); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $block->getAdjacentSupportType($face)->equals(SupportType::FULL()); } } diff --git a/src/block/Lantern.php b/src/block/Lantern.php index bc50c3cb6..8ebc8ba2c 100644 --- a/src/block/Lantern.php +++ b/src/block/Lantern.php @@ -77,22 +77,23 @@ class Lantern extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::UP), Facing::DOWN) && !$this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN), Facing::UP)){ + $downSupport = $this->canBeSupportedAt($blockReplace, Facing::DOWN); + if(!$downSupport && !$this->canBeSupportedAt($blockReplace, Facing::UP)){ return false; } - $this->hanging = ($face === Facing::DOWN || !$this->canBeSupportedBy($this->position->getWorld()->getBlock($blockReplace->getPosition()->down()), Facing::UP)); + $this->hanging = $face === Facing::DOWN || !$downSupport; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ $face = $this->hanging ? Facing::UP : Facing::DOWN; - if(!$this->canBeSupportedBy($this->getSide($face), Facing::opposite($face))){ + if(!$this->canBeSupportedAt($this, $face)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return $block->getSupportType($face)->hasCenterSupport(); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $block->getAdjacentSupportType($face)->hasCenterSupport(); } } diff --git a/src/block/Lever.php b/src/block/Lever.php index 5d86ac7d2..e4b8c0811 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -66,7 +66,7 @@ class Lever extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ + if(!$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ return false; } @@ -90,8 +90,7 @@ class Lever extends Flowable{ } public function onNearbyBlockChange() : void{ - $facing = $this->facing->getFacing(); - if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($facing)), $facing)){ + if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing->getFacing()))){ $this->position->getWorld()->useBreakOn($this->position); } } @@ -107,8 +106,8 @@ class Lever extends Flowable{ return true; } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return $block->getSupportType($face)->hasCenterSupport(); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $block->getAdjacentSupportType($face)->hasCenterSupport(); } //TODO diff --git a/src/block/NetherVines.php b/src/block/NetherVines.php index ac075f667..c78000fa1 100644 --- a/src/block/NetherVines.php +++ b/src/block/NetherVines.php @@ -83,16 +83,13 @@ class NetherVines extends Flowable{ return true; } - private function getSupportFace() : int{ - return Facing::opposite($this->growthFace); - } - - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType($this->getSupportFace())->hasCenterSupport() || $block->hasSameTypeId($this); + private function canBeSupportedAt(Block $block) : bool{ + $supportBlock = $block->getSide(Facing::opposite($this->growthFace)); + return $supportBlock->getSupportType($this->growthFace)->hasCenterSupport() || $supportBlock->hasSameTypeId($this); } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide($this->getSupportFace()))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } @@ -109,7 +106,7 @@ class NetherVines extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide($this->getSupportFace()))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } $this->age = mt_rand(0, self::MAX_AGE - 1); diff --git a/src/block/PressurePlate.php b/src/block/PressurePlate.php index 7f9403b74..4df0bf927 100644 --- a/src/block/PressurePlate.php +++ b/src/block/PressurePlate.php @@ -45,18 +45,18 @@ abstract class PressurePlate extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; } - private function canBeSupportedBy(Block $block) : bool{ - return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block) : bool{ + return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE()); } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 2158f1a84..8b436020b 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -85,7 +85,7 @@ class RedstoneComparator extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } @@ -102,13 +102,13 @@ class RedstoneComparator extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block) : bool{ - return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block) : bool{ + return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE()); } //TODO: redstone functionality diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index d4f145238..518eeb9e5 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -68,7 +68,7 @@ class RedstoneRepeater extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } @@ -88,13 +88,13 @@ class RedstoneRepeater extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block) : bool{ - return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE()); + private function canBeSupportedAt(Block $block) : bool{ + return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE()); } //TODO: redstone functionality diff --git a/src/block/RedstoneWire.php b/src/block/RedstoneWire.php index 022672b5d..167365f56 100644 --- a/src/block/RedstoneWire.php +++ b/src/block/RedstoneWire.php @@ -35,7 +35,7 @@ class RedstoneWire extends Flowable{ use AnalogRedstoneSignalEmitterTrait; public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; @@ -49,13 +49,13 @@ class RedstoneWire extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::UP)->hasCenterSupport(); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport(); } public function asItem() : Item{ diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index f2425455c..f561c8ff5 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -80,8 +80,8 @@ class SnowLayer extends Flowable implements Fallable{ return SupportType::NONE(); } - private function canBeSupportedBy(Block $b) : bool{ - return $b->getSupportType(Facing::UP)->equals(SupportType::FULL()); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::FULL()); } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ @@ -91,7 +91,7 @@ class SnowLayer extends Flowable implements Fallable{ } $this->layers = $blockReplace->layers + 1; } - if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + if($this->canBeSupportedAt($blockReplace)){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/block/SporeBlossom.php b/src/block/SporeBlossom.php index 73e31edf2..909932178 100644 --- a/src/block/SporeBlossom.php +++ b/src/block/SporeBlossom.php @@ -32,12 +32,12 @@ use pocketmine\world\BlockTransaction; final class SporeBlossom extends Flowable{ - private function canBeSupportedBy(Block $block) : bool{ - return $block->getSupportType(Facing::DOWN)->equals(SupportType::FULL()); + private function canBeSupportedAt(Block $block) : bool{ + return $block->getAdjacentSupportType(Facing::UP)->equals(SupportType::FULL()); } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::UP))){ + if(!$this->canBeSupportedAt($blockReplace)){ return false; } @@ -45,7 +45,7 @@ final class SporeBlossom extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->getSide(Facing::UP))){ + if(!$this->canBeSupportedAt($this)){ $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/Torch.php b/src/block/Torch.php index 163c0d115..66b62bc19 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\block\utils\SupportType; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\item\Item; -use pocketmine\math\Axis; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -56,15 +55,13 @@ class Torch extends Flowable{ } public function onNearbyBlockChange() : void{ - $face = Facing::opposite($this->facing); - - if(!$this->canBeSupportedBy($this->getSide($face), $this->facing)){ + if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){ $this->position->getWorld()->useBreakOn($this->position); } } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($face !== Facing::DOWN && $this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ + if($face !== Facing::DOWN && $this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ @@ -75,8 +72,7 @@ class Torch extends Flowable{ Facing::EAST, Facing::DOWN ] as $side){ - $block = $this->getSide($side); - if($this->canBeSupportedBy($block, Facing::opposite($side))){ + if($this->canBeSupportedAt($blockReplace, $side)){ $this->facing = Facing::opposite($side); return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -85,8 +81,9 @@ class Torch extends Flowable{ return false; } - private function canBeSupportedBy(Block $support, int $face) : bool{ - return ($face === Facing::UP && $support->getSupportType($face)->hasCenterSupport()) || - (Facing::axis($face) !== Axis::Y && $support->getSupportType($face)->equals(SupportType::FULL())); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $face === Facing::DOWN ? + $block->getAdjacentSupportType($face)->hasCenterSupport() : + $block->getAdjacentSupportType($face)->equals(SupportType::FULL()); } } diff --git a/src/block/WallCoralFan.php b/src/block/WallCoralFan.php index 432dd5ddb..f9dece1cd 100644 --- a/src/block/WallCoralFan.php +++ b/src/block/WallCoralFan.php @@ -42,7 +42,7 @@ final class WallCoralFan extends BaseCoral{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $axis = Facing::axis($face); - if(($axis !== Axis::X && $axis !== Axis::Z) || !$this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ + if(($axis !== Axis::X && $axis !== Axis::Z) || !$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ return false; } $this->facing = $face; @@ -54,15 +54,15 @@ final class WallCoralFan extends BaseCoral{ public function onNearbyBlockChange() : void{ $world = $this->position->getWorld(); - if(!$this->canBeSupportedBy($world->getBlock($this->position->getSide(Facing::opposite($this->facing))), $this->facing)){ + if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){ $world->useBreakOn($this->position); }else{ parent::onNearbyBlockChange(); } } - private function canBeSupportedBy(Block $block, int $face) : bool{ - return $block->getSupportType($face)->hasCenterSupport(); + private function canBeSupportedAt(Block $block, int $face) : bool{ + return $block->getAdjacentSupportType($face)->hasCenterSupport(); } public function asItem() : Item{ From 2779f92828de5214f73d4df151effa1d97466deb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Jul 2023 15:29:33 +0100 Subject: [PATCH 15/25] Bell: clean up code --- src/block/Bell.php | 55 ++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/src/block/Bell.php b/src/block/Bell.php index 0e2941d8e..3f15d6909 100644 --- a/src/block/Bell.php +++ b/src/block/Bell.php @@ -35,6 +35,7 @@ use pocketmine\math\Facing; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\player\Player; +use pocketmine\utils\AssumptionFailedError; use pocketmine\world\BlockTransaction; use pocketmine\world\sound\BellRingSound; @@ -92,41 +93,39 @@ final class Bell extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(!$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ + return false; + } if($face === Facing::UP){ - if(!$this->canBeSupportedAt($blockReplace, Facing::DOWN)){ - return false; - } if($player !== null){ $this->setFacing(Facing::opposite($player->getHorizontalFacing())); } $this->setAttachmentType(BellAttachmentType::FLOOR()); }elseif($face === Facing::DOWN){ - if(!$this->canBeSupportedAt($blockReplace, Facing::UP)){ - return false; - } $this->setAttachmentType(BellAttachmentType::CEILING()); }else{ $this->setFacing($face); - if($this->canBeSupportedAt($blockReplace, Facing::opposite($face))){ - $this->setAttachmentType(BellAttachmentType::ONE_WALL()); - }else{ - return false; - } - if($this->canBeSupportedAt($blockReplace, $face)){ - $this->setAttachmentType(BellAttachmentType::TWO_WALLS()); - } + $this->setAttachmentType( + $this->canBeSupportedAt($blockReplace, $face) ? + BellAttachmentType::TWO_WALLS() : + BellAttachmentType::ONE_WALL() + ); } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - if( - ($this->attachmentType->equals(BellAttachmentType::CEILING()) && !$this->canBeSupportedAt($this, Facing::UP)) || - ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && !$this->canBeSupportedAt($this, Facing::DOWN)) || - ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedAt($this, Facing::opposite($this->facing))) || - ($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedAt($this, $this->facing) || !$this->canBeSupportedAt($this, Facing::opposite($this->facing)))) - ){ - $this->position->getWorld()->useBreakOn($this->position); + foreach(match($this->attachmentType){ + BellAttachmentType::CEILING() => [Facing::UP], + BellAttachmentType::FLOOR() => [Facing::DOWN], + BellAttachmentType::ONE_WALL() => [Facing::opposite($this->facing)], + BellAttachmentType::TWO_WALLS() => [$this->facing, Facing::opposite($this->facing)], + default => throw new AssumptionFailedError("All cases of BellAttachmentType must be handled") + } as $supportBlockDirection){ + if(!$this->canBeSupportedAt($this, $supportBlockDirection)){ + $this->position->getWorld()->useBreakOn($this->position); + break; + } } } @@ -159,13 +158,11 @@ final class Bell extends Transparent{ } private function isValidFaceToRing(int $faceHit) : bool{ - return ( - $this->attachmentType->equals(BellAttachmentType::CEILING()) || - ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && Facing::axis($faceHit) === Facing::axis($this->facing)) || - ( - ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) || $this->attachmentType->equals(BellAttachmentType::TWO_WALLS())) && - ($faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true)) - ) - ); + return match($this->attachmentType){ + BellAttachmentType::CEILING() => true, + BellAttachmentType::FLOOR() => Facing::axis($faceHit) === Facing::axis($this->facing), + BellAttachmentType::ONE_WALL(), BellAttachmentType::TWO_WALLS() => $faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true), + default => throw new AssumptionFailedError("All cases of BellAttachmentType must be handled") + }; } } From 43770313ba08a7fb021536a2bc892c2228724c5a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Jul 2023 12:07:32 +0100 Subject: [PATCH 16/25] Update symfony/filesystem to 6.3.x --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 4589d73a1..ea312ac14 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "pocketmine/raklib-ipc": "^0.2.0", "pocketmine/snooze": "^0.5.0", "ramsey/uuid": "~4.7.0", - "symfony/filesystem": "~6.2.0" + "symfony/filesystem": "~6.3.0" }, "require-dev": { "phpstan/phpstan": "1.10.16", diff --git a/composer.lock b/composer.lock index a82393a89..53807f312 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": "ee46ec27f8dfc8c767527b7776fe9992", + "content-hash": "74166e6c2f09b356c83a951efef349f2", "packages": [ { "name": "adhocore/json-comment", @@ -998,16 +998,16 @@ }, { "name": "symfony/filesystem", - "version": "v6.2.12", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "b0818e7203e53540f2a5c9a5017d97897df1e9bb" + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b0818e7203e53540f2a5c9a5017d97897df1e9bb", - "reference": "b0818e7203e53540f2a5c9a5017d97897df1e9bb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", "shasum": "" }, "require": { @@ -1041,7 +1041,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.2.12" + "source": "https://github.com/symfony/filesystem/tree/v6.3.1" }, "funding": [ { @@ -1057,7 +1057,7 @@ "type": "tidelift" } ], - "time": "2023-06-01T08:29:37+00:00" + "time": "2023-06-01T08:30:39+00:00" }, { "name": "symfony/polyfill-ctype", From 4eb9dacd3cc219eeaff0c9cbda80683e3c02d9ba Mon Sep 17 00:00:00 2001 From: dohwi <78037515+dohwi@users.noreply.github.com> Date: Mon, 24 Jul 2023 20:16:56 +0900 Subject: [PATCH 17/25] Remove unnecessary HorizontalFacingTrait (#5930) FacingOppositePlacingPlayerTrait already includes HorizontalFacingTrait, so we don't need to include it twice. --- src/block/CarvedPumpkin.php | 2 -- src/block/ChemistryTable.php | 2 -- src/block/Chest.php | 2 -- src/block/EndPortalFrame.php | 2 -- src/block/EnderChest.php | 2 -- src/block/Furnace.php | 2 -- src/block/GlazedTerracotta.php | 2 -- src/block/Lectern.php | 2 -- src/block/Loom.php | 2 -- src/block/Stonecutter.php | 2 -- 10 files changed, 20 deletions(-) diff --git a/src/block/CarvedPumpkin.php b/src/block/CarvedPumpkin.php index 5fc73d088..98f3c2307 100644 --- a/src/block/CarvedPumpkin.php +++ b/src/block/CarvedPumpkin.php @@ -24,9 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; -use pocketmine\block\utils\HorizontalFacingTrait; class CarvedPumpkin extends Opaque{ use FacesOppositePlacingPlayerTrait; - use HorizontalFacingTrait; } diff --git a/src/block/ChemistryTable.php b/src/block/ChemistryTable.php index 27fb63674..058e40288 100644 --- a/src/block/ChemistryTable.php +++ b/src/block/ChemistryTable.php @@ -24,14 +24,12 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; -use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\player\Player; final class ChemistryTable extends Opaque{ use FacesOppositePlacingPlayerTrait; - use HorizontalFacingTrait; public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ //TODO diff --git a/src/block/Chest.php b/src/block/Chest.php index 45c190505..270c696c3 100644 --- a/src/block/Chest.php +++ b/src/block/Chest.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\block\tile\Chest as TileChest; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; -use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\block\utils\SupportType; use pocketmine\event\block\ChestPairEvent; use pocketmine\item\Item; @@ -36,7 +35,6 @@ use pocketmine\player\Player; class Chest extends Transparent{ use FacesOppositePlacingPlayerTrait; - use HorizontalFacingTrait; /** * @return AxisAlignedBB[] diff --git a/src/block/EndPortalFrame.php b/src/block/EndPortalFrame.php index 08c903f11..612cf3723 100644 --- a/src/block/EndPortalFrame.php +++ b/src/block/EndPortalFrame.php @@ -24,14 +24,12 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; -use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; class EndPortalFrame extends Opaque{ use FacesOppositePlacingPlayerTrait; - use HorizontalFacingTrait; protected bool $eye = false; diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index 68c2805f9..26596eac9 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\block\inventory\EnderChestInventory; use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; -use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\block\utils\SupportType; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; @@ -36,7 +35,6 @@ use pocketmine\player\Player; class EnderChest extends Transparent{ use FacesOppositePlacingPlayerTrait; - use HorizontalFacingTrait; public function getLightLevel() : int{ return 7; diff --git a/src/block/Furnace.php b/src/block/Furnace.php index d943f8cc6..fbff73c93 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\block\tile\Furnace as TileFurnace; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; -use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\crafting\FurnaceType; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\item\Item; @@ -35,7 +34,6 @@ use function mt_rand; class Furnace extends Opaque{ use FacesOppositePlacingPlayerTrait; - use HorizontalFacingTrait; protected FurnaceType $furnaceType; diff --git a/src/block/GlazedTerracotta.php b/src/block/GlazedTerracotta.php index 5568703c2..b49347aef 100644 --- a/src/block/GlazedTerracotta.php +++ b/src/block/GlazedTerracotta.php @@ -26,12 +26,10 @@ namespace pocketmine\block; use pocketmine\block\utils\ColoredTrait; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; -use pocketmine\block\utils\HorizontalFacingTrait; class GlazedTerracotta extends Opaque{ use ColoredTrait; use FacesOppositePlacingPlayerTrait; - use HorizontalFacingTrait; public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){ $this->color = DyeColor::BLACK(); diff --git a/src/block/Lectern.php b/src/block/Lectern.php index a80426acf..d9f07d22b 100644 --- a/src/block/Lectern.php +++ b/src/block/Lectern.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\block\tile\Lectern as TileLectern; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; -use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\block\utils\SupportType; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\item\Item; @@ -39,7 +38,6 @@ use function count; class Lectern extends Transparent{ use FacesOppositePlacingPlayerTrait; - use HorizontalFacingTrait; protected int $viewedPage = 0; protected ?WritableBookBase $book = null; diff --git a/src/block/Loom.php b/src/block/Loom.php index a10b57723..d3dd4f3c7 100644 --- a/src/block/Loom.php +++ b/src/block/Loom.php @@ -25,14 +25,12 @@ namespace pocketmine\block; use pocketmine\block\inventory\LoomInventory; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; -use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\player\Player; final class Loom extends Opaque{ use FacesOppositePlacingPlayerTrait; - use HorizontalFacingTrait; public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ if($player !== null){ diff --git a/src/block/Stonecutter.php b/src/block/Stonecutter.php index 7736381e4..eb7dc68c2 100644 --- a/src/block/Stonecutter.php +++ b/src/block/Stonecutter.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\block\inventory\StonecutterInventory; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; -use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\block\utils\SupportType; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; @@ -35,7 +34,6 @@ use pocketmine\player\Player; class Stonecutter extends Transparent{ use FacesOppositePlacingPlayerTrait; - use HorizontalFacingTrait; public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ if($player !== null){ From b078e01b65a9a45386ff23633d927362ea9c58a4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Jul 2023 13:35:32 +0100 Subject: [PATCH 18/25] JwtUtils: handle DER <-> raw signature conversion in-house, drop fgrosse/phpasn1 dependency normally I would hesitate to reinvent the wheel, but we only need a tiny subset of the ASN.1 spec which is trivial to implement by itself. I'd rather this than depend on another library that could introduce security vulnerabilities (I'm looking at you, jsonmapper). closes #5935 --- composer.json | 1 - composer.lock | 78 +------------------- src/network/mcpe/JwtUtils.php | 131 ++++++++++++++++++++++------------ 3 files changed, 85 insertions(+), 125 deletions(-) diff --git a/composer.json b/composer.json index ea312ac14..608c88459 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,6 @@ "ext-zlib": ">=1.2.11", "composer-runtime-api": "^2.0", "adhocore/json-comment": "~1.2.0", - "fgrosse/phpasn1": "~2.5.0", "pocketmine/netresearch-jsonmapper": "~v4.2.1000", "pocketmine/bedrock-block-upgrade-schema": "~3.1.0+bedrock-1.20.10", "pocketmine/bedrock-data": "~2.4.0+bedrock-1.20.10", diff --git a/composer.lock b/composer.lock index 53807f312..2a4521d26 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": "74166e6c2f09b356c83a951efef349f2", + "content-hash": "fa059375785ed5b842af30c6b99c572f", "packages": [ { "name": "adhocore/json-comment", @@ -120,82 +120,6 @@ ], "time": "2023-01-15T23:15:59+00:00" }, - { - "name": "fgrosse/phpasn1", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/fgrosse/PHPASN1.git", - "reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/42060ed45344789fb9f21f9f1864fc47b9e3507b", - "reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "php-coveralls/php-coveralls": "~2.0", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" - }, - "suggest": { - "ext-bcmath": "BCmath is the fallback extension for big integer calculations", - "ext-curl": "For loading OID information from the web if they have not bee defined statically", - "ext-gmp": "GMP is the preferred extension for big integer calculations", - "phpseclib/bcmath_compat": "BCmath polyfill for servers where neither GMP nor BCmath is available" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "FG\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Friedrich Große", - "email": "friedrich.grosse@gmail.com", - "homepage": "https://github.com/FGrosse", - "role": "Author" - }, - { - "name": "All contributors", - "homepage": "https://github.com/FGrosse/PHPASN1/contributors" - } - ], - "description": "A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690 Encoding Rules.", - "homepage": "https://github.com/FGrosse/PHPASN1", - "keywords": [ - "DER", - "asn.1", - "asn1", - "ber", - "binary", - "decoding", - "encoding", - "x.509", - "x.690", - "x509", - "x690" - ], - "support": { - "issues": "https://github.com/fgrosse/PHPASN1/issues", - "source": "https://github.com/fgrosse/PHPASN1/tree/v2.5.0" - }, - "abandoned": true, - "time": "2022-12-19T11:08:26+00:00" - }, { "name": "pocketmine/bedrock-block-upgrade-schema", "version": "3.1.0", diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index a3cebbd73..259a602d4 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -23,28 +23,26 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use FG\ASN1\Exception\ParserException; -use FG\ASN1\Universal\Integer; -use FG\ASN1\Universal\Sequence; use pocketmine\utils\AssumptionFailedError; +use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; use function base64_decode; use function base64_encode; +use function bin2hex; +use function chr; use function count; use function explode; -use function gmp_export; -use function gmp_import; -use function gmp_init; -use function gmp_strval; use function is_array; use function json_decode; use function json_encode; use function json_last_error_msg; +use function ltrim; use function openssl_error_string; use function openssl_pkey_get_details; use function openssl_pkey_get_public; use function openssl_sign; use function openssl_verify; +use function ord; use function preg_match; use function rtrim; use function sprintf; @@ -54,8 +52,7 @@ use function str_replace; use function str_split; use function strlen; use function strtr; -use const GMP_BIG_ENDIAN; -use const GMP_MSW_FIRST; +use function substr; use const JSON_THROW_ON_ERROR; use const OPENSSL_ALGO_SHA384; use const STR_PAD_LEFT; @@ -63,6 +60,12 @@ use const STR_PAD_LEFT; final class JwtUtils{ public const BEDROCK_SIGNING_KEY_CURVE_NAME = "secp384r1"; + private const ASN1_INTEGER_TAG = "\x02"; + private const ASN1_SEQUENCE_TAG = "\x30"; + + private const SIGNATURE_PART_LENGTH = 48; + private const SIGNATURE_ALGORITHM = OPENSSL_ALGO_SHA384; + /** * @return string[] * @phpstan-return array{string, string, string} @@ -98,30 +101,84 @@ final class JwtUtils{ return [$header, $body, $signature]; } + private static function signaturePartToAsn1(string $part) : string{ + if(strlen($part) !== self::SIGNATURE_PART_LENGTH){ + throw new JwtException("R and S for a SHA384 signature must each be exactly 48 bytes, but have " . strlen($part) . " bytes"); + } + $part = ltrim($part, "\x00"); + if(ord($part[0]) >= 128){ + //ASN.1 integers with a leading 1 bit are considered negative - add a leading 0 byte to prevent this + //ECDSA signature R and S values are always positive + $part = "\x00" . $part; + } + + //we can assume the length is 1 byte here - if it were larger than 127, more complex logic would be needed + return self::ASN1_INTEGER_TAG . chr(strlen($part)) . $part; + } + + private static function rawSignatureToDer(string $rawSignature) : string{ + if(strlen($rawSignature) !== self::SIGNATURE_PART_LENGTH * 2){ + throw new JwtException("JWT signature has unexpected length, expected 96, got " . strlen($rawSignature)); + } + + [$rString, $sString] = str_split($rawSignature, self::SIGNATURE_PART_LENGTH); + $sequence = self::signaturePartToAsn1($rString) . self::signaturePartToAsn1($sString); + + //we can assume the length is 1 byte here - if it were larger than 127, more complex logic would be needed + return self::ASN1_SEQUENCE_TAG . chr(strlen($sequence)) . $sequence; + } + + private static function signaturePartFromAsn1(BinaryStream $stream) : string{ + $prefix = $stream->get(1); + if($prefix !== self::ASN1_INTEGER_TAG){ + throw new \InvalidArgumentException("Expected an ASN.1 INTEGER tag, got " . bin2hex($prefix)); + } + //we can assume the length is 1 byte here - if it were larger than 127, more complex logic would be needed + $length = $stream->getByte(); + if($length > self::SIGNATURE_PART_LENGTH + 1){ //each part may have an extra leading 0 byte to prevent it being interpreted as a negative number + throw new \InvalidArgumentException("Expected at most 49 bytes for signature R or S, got $length"); + } + $part = $stream->get($length); + return str_pad(ltrim($part, "\x00"), self::SIGNATURE_PART_LENGTH, "\x00", STR_PAD_LEFT); + } + + private static function rawSignatureFromDer(string $derSignature) : string{ + if($derSignature[0] !== self::ASN1_SEQUENCE_TAG){ + throw new \InvalidArgumentException("Invalid DER signature, expected ASN.1 SEQUENCE tag, got " . bin2hex($derSignature[0])); + } + + //we can assume the length is 1 byte here - if it were larger than 127, more complex logic would be needed + $length = ord($derSignature[1]); + $parts = substr($derSignature, 2, $length); + if(strlen($parts) !== $length){ + throw new \InvalidArgumentException("Invalid DER signature, expected $length sequence bytes, got " . strlen($parts)); + } + + $stream = new BinaryStream($parts); + $rRaw = self::signaturePartFromAsn1($stream); + $sRaw = self::signaturePartFromAsn1($stream); + + if(!$stream->feof()){ + throw new \InvalidArgumentException("Invalid DER signature, unexpected trailing sequence data"); + } + + return $rRaw . $sRaw; + } + /** * @throws JwtException */ public static function verify(string $jwt, \OpenSSLAsymmetricKey $signingKey) : bool{ [$header, $body, $signature] = self::split($jwt); - $plainSignature = self::b64UrlDecode($signature); - if(strlen($plainSignature) !== 96){ - throw new JwtException("JWT signature has unexpected length, expected 96, got " . strlen($plainSignature)); - } - - [$rString, $sString] = str_split($plainSignature, 48); - $convert = fn(string $str) => gmp_strval(gmp_import($str, 1, GMP_BIG_ENDIAN | GMP_MSW_FIRST), 10); - - $sequence = new Sequence( - new Integer($convert($rString)), - new Integer($convert($sString)) - ); + $rawSignature = self::b64UrlDecode($signature); + $derSignature = self::rawSignatureToDer($rawSignature); $v = openssl_verify( $header . '.' . $body, - $sequence->getBinary(), + $derSignature, $signingKey, - OPENSSL_ALGO_SHA384 + self::SIGNATURE_ALGORITHM ); switch($v){ case 0: return false; @@ -140,33 +197,13 @@ final class JwtUtils{ openssl_sign( $jwtBody, - $rawDerSig, + $derSignature, $signingKey, - OPENSSL_ALGO_SHA384 + self::SIGNATURE_ALGORITHM ); - try{ - $asnObject = Sequence::fromBinary($rawDerSig); - }catch(ParserException $e){ - throw new AssumptionFailedError("Failed to parse OpenSSL signature: " . $e->getMessage(), 0, $e); - } - if(count($asnObject) !== 2){ - throw new AssumptionFailedError("OpenSSL produced invalid signature, expected exactly 2 parts"); - } - [$r, $s] = [$asnObject[0], $asnObject[1]]; - if(!($r instanceof Integer) || !($s instanceof Integer)){ - throw new AssumptionFailedError("OpenSSL produced invalid signature, expected 2 INTEGER parts"); - } - $rString = $r->getContent(); - $sString = $s->getContent(); - - $toBinary = fn($str) => str_pad( - gmp_export(gmp_init($str, 10), 1, GMP_BIG_ENDIAN | GMP_MSW_FIRST), - 48, - "\x00", - STR_PAD_LEFT - ); - $jwtSig = JwtUtils::b64UrlEncode($toBinary($rString) . $toBinary($sString)); + $rawSignature = self::rawSignatureFromDer($derSignature); + $jwtSig = self::b64UrlEncode($rawSignature); return "$jwtBody.$jwtSig"; } From 6086ef667ce2b145545c14871e671d172030229a Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Tue, 25 Jul 2023 16:50:28 +0300 Subject: [PATCH 19/25] Added handling for attack-air action (#5912) --- src/event/player/PlayerMissedSwingEvent.php | 39 +++++++++++++++++++ .../mcpe/handler/InGamePacketHandler.php | 3 ++ src/player/Player.php | 13 +++++++ 3 files changed, 55 insertions(+) create mode 100644 src/event/player/PlayerMissedSwingEvent.php diff --git a/src/event/player/PlayerMissedSwingEvent.php b/src/event/player/PlayerMissedSwingEvent.php new file mode 100644 index 000000000..3157f62d1 --- /dev/null +++ b/src/event/player/PlayerMissedSwingEvent.php @@ -0,0 +1,39 @@ +player = $player; + } +} diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 22eb91935..729b5b51b 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -236,6 +236,9 @@ class InGamePacketHandler extends PacketHandler{ if($packet->hasFlag(PlayerAuthInputFlags::START_JUMPING)){ $this->player->jump(); } + if($packet->hasFlag(PlayerAuthInputFlags::MISSED_SWING)){ + $this->player->missSwing(); + } } if(!$this->forceMoveSync && $hasMoved){ diff --git a/src/player/Player.php b/src/player/Player.php index f8d4923f0..9b6c321e8 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -66,6 +66,7 @@ use pocketmine\event\player\PlayerItemUseEvent; use pocketmine\event\player\PlayerJoinEvent; use pocketmine\event\player\PlayerJumpEvent; use pocketmine\event\player\PlayerKickEvent; +use pocketmine\event\player\PlayerMissedSwingEvent; use pocketmine\event\player\PlayerMoveEvent; use pocketmine\event\player\PlayerPostChunkSendEvent; use pocketmine\event\player\PlayerQuitEvent; @@ -1894,6 +1895,18 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return true; } + /** + * Performs actions associated with the attack action (left-click) without a target entity. + * Under normal circumstances, this will play the no-damage attack sound and nothing else. + */ + public function missSwing() : void{ + $ev = new PlayerMissedSwingEvent($this); + $ev->call(); + if(!$ev->isCancelled()){ + $this->broadcastSound(new EntityAttackNoDamageSound()); + } + } + /** * Interacts with the given entity using the currently-held item. */ From bbdcab727726225dca6d353ed4dc48815cd90b8e Mon Sep 17 00:00:00 2001 From: rasu3n Date: Wed, 26 Jul 2023 18:04:36 +0900 Subject: [PATCH 20/25] Player: Added animation to missSwing() (#5942) --- src/player/Player.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 9b6c321e8..292ab98b3 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1897,13 +1897,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** * Performs actions associated with the attack action (left-click) without a target entity. - * Under normal circumstances, this will play the no-damage attack sound and nothing else. + * Under normal circumstances, this will just play the no-damage attack sound and the arm-swing animation. */ public function missSwing() : void{ $ev = new PlayerMissedSwingEvent($this); $ev->call(); if(!$ev->isCancelled()){ $this->broadcastSound(new EntityAttackNoDamageSound()); + $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); } } From 82a5ea9ed3d4aab82e7389b50c550c9ea4aa80b4 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Wed, 26 Jul 2023 16:26:03 +0100 Subject: [PATCH 21/25] Allow thread errors and their traces to be properly recorded in crashdumps (#5910) until now, any thread crash would show as a generic crash since we aren't able to get the trace from the crashed thread directly. This uses some dirty tricks to export a partially serialized stack trace to the main thread, where it can be written into a crashdump. This enables us to see proper crash information for async tasks in the crash archive (finally!!!) as well as being able to capture RakLib errors properly. --- src/Server.php | 38 +++++-- src/crash/CrashDump.php | 15 +-- src/crash/CrashDumpData.php | 2 + src/crash/CrashDumpRenderer.php | 1 + src/network/mcpe/raklib/RakLibInterface.php | 3 +- src/network/mcpe/raklib/RakLibServer.php | 101 ++++++------------ .../mcpe/raklib/RakLibThreadCrashInfo.php | 61 ----------- src/scheduler/AsyncPool.php | 14 ++- src/scheduler/AsyncWorker.php | 12 +-- src/thread/CommonThreadPartsTrait.php | 41 +++++++ src/thread/ThreadCrashException.php | 38 +++++++ src/thread/ThreadCrashInfo.php | 89 +++++++++++++++ src/thread/ThreadCrashInfoFrame.php | 41 +++++++ src/utils/Utils.php | 25 +++++ tests/phpstan/configs/actual-problems.neon | 10 ++ 15 files changed, 329 insertions(+), 162 deletions(-) delete mode 100644 src/network/mcpe/raklib/RakLibThreadCrashInfo.php create mode 100644 src/thread/ThreadCrashException.php create mode 100644 src/thread/ThreadCrashInfo.php create mode 100644 src/thread/ThreadCrashInfoFrame.php diff --git a/src/Server.php b/src/Server.php index e8f2d2726..148c93b8e 100644 --- a/src/Server.php +++ b/src/Server.php @@ -93,6 +93,7 @@ use pocketmine\scheduler\AsyncPool; use pocketmine\snooze\SleeperHandler; use pocketmine\stats\SendUsageTask; use pocketmine\thread\log\AttachableThreadSafeLogger; +use pocketmine\thread\ThreadCrashException; use pocketmine\thread\ThreadSafeClassLoader; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; @@ -1516,23 +1517,38 @@ class Server{ $trace = $e->getTrace(); } - $errstr = $e->getMessage(); - $errfile = $e->getFile(); - $errline = $e->getLine(); + //If this is a thread crash, this logs where the exception came from on the main thread, as opposed to the + //crashed thread. This is intentional, and might be useful for debugging + //Assume that the thread already logged the original exception with the correct stack trace + $this->logger->logException($e, $trace); + + if($e instanceof ThreadCrashException){ + $info = $e->getCrashInfo(); + $type = $info->getType(); + $errstr = $info->getMessage(); + $errfile = $info->getFile(); + $errline = $info->getLine(); + $printableTrace = $info->getTrace(); + $thread = $info->getThreadName(); + }else{ + $type = get_class($e); + $errstr = $e->getMessage(); + $errfile = $e->getFile(); + $errline = $e->getLine(); + $printableTrace = Utils::printableTraceWithMetadata($trace); + $thread = "Main"; + } $errstr = preg_replace('/\s+/', ' ', trim($errstr)); - $errfile = Filesystem::cleanPath($errfile); - - $this->logger->logException($e, $trace); - $lastError = [ - "type" => get_class($e), + "type" => $type, "message" => $errstr, - "fullFile" => $e->getFile(), - "file" => $errfile, + "fullFile" => $errfile, + "file" => Filesystem::cleanPath($errfile), "line" => $errline, - "trace" => $trace + "trace" => $printableTrace, + "thread" => $thread ]; global $lastExceptionError, $lastError; diff --git a/src/crash/CrashDump.php b/src/crash/CrashDump.php index d7223eb2f..40af53fd0 100644 --- a/src/crash/CrashDump.php +++ b/src/crash/CrashDump.php @@ -29,11 +29,13 @@ use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\plugin\PluginBase; use pocketmine\plugin\PluginManager; use pocketmine\Server; +use pocketmine\thread\ThreadCrashInfoFrame; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; use pocketmine\VersionInfo; use Symfony\Component\Filesystem\Path; +use function array_map; use function base64_encode; use function error_get_last; use function file; @@ -186,7 +188,7 @@ class CrashDump{ if($error === null){ throw new \RuntimeException("Crash error information missing - did something use exit()?"); } - $error["trace"] = Utils::currentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump + $error["trace"] = Utils::printableTrace(Utils::currentTrace(3)); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump $error["fullFile"] = $error["file"]; $error["file"] = Filesystem::cleanPath($error["file"]); try{ @@ -201,9 +203,6 @@ class CrashDump{ $error["message"] = mb_scrub($error["message"], 'UTF-8'); if(isset($lastError)){ - if(isset($lastError["trace"])){ - $lastError["trace"] = Utils::printableTrace($lastError["trace"]); - } $this->data->lastError = $lastError; $this->data->lastError["message"] = mb_scrub($this->data->lastError["message"], 'UTF-8'); } @@ -215,10 +214,11 @@ class CrashDump{ $this->data->plugin_involvement = self::PLUGIN_INVOLVEMENT_NONE; if(!$this->determinePluginFromFile($error["fullFile"], true)){ //fatal errors won't leave any stack trace foreach($error["trace"] as $frame){ - if(!isset($frame["file"])){ + $frameFile = $frame->getFile(); + if($frameFile === null){ continue; //PHP core } - if($this->determinePluginFromFile($frame["file"], false)){ + if($this->determinePluginFromFile($frameFile, false)){ break; } } @@ -233,7 +233,8 @@ class CrashDump{ } } - $this->data->trace = Utils::printableTrace($error["trace"]); + $this->data->trace = array_map(array: $error["trace"], callback: fn(ThreadCrashInfoFrame $frame) => $frame->getPrintableFrame()); + $this->data->thread = $error["thread"]; } private function determinePluginFromFile(string $filePath, bool $crashFrame) : bool{ diff --git a/src/crash/CrashDumpData.php b/src/crash/CrashDumpData.php index 0f5358be5..b71e6f405 100644 --- a/src/crash/CrashDumpData.php +++ b/src/crash/CrashDumpData.php @@ -37,6 +37,8 @@ final class CrashDumpData implements \JsonSerializable{ /** @var mixed[] */ public array $error; + public string $thread; + public string $plugin_involvement; public string $plugin = ""; diff --git a/src/crash/CrashDumpRenderer.php b/src/crash/CrashDumpRenderer.php index 2858f43ec..617dcb7ab 100644 --- a/src/crash/CrashDumpRenderer.php +++ b/src/crash/CrashDumpRenderer.php @@ -64,6 +64,7 @@ final class CrashDumpRenderer{ $this->addLine(); + $this->addLine("Thread: " . $this->data->thread); $this->addLine("Error: " . $this->data->error["message"]); $this->addLine("File: " . $this->data->error["file"]); $this->addLine("Line: " . $this->data->error["line"]); diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 93dff68a2..4bf8ffb15 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -39,6 +39,7 @@ use pocketmine\network\NetworkInterfaceStartException; use pocketmine\network\PacketHandlingException; use pocketmine\player\GameMode; use pocketmine\Server; +use pocketmine\thread\ThreadCrashException; use pocketmine\timings\Timings; use pocketmine\utils\Utils; use raklib\generic\DisconnectReason; @@ -154,7 +155,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ if(!$this->rakLib->isRunning()){ $e = $this->rakLib->getCrashInfo(); if($e !== null){ - throw new \RuntimeException("RakLib crashed: " . $e->makePrettyMessage()); + throw new ThreadCrashException("RakLib crashed", $e); } throw new \Exception("RakLib Thread crashed without crash information"); } diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index a3f7c1609..e59b6971f 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -29,6 +29,7 @@ use pocketmine\snooze\SleeperHandlerEntry; use pocketmine\thread\log\ThreadSafeLogger; use pocketmine\thread\NonThreadSafeValue; use pocketmine\thread\Thread; +use pocketmine\thread\ThreadCrashException; use raklib\generic\SocketException; use raklib\server\ipc\RakLibToUserThreadMessageSender; use raklib\server\ipc\UserToRakLibThreadMessageReceiver; @@ -37,17 +38,12 @@ use raklib\server\ServerSocket; use raklib\server\SimpleProtocolAcceptor; use raklib\utils\ExceptionTraceCleaner; use raklib\utils\InternetAddress; -use function error_get_last; use function gc_enable; use function ini_set; -use function register_shutdown_function; class RakLibServer extends Thread{ - protected bool $cleanShutdown = false; protected bool $ready = false; protected string $mainPath; - /** @phpstan-var NonThreadSafeValue|null */ - public ?NonThreadSafeValue $crashInfo = null; /** @phpstan-var NonThreadSafeValue */ protected NonThreadSafeValue $address; @@ -69,86 +65,51 @@ class RakLibServer extends Thread{ $this->address = new NonThreadSafeValue($address); } - /** - * @return void - */ - public function shutdownHandler(){ - if($this->cleanShutdown !== true && $this->crashInfo === null){ - $error = error_get_last(); - - if($error !== null){ - $this->logger->emergency("Fatal error: " . $error["message"] . " in " . $error["file"] . " on line " . $error["line"]); - $this->setCrashInfo(RakLibThreadCrashInfo::fromLastErrorInfo($error)); - }else{ - $this->logger->emergency("RakLib shutdown unexpectedly"); - } - } - } - - public function getCrashInfo() : ?RakLibThreadCrashInfo{ - return $this->crashInfo?->deserialize(); - } - - private function setCrashInfo(RakLibThreadCrashInfo $info) : void{ - $this->synchronized(function() use ($info) : void{ - $this->crashInfo = new NonThreadSafeValue($info); - $this->notify(); - }); - } - public function startAndWait(int $options = NativeThread::INHERIT_NONE) : void{ $this->start($options); $this->synchronized(function() : void{ - while(!$this->ready && $this->crashInfo === null){ + while(!$this->ready && $this->getCrashInfo() === null){ $this->wait(); } - $crashInfo = $this->crashInfo?->deserialize(); + $crashInfo = $this->getCrashInfo(); if($crashInfo !== null){ - if($crashInfo->getClass() === SocketException::class){ + if($crashInfo->getType() === SocketException::class){ throw new SocketException($crashInfo->getMessage()); } - throw new \RuntimeException("RakLib failed to start: " . $crashInfo->makePrettyMessage()); + throw new ThreadCrashException("RakLib failed to start", $crashInfo); } }); } protected function onRun() : void{ - try{ - gc_enable(); - ini_set("display_errors", '1'); - ini_set("display_startup_errors", '1'); + gc_enable(); + ini_set("display_errors", '1'); + ini_set("display_startup_errors", '1'); - register_shutdown_function([$this, "shutdownHandler"]); - - try{ - $socket = new ServerSocket($this->address->deserialize()); - }catch(SocketException $e){ - $this->setCrashInfo(RakLibThreadCrashInfo::fromThrowable($e)); - return; - } - $manager = new Server( - $this->serverId, - $this->logger, - $socket, - $this->maxMtuSize, - new SimpleProtocolAcceptor($this->protocolVersion), - new UserToRakLibThreadMessageReceiver(new PthreadsChannelReader($this->mainToThreadBuffer)), - new RakLibToUserThreadMessageSender(new SnoozeAwarePthreadsChannelWriter($this->threadToMainBuffer, $this->sleeperEntry->createNotifier())), - new ExceptionTraceCleaner($this->mainPath) - ); - $this->synchronized(function() : void{ - $this->ready = true; - $this->notify(); - }); - while(!$this->isKilled){ - $manager->tickProcessor(); - } - $manager->waitShutdown(); - $this->cleanShutdown = true; - }catch(\Throwable $e){ - $this->setCrashInfo(RakLibThreadCrashInfo::fromThrowable($e)); - $this->logger->logException($e); + $socket = new ServerSocket($this->address->deserialize()); + $manager = new Server( + $this->serverId, + $this->logger, + $socket, + $this->maxMtuSize, + new SimpleProtocolAcceptor($this->protocolVersion), + new UserToRakLibThreadMessageReceiver(new PthreadsChannelReader($this->mainToThreadBuffer)), + new RakLibToUserThreadMessageSender(new SnoozeAwarePthreadsChannelWriter($this->threadToMainBuffer, $this->sleeperEntry->createNotifier())), + new ExceptionTraceCleaner($this->mainPath) + ); + $this->synchronized(function() : void{ + $this->ready = true; + $this->notify(); + }); + while(!$this->isKilled){ + $manager->tickProcessor(); } + $manager->waitShutdown(); + } + + protected function onUncaughtException(\Throwable $e) : void{ + parent::onUncaughtException($e); + $this->logger->logException($e); } public function getThreadName() : string{ diff --git a/src/network/mcpe/raklib/RakLibThreadCrashInfo.php b/src/network/mcpe/raklib/RakLibThreadCrashInfo.php deleted file mode 100644 index 60e04b4b4..000000000 --- a/src/network/mcpe/raklib/RakLibThreadCrashInfo.php +++ /dev/null @@ -1,61 +0,0 @@ -getMessage(), $e->getFile(), $e->getLine()); - } - - /** - * @phpstan-param array{message: string, file: string, line: int} $info - */ - public static function fromLastErrorInfo(array $info) : self{ - return new self(null, $info["message"], $info["file"], $info["line"]); - } - - public function getClass() : ?string{ return $this->class; } - - public function getMessage() : string{ return $this->message; } - - public function getFile() : string{ return $this->file; } - - public function getLine() : int{ return $this->line; } - - public function makePrettyMessage() : string{ - return sprintf("%s: \"%s\" in %s on line %d", $this->class ?? "Fatal error", $this->message, Filesystem::cleanPath($this->file), $this->line); - } -} diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index 7540294ef..bb79df507 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -26,6 +26,7 @@ namespace pocketmine\scheduler; use pmmp\thread\Thread as NativeThread; use pocketmine\snooze\SleeperHandler; use pocketmine\thread\log\ThreadSafeLogger; +use pocketmine\thread\ThreadCrashException; use pocketmine\thread\ThreadSafeClassLoader; use pocketmine\timings\Timings; use pocketmine\utils\AssumptionFailedError; @@ -215,12 +216,17 @@ class AsyncPool{ } } } - if($crashedTask !== null){ - $message = "Worker $workerId crashed while running task " . get_class($crashedTask) . "#" . spl_object_id($crashedTask); + $info = $entry->worker->getCrashInfo(); + if($info !== null){ + if($crashedTask !== null){ + $message = "Worker $workerId crashed while running task " . get_class($crashedTask) . "#" . spl_object_id($crashedTask); + }else{ + $message = "Worker $workerId crashed while doing unknown work"; + } + throw new ThreadCrashException($message, $info); }else{ - $message = "Worker $workerId crashed for unknown reason"; + throw new \RuntimeException("Worker $workerId crashed for unknown reason"); } - throw new \RuntimeException($message); } } diff --git a/src/scheduler/AsyncWorker.php b/src/scheduler/AsyncWorker.php index 19a19b102..b26afc29b 100644 --- a/src/scheduler/AsyncWorker.php +++ b/src/scheduler/AsyncWorker.php @@ -31,7 +31,6 @@ use pocketmine\thread\Worker; use pocketmine\utils\AssumptionFailedError; use function gc_enable; use function ini_set; -use function set_exception_handler; class AsyncWorker extends Worker{ /** @var mixed[] */ @@ -68,20 +67,17 @@ class AsyncWorker extends Worker{ } $this->saveToThreadStore(self::TLS_KEY_NOTIFIER, $this->sleeperEntry->createNotifier()); + } - set_exception_handler(function(\Throwable $e){ - $this->logger->logException($e); - }); + protected function onUncaughtException(\Throwable $e) : void{ + parent::onUncaughtException($e); + $this->logger->logException($e); } public function getLogger() : ThreadSafeLogger{ return $this->logger; } - public function handleException(\Throwable $e) : void{ - $this->logger->logException($e); - } - public function getThreadName() : string{ return "AsyncWorker#" . $this->id; } diff --git a/src/thread/CommonThreadPartsTrait.php b/src/thread/CommonThreadPartsTrait.php index c35dd7791..340ce554d 100644 --- a/src/thread/CommonThreadPartsTrait.php +++ b/src/thread/CommonThreadPartsTrait.php @@ -26,7 +26,10 @@ namespace pocketmine\thread; use pmmp\thread\ThreadSafeArray; use pocketmine\errorhandler\ErrorToExceptionHandler; use pocketmine\Server; +use function error_get_last; use function error_reporting; +use function register_shutdown_function; +use function set_exception_handler; trait CommonThreadPartsTrait{ /** @@ -38,6 +41,8 @@ trait CommonThreadPartsTrait{ protected bool $isKilled = false; + private ?ThreadCrashInfo $crashInfo = null; + /** * @return ThreadSafeClassLoader[] */ @@ -88,12 +93,48 @@ trait CommonThreadPartsTrait{ } } + public function getCrashInfo() : ?ThreadCrashInfo{ return $this->crashInfo; } + final public function run() : void{ error_reporting(-1); $this->registerClassLoaders(); //set this after the autoloader is registered ErrorToExceptionHandler::set(); + + //this permits adding extra functionality to the exception and shutdown handlers via overriding + set_exception_handler($this->onUncaughtException(...)); + register_shutdown_function($this->onShutdown(...)); + $this->onRun(); + $this->isKilled = true; + } + + /** + * Called by set_exception_handler() when an uncaught exception is thrown. + */ + protected function onUncaughtException(\Throwable $e) : void{ + $this->synchronized(function() use ($e) : void{ + $this->crashInfo = ThreadCrashInfo::fromThrowable($e, $this->getThreadName()); + }); + } + + /** + * Called by register_shutdown_function() when the thread shuts down. This may be because of a benign shutdown, or + * because of a fatal error. Use isKilled to determine which. + */ + protected function onShutdown() : void{ + $this->synchronized(function() : void{ + if(!$this->isKilled && $this->crashInfo === null){ + $last = error_get_last(); + if($last !== null){ + //fatal error + $this->crashInfo = ThreadCrashInfo::fromLastErrorInfo($last, $this->getThreadName()); + }else{ + //probably misused exit() + $this->crashInfo = ThreadCrashInfo::fromThrowable(new \RuntimeException("Thread crashed without an error - perhaps exit() was called?"), $this->getThreadName()); + } + } + }); } /** diff --git a/src/thread/ThreadCrashException.php b/src/thread/ThreadCrashException.php new file mode 100644 index 000000000..0eba37934 --- /dev/null +++ b/src/thread/ThreadCrashException.php @@ -0,0 +1,38 @@ +crashInfo = $crashInfo; + } + + public function getCrashInfo() : ThreadCrashInfo{ + return $this->crashInfo; + } +} diff --git a/src/thread/ThreadCrashInfo.php b/src/thread/ThreadCrashInfo.php new file mode 100644 index 000000000..66aae927a --- /dev/null +++ b/src/thread/ThreadCrashInfo.php @@ -0,0 +1,89 @@ + */ + private ThreadSafeArray $trace; + + /** + * @param ThreadCrashInfoFrame[] $trace + */ + public function __construct( + private string $type, + private string $message, + private string $file, + private int $line, + array $trace, + private string $threadName + ){ + $this->trace = ThreadSafeArray::fromArray($trace); + } + + public static function fromThrowable(\Throwable $e, string $threadName) : self{ + return new self(get_class($e), $e->getMessage(), $e->getFile(), $e->getLine(), Utils::printableTraceWithMetadata($e->getTrace()), $threadName); + } + + /** + * @phpstan-param array{type: int, message: string, file: string, line: int} $info + */ + public static function fromLastErrorInfo(array $info, string $threadName) : self{ + try{ + $class = ErrorTypeToStringMap::get($info["type"]); + }catch(\InvalidArgumentException){ + $class = "Unknown error type (" . $info["type"] . ")"; + } + return new self($class, $info["message"], $info["file"], $info["line"], Utils::printableTraceWithMetadata(Utils::currentTrace()), $threadName); + } + + public function getType() : string{ return $this->type; } + + public function getMessage() : string{ return $this->message; } + + public function getFile() : string{ return $this->file; } + + public function getLine() : int{ return $this->line; } + + /** + * @return ThreadCrashInfoFrame[] + */ + public function getTrace() : array{ + return (array) $this->trace; + } + + public function getThreadName() : string{ return $this->threadName; } + + public function makePrettyMessage() : string{ + return sprintf("%s: \"%s\" in \"%s\" on line %d", $this->type ?? "Fatal error", $this->message, Filesystem::cleanPath($this->file), $this->line); + } +} diff --git a/src/thread/ThreadCrashInfoFrame.php b/src/thread/ThreadCrashInfoFrame.php new file mode 100644 index 000000000..27f470387 --- /dev/null +++ b/src/thread/ThreadCrashInfoFrame.php @@ -0,0 +1,41 @@ +printableFrame; } + + public function getFile() : ?string{ return $this->file; } + + public function getLine() : int{ return $this->line; } +} diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 11548e193..f5ec5f8e4 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -31,6 +31,7 @@ use DaveRandom\CallbackValidator\CallbackType; use pocketmine\entity\Location; use pocketmine\errorhandler\ErrorTypeToStringMap; use pocketmine\math\Vector3; +use pocketmine\thread\ThreadCrashInfoFrame; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use function array_combine; @@ -469,6 +470,30 @@ final class Utils{ return $messages; } + /** + * Similar to {@link Utils::printableTrace()}, but associates metadata such as file and line number with each frame. + * This is used to transmit thread-safe information about crash traces to the main thread when a thread crashes. + * + * @param mixed[][] $rawTrace + * @phpstan-param list> $rawTrace + * + * @return ThreadCrashInfoFrame[] + */ + public static function printableTraceWithMetadata(array $rawTrace, int $maxStringLength = 80) : array{ + $printableTrace = self::printableTrace($rawTrace, $maxStringLength); + $safeTrace = []; + foreach($printableTrace as $frameId => $printableFrame){ + $rawFrame = $rawTrace[$frameId]; + $safeTrace[$frameId] = new ThreadCrashInfoFrame( + $printableFrame, + $rawFrame["file"] ?? "unknown", + $rawFrame["line"] ?? 0 + ); + } + + return $safeTrace; + } + /** * @return mixed[][] * @phpstan-return list> diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index 27e881153..75118cc93 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -845,6 +845,16 @@ parameters: count: 1 path: ../../../src/utils/Utils.php + - + message: "#^Parameter \\#2 \\$file of class pocketmine\\\\thread\\\\ThreadCrashInfoFrame constructor expects string\\|null, mixed given\\.$#" + count: 1 + path: ../../../src/utils/Utils.php + + - + message: "#^Parameter \\#3 \\$line of class pocketmine\\\\thread\\\\ThreadCrashInfoFrame constructor expects int, mixed given\\.$#" + count: 1 + path: ../../../src/utils/Utils.php + - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" count: 1 From a45763328bdb6703304ac97dd5164665e5ab180e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Jul 2023 12:36:46 +0100 Subject: [PATCH 22/25] Added constants for default knockback force and vertical limit --- src/entity/Living.php | 13 ++++++++++++- src/event/entity/EntityDamageByEntityEvent.php | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index d1fbf4b8e..1b5b582da 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -80,6 +80,17 @@ use const M_PI; abstract class Living extends Entity{ protected const DEFAULT_BREATH_TICKS = 300; + /** + * The default knockback multiplier when an entity is hit by another entity. + * Larger values knock the entity back with increased velocity. + */ + public const DEFAULT_KNOCKBACK_FORCE = 0.4; + /** + * Limit of an entity's vertical knockback velocity when hit by another entity. Without this limit, the entity + * may be knocked far up into the air with large knockback forces. + */ + public const DEFAULT_KNOCKBACK_VERTICAL_LIMIT = 0.4; + private const TAG_LEGACY_HEALTH = "HealF"; //TAG_Float private const TAG_HEALTH = "Health"; //TAG_Float private const TAG_BREATH_TICKS = "Air"; //TAG_Short @@ -567,7 +578,7 @@ abstract class Living extends Entity{ $this->broadcastAnimation(new HurtAnimation($this)); } - public function knockBack(float $x, float $z, float $force = 0.4, ?float $verticalLimit = 0.4) : void{ + public function knockBack(float $x, float $z, float $force = self::DEFAULT_KNOCKBACK_FORCE, ?float $verticalLimit = self::DEFAULT_KNOCKBACK_VERTICAL_LIMIT) : void{ $f = sqrt($x * $x + $z * $z); if($f <= 0){ return; diff --git a/src/event/entity/EntityDamageByEntityEvent.php b/src/event/entity/EntityDamageByEntityEvent.php index 6264375bb..11214a3e0 100644 --- a/src/event/entity/EntityDamageByEntityEvent.php +++ b/src/event/entity/EntityDamageByEntityEvent.php @@ -36,7 +36,7 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ /** * @param float[] $modifiers */ - public function __construct(Entity $damager, Entity $entity, int $cause, float $damage, array $modifiers = [], private float $knockBack = 0.4){ + public function __construct(Entity $damager, Entity $entity, int $cause, float $damage, array $modifiers = [], private float $knockBack = Living::DEFAULT_KNOCKBACK_FORCE){ $this->damagerEntityId = $damager->getId(); parent::__construct($entity, $cause, $damage, $modifiers); $this->addAttackerModifiers($damager); From c972e657418d29b66f53f42e82e65a47b8a7a10f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Jul 2023 12:41:27 +0100 Subject: [PATCH 23/25] EntityDamageByEntityEvent: document methods --- src/event/entity/EntityDamageByEntityEvent.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/event/entity/EntityDamageByEntityEvent.php b/src/event/entity/EntityDamageByEntityEvent.php index 11214a3e0..b8eb95def 100644 --- a/src/event/entity/EntityDamageByEntityEvent.php +++ b/src/event/entity/EntityDamageByEntityEvent.php @@ -62,10 +62,20 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ return $this->getEntity()->getWorld()->getServer()->getWorldManager()->findEntity($this->damagerEntityId); } + /** + * Returns the force with which the victim will be knocked back from the attacking entity. + * + * @see Living::DEFAULT_KNOCKBACK_FORCE + */ public function getKnockBack() : float{ return $this->knockBack; } + /** + * Sets the force with which the victim will be knocked back from the attacking entity. + * Larger values will knock the victim back further. + * Negative values will pull the victim towards the attacker. + */ public function setKnockBack(float $knockBack) : void{ $this->knockBack = $knockBack; } From 5ec3f4655fe30a63827570877875b0f50c42901c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Jul 2023 12:52:15 +0100 Subject: [PATCH 24/25] EntityDamageByEntityEvent: added APIs to get and set vertical knockback limits this was requested and PR'd as far back as 2020 (see #3782). Since no issue was filed about this, it became forgotten until #5946. However, #5946 overcomplicates the solution to the problem, and breaks BC without an obvious reason. --- src/entity/Living.php | 4 +-- .../entity/EntityDamageByEntityEvent.php | 28 ++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index 1b5b582da..4d5e10cb3 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -557,14 +557,14 @@ abstract class Living extends Entity{ $e = $source->getChild(); if($e !== null){ $motion = $e->getMotion(); - $this->knockBack($motion->x, $motion->z, $source->getKnockBack()); + $this->knockBack($motion->x, $motion->z, $source->getKnockBack(), $source->getVerticalKnockBackLimit()); } }elseif($source instanceof EntityDamageByEntityEvent){ $e = $source->getDamager(); if($e !== null){ $deltaX = $this->location->x - $e->location->x; $deltaZ = $this->location->z - $e->location->z; - $this->knockBack($deltaX, $deltaZ, $source->getKnockBack()); + $this->knockBack($deltaX, $deltaZ, $source->getKnockBack(), $source->getVerticalKnockBackLimit()); } } diff --git a/src/event/entity/EntityDamageByEntityEvent.php b/src/event/entity/EntityDamageByEntityEvent.php index b8eb95def..5ef6c4b8e 100644 --- a/src/event/entity/EntityDamageByEntityEvent.php +++ b/src/event/entity/EntityDamageByEntityEvent.php @@ -36,7 +36,15 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ /** * @param float[] $modifiers */ - public function __construct(Entity $damager, Entity $entity, int $cause, float $damage, array $modifiers = [], private float $knockBack = Living::DEFAULT_KNOCKBACK_FORCE){ + public function __construct( + Entity $damager, + Entity $entity, + int $cause, + float $damage, + array $modifiers = [], + private float $knockBack = Living::DEFAULT_KNOCKBACK_FORCE, + private float $verticalKnockBackLimit = Living::DEFAULT_KNOCKBACK_VERTICAL_LIMIT + ){ $this->damagerEntityId = $damager->getId(); parent::__construct($entity, $cause, $damage, $modifiers); $this->addAttackerModifiers($damager); @@ -79,4 +87,22 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ public function setKnockBack(float $knockBack) : void{ $this->knockBack = $knockBack; } + + /** + * Returns the maximum upwards velocity the victim may have after being knocked back. + * This ensures that the victim doesn't fly up into the sky when high levels of knockback are applied. + * + * @see Living::DEFAULT_KNOCKBACK_VERTICAL_LIMIT + */ + public function getVerticalKnockBackLimit() : float{ + return $this->verticalKnockBackLimit; + } + + /** + * Sets the maximum upwards velocity the victim may have after being knocked back. + * Larger values will allow the victim to fly higher if the knockback force is also large. + */ + public function setVerticalKnockBackLimit(float $verticalKnockBackLimit) : void{ + $this->verticalKnockBackLimit = $verticalKnockBackLimit; + } } From 9b2a7b43c2985ba46a759d272dd5f3157a39d7f1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Jul 2023 16:06:29 +0100 Subject: [PATCH 25/25] ItemEntity: fixed O(n^2) performance issue when many of the same unstackable item are in the same place this produced a 40% performance improvement in a simulation with 800 item entities. If the items were all different, then this would still be a problem. However, many of the same unstackable items occupying the same space is a problem for SkyBlock farms, so this should improve performance for SkyBlock quite a bit. --- src/entity/object/ItemEntity.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 6e9fdcdcf..90eeece67 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -123,7 +123,7 @@ class ItemEntity extends Entity{ } } - if($this->hasMovementUpdate() && $this->despawnDelay % self::MERGE_CHECK_PERIOD === 0){ + if($this->hasMovementUpdate() && $this->isMergeCandidate() && $this->despawnDelay % self::MERGE_CHECK_PERIOD === 0){ $mergeable = [$this]; //in case the merge target ends up not being this $mergeTarget = $this; foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(0.5, 0.5, 0.5), $this) as $entity){ @@ -165,12 +165,19 @@ class ItemEntity extends Entity{ } } + private function isMergeCandidate() : bool{ + return $this->pickupDelay !== self::NEVER_DESPAWN && $this->item->getCount() < $this->item->getMaxStackSize(); + } + /** * Returns whether this item entity can merge with the given one. */ public function isMergeable(ItemEntity $entity) : bool{ + if(!$this->isMergeCandidate() || !$entity->isMergeCandidate()){ + return false; + } $item = $entity->item; - return $entity !== $this && $entity->pickupDelay !== self::NEVER_DESPAWN && $item->canStackWith($this->item) && $item->getCount() + $this->item->getCount() <= $item->getMaxStackSize(); + return $entity !== $this && $item->canStackWith($this->item) && $item->getCount() + $this->item->getCount() <= $item->getMaxStackSize(); } /**