diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 4f045bdc9..437ed963f 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -53,7 +53,7 @@ jobs: run: echo NAME=$(echo "${GITHUB_REPOSITORY,,}") >> $GITHUB_OUTPUT - name: Build image for tag - uses: docker/build-push-action@v6.6.1 + uses: docker/build-push-action@v6.7.0 with: push: true context: ./pocketmine-mp @@ -66,7 +66,7 @@ jobs: - name: Build image for major tag if: steps.channel.outputs.CHANNEL == 'stable' - uses: docker/build-push-action@v6.6.1 + uses: docker/build-push-action@v6.7.0 with: push: true context: ./pocketmine-mp @@ -79,7 +79,7 @@ jobs: - name: Build image for minor tag if: steps.channel.outputs.CHANNEL == 'stable' - uses: docker/build-push-action@v6.6.1 + uses: docker/build-push-action@v6.7.0 with: push: true context: ./pocketmine-mp @@ -92,7 +92,7 @@ jobs: - name: Build image for latest tag if: steps.channel.outputs.CHANNEL == 'stable' - uses: docker/build-push-action@v6.6.1 + uses: docker/build-push-action@v6.7.0 with: push: true context: ./pocketmine-mp diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7c92c0b8b..b5a9740b5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,3 +37,15 @@ jobs: - name: Run PHP-CS-Fixer run: php-cs-fixer fix --dry-run --diff --ansi + + shellcheck: + name: ShellCheck + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v4 + + - name: Run ShellCheck + uses: ludeeus/action-shellcheck@2.0.0 diff --git a/changelogs/5.18.md b/changelogs/5.18.md index 4b7911efe..35aa237af 100644 --- a/changelogs/5.18.md +++ b/changelogs/5.18.md @@ -17,3 +17,14 @@ Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if ## Fixes - Use `VISIBLE_MOB_EFFECTS` actor metadata property to send effect bubbles, this fixes effect bubbles not showing + +# 5.18.1 +Released 3rd September 2024. + +## Fixes +- Fixed shift-crafting. +- Blue Ice block no longer emits light & it's now dropped when mined with a tool with silk touch enchantment. + +## Internals +- Pull Requests from team members now get an approval automatically. This means that if a team member makes a PR, only one other approval should be needed. +- Added [ShellCheck](https://github.com/koalaman/shellcheck) to the CI tests. diff --git a/changelogs/5.19.md b/changelogs/5.19.md new file mode 100644 index 000000000..57d322bf7 --- /dev/null +++ b/changelogs/5.19.md @@ -0,0 +1,16 @@ +# 5.19.0 +Released 21tst September 2024. + +**For Minecraft: Bedrock Edition 1.21.30** + +This is a support release for Minecraft: Bedrock Edition 1.21.30. + +**Plugin compatibility:** Plugins for previous 5.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` or `pocketmine\data` namespace. +Do not update plugin minimum API versions unless you need new features added in this release. + +**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.** +Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly. + +## General +- Added support for Minecraft: Bedrock Edition 1.21.30. +- Removed support for earlier versions. diff --git a/composer.json b/composer.json index 407528c92..b894bc3be 100644 --- a/composer.json +++ b/composer.json @@ -33,10 +33,10 @@ "composer-runtime-api": "^2.0", "adhocore/json-comment": "~1.2.0", "pocketmine/netresearch-jsonmapper": "~v4.4.999", - "pocketmine/bedrock-block-upgrade-schema": "~4.3.0+bedrock-1.21.20", - "pocketmine/bedrock-data": "~2.12.0+bedrock-1.21.20", - "pocketmine/bedrock-item-upgrade-schema": "~1.11.0+bedrock-1.21.20", - "pocketmine/bedrock-protocol": "~33.0.0+bedrock-1.21.20", + "pocketmine/bedrock-block-upgrade-schema": "~4.4.0+bedrock-1.21.30", + "pocketmine/bedrock-data": "~2.13.0+bedrock-1.21.30", + "pocketmine/bedrock-item-upgrade-schema": "~1.12.0+bedrock-1.21.30", + "pocketmine/bedrock-protocol": "~34.0.0+bedrock-1.21.30", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/color": "^0.3.0", @@ -52,7 +52,7 @@ "symfony/filesystem": "~6.4.0" }, "require-dev": { - "phpstan/phpstan": "1.11.10", + "phpstan/phpstan": "1.11.11", "phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-strict-rules": "^1.2.0", "phpunit/phpunit": "^10.5.24" diff --git a/composer.lock b/composer.lock index 5eb9a2158..d023c74ac 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": "fab1e131dfd049da39a87d4e562f1870", + "content-hash": "e16d3ebe48e32bbf96348981249c0ac1", "packages": [ { "name": "adhocore/json-comment", @@ -127,16 +127,16 @@ }, { "name": "pocketmine/bedrock-block-upgrade-schema", - "version": "4.3.0", + "version": "4.4.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockBlockUpgradeSchema.git", - "reference": "53d3a41c37ce90d58b33130cdadad08e442d7c47" + "reference": "89e5f6e19c29e0d0d24835639f72a5ef157c2761" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/53d3a41c37ce90d58b33130cdadad08e442d7c47", - "reference": "53d3a41c37ce90d58b33130cdadad08e442d7c47", + "url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/89e5f6e19c29e0d0d24835639f72a5ef157c2761", + "reference": "89e5f6e19c29e0d0d24835639f72a5ef157c2761", "shasum": "" }, "type": "library", @@ -147,22 +147,22 @@ "description": "Schemas describing how to upgrade saved block data in older Minecraft: Bedrock Edition world saves", "support": { "issues": "https://github.com/pmmp/BedrockBlockUpgradeSchema/issues", - "source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/4.3.0" + "source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/4.4.0" }, - "time": "2024-08-13T18:04:27+00:00" + "time": "2024-09-17T16:06:36+00:00" }, { "name": "pocketmine/bedrock-data", - "version": "2.12.0+bedrock-1.21.20", + "version": "2.13.0+bedrock-1.21.30", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockData.git", - "reference": "d4ee3d08964fa16fbbdd04af1fb52bbde540b665" + "reference": "23d9356b866654cbd2a62b31373118bedb4a2562" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/d4ee3d08964fa16fbbdd04af1fb52bbde540b665", - "reference": "d4ee3d08964fa16fbbdd04af1fb52bbde540b665", + "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/23d9356b866654cbd2a62b31373118bedb4a2562", + "reference": "23d9356b866654cbd2a62b31373118bedb4a2562", "shasum": "" }, "type": "library", @@ -173,22 +173,22 @@ "description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP", "support": { "issues": "https://github.com/pmmp/BedrockData/issues", - "source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.21.20" + "source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.21.30" }, - "time": "2024-08-15T12:50:26+00:00" + "time": "2024-09-17T16:03:14+00:00" }, { "name": "pocketmine/bedrock-item-upgrade-schema", - "version": "1.11.0", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockItemUpgradeSchema.git", - "reference": "35c18d093fc2b12da8737b2edb2c3ad6a14a53dd" + "reference": "85a0014c7dfd4a25c22a9efb0b447afb7dc6c409" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/35c18d093fc2b12da8737b2edb2c3ad6a14a53dd", - "reference": "35c18d093fc2b12da8737b2edb2c3ad6a14a53dd", + "url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/85a0014c7dfd4a25c22a9efb0b447afb7dc6c409", + "reference": "85a0014c7dfd4a25c22a9efb0b447afb7dc6c409", "shasum": "" }, "type": "library", @@ -199,22 +199,22 @@ "description": "JSON schemas for upgrading items found in older Minecraft: Bedrock world saves", "support": { "issues": "https://github.com/pmmp/BedrockItemUpgradeSchema/issues", - "source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.11.0" + "source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.12.0" }, - "time": "2024-08-13T18:06:25+00:00" + "time": "2024-09-11T19:48:31+00:00" }, { "name": "pocketmine/bedrock-protocol", - "version": "33.0.0+bedrock-1.21.20", + "version": "34.0.0+bedrock-1.21.30", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "e2264137c5cd0522de2c6ee4921a3a803818ea32" + "reference": "440c8078c66cc2a8f2abf58468df7df7246ee33b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/e2264137c5cd0522de2c6ee4921a3a803818ea32", - "reference": "e2264137c5cd0522de2c6ee4921a3a803818ea32", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/440c8078c66cc2a8f2abf58468df7df7246ee33b", + "reference": "440c8078c66cc2a8f2abf58468df7df7246ee33b", "shasum": "" }, "require": { @@ -227,7 +227,7 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "1.11.2", + "phpstan/phpstan": "1.11.9", "phpstan/phpstan-phpunit": "^1.0.0", "phpstan/phpstan-strict-rules": "^1.0.0", "phpunit/phpunit": "^9.5 || ^10.0" @@ -245,9 +245,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/32.2.0+bedrock-1.21.2" + "source": "https://github.com/pmmp/BedrockProtocol/tree/34.0.0+bedrock-1.21.30" }, - "time": "2024-08-10T19:23:18+00:00" + "time": "2024-09-18T20:58:42+00:00" }, { "name": "pocketmine/binaryutils", @@ -1389,16 +1389,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.10", + "version": "1.11.11", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "640410b32995914bde3eed26fa89552f9c2c082f" + "reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/640410b32995914bde3eed26fa89552f9c2c082f", - "reference": "640410b32995914bde3eed26fa89552f9c2c082f", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/707c2aed5d8d0075666e673a5e71440c1d01a5a3", + "reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3", "shasum": "" }, "require": { @@ -1443,7 +1443,7 @@ "type": "github" } ], - "time": "2024-08-08T09:02:50+00:00" + "time": "2024-08-19T14:37:29+00:00" }, { "name": "phpstan/phpstan-phpunit", diff --git a/src/VersionInfo.php b/src/VersionInfo.php index b292b4c45..b2d2fe4ab 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,7 +31,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "5.18.1"; + public const BASE_VERSION = "5.19.1"; public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "stable"; diff --git a/src/block/BlueIce.php b/src/block/BlueIce.php index f7e9a0404..11e3498dd 100644 --- a/src/block/BlueIce.php +++ b/src/block/BlueIce.php @@ -27,10 +27,6 @@ use pocketmine\item\Item; class BlueIce extends Opaque{ - public function getLightLevel() : int{ - return 1; - } - public function getFrictionFactor() : float{ return 0.99; } @@ -38,4 +34,8 @@ class BlueIce extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return []; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/ChiseledBookshelf.php b/src/block/ChiseledBookshelf.php index 89340a8f3..73c4861bf 100644 --- a/src/block/ChiseledBookshelf.php +++ b/src/block/ChiseledBookshelf.php @@ -48,11 +48,32 @@ class ChiseledBookshelf extends Opaque{ */ private array $slots = []; + private ?ChiseledBookshelfSlot $lastInteractedSlot = null; + protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{ $w->horizontalFacing($this->facing); $w->enumSet($this->slots, ChiseledBookshelfSlot::cases()); } + public function readStateFromWorld() : Block{ + $tile = $this->position->getWorld()->getTile($this->position); + if($tile instanceof TileChiseledBookshelf){ + $this->lastInteractedSlot = $tile->getLastInteractedSlot(); + }else{ + $this->lastInteractedSlot = null; + } + return $this; + } + + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + + $tile = $this->position->getWorld()->getTile($this->position); + if($tile instanceof TileChiseledBookshelf){ + $tile->setLastInteractedSlot($this->lastInteractedSlot); + } + } + /** * Returns whether the given slot is displayed as occupied. * This doesn't guarantee that there is or isn't a book in the bookshelf's inventory. @@ -92,6 +113,23 @@ class ChiseledBookshelf extends Opaque{ return $this->slots; } + /** + * Returns the last slot interacted by a player or null if no slot has been interacted with yet. + */ + public function getLastInteractedSlot() : ?ChiseledBookshelfSlot{ + return $this->lastInteractedSlot; + } + + /** + * Sets the last slot interacted by a player. + * + * @return $this + */ + public function setLastInteractedSlot(?ChiseledBookshelfSlot $lastInteractedSlot) : self{ + $this->lastInteractedSlot = $lastInteractedSlot; + return $this; + } + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ if($face !== $this->facing){ return false; @@ -112,10 +150,12 @@ class ChiseledBookshelf extends Opaque{ $returnedItems[] = $inventory->getItem($slot->value); $inventory->clear($slot->value); $this->setSlot($slot, false); + $this->lastInteractedSlot = $slot; }elseif($item instanceof WritableBookBase || $item instanceof Book || $item instanceof EnchantedBook){ //TODO: type tags like blocks would be better for this $inventory->setItem($slot->value, $item->pop()); $this->setSlot($slot, true); + $this->lastInteractedSlot = $slot; }else{ return true; } diff --git a/src/block/tile/ChiseledBookshelf.php b/src/block/tile/ChiseledBookshelf.php index 6455208fe..06175e27f 100644 --- a/src/block/tile/ChiseledBookshelf.php +++ b/src/block/tile/ChiseledBookshelf.php @@ -40,8 +40,12 @@ use function count; class ChiseledBookshelf extends Tile implements Container{ use ContainerTrait; + private const TAG_LAST_INTERACTED_SLOT = "LastInteractedSlot"; //TAG_Int + private SimpleInventory $inventory; + private ?ChiseledBookshelfSlot $lastInteractedSlot = null; + public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); $this->inventory = new SimpleInventory(count(ChiseledBookshelfSlot::cases())); @@ -55,12 +59,30 @@ class ChiseledBookshelf extends Tile implements Container{ return $this->inventory; } + public function getLastInteractedSlot() : ?ChiseledBookshelfSlot{ + return $this->lastInteractedSlot; + } + + public function setLastInteractedSlot(?ChiseledBookshelfSlot $lastInteractedSlot) : void{ + $this->lastInteractedSlot = $lastInteractedSlot; + } + public function readSaveData(CompoundTag $nbt) : void{ $this->loadItems($nbt); + + $lastInteractedSlot = $nbt->getInt(self::TAG_LAST_INTERACTED_SLOT, 0); + if($lastInteractedSlot !== 0){ + $this->lastInteractedSlot = ChiseledBookshelfSlot::tryFrom($lastInteractedSlot - 1); + } } protected function writeSaveData(CompoundTag $nbt) : void{ $this->saveItems($nbt); + + $nbt->setInt(self::TAG_LAST_INTERACTED_SLOT, $this->lastInteractedSlot !== null ? + $this->lastInteractedSlot->value + 1 : + 0 + ); } protected function loadItems(CompoundTag $tag) : void{ diff --git a/src/data/bedrock/block/BlockStateData.php b/src/data/bedrock/block/BlockStateData.php index 1973b55af..f405e4cf6 100644 --- a/src/data/bedrock/block/BlockStateData.php +++ b/src/data/bedrock/block/BlockStateData.php @@ -45,8 +45,8 @@ final class BlockStateData{ public const CURRENT_VERSION = (1 << 24) | //major (21 << 16) | //minor - (20 << 8) | //patch - (6); //revision + (30 << 8) | //patch + (7); //revision public const TAG_NAME = "name"; public const TAG_STATES = "states"; diff --git a/src/data/bedrock/block/BlockStateNames.php b/src/data/bedrock/block/BlockStateNames.php index e9c33bee2..c54822671 100644 --- a/src/data/bedrock/block/BlockStateNames.php +++ b/src/data/bedrock/block/BlockStateNames.php @@ -34,7 +34,6 @@ final class BlockStateNames{ public const ACTIVE = "active"; public const AGE = "age"; public const AGE_BIT = "age_bit"; - public const ALLOW_UNDERWATER_BIT = "allow_underwater_bit"; public const ATTACHED_BIT = "attached_bit"; public const ATTACHMENT = "attachment"; public const BAMBOO_LEAF_SIZE = "bamboo_leaf_size"; @@ -52,10 +51,7 @@ final class BlockStateNames{ public const CAN_SUMMON = "can_summon"; public const CANDLES = "candles"; public const CAULDRON_LIQUID = "cauldron_liquid"; - public const CHEMISTRY_TABLE_TYPE = "chemistry_table_type"; - public const CHISEL_TYPE = "chisel_type"; public const CLUSTER_COUNT = "cluster_count"; - public const COLOR_BIT = "color_bit"; public const COMPOSTER_FILL_LEVEL = "composter_fill_level"; public const CONDITIONAL_BIT = "conditional_bit"; public const CORAL_DIRECTION = "coral_direction"; @@ -116,12 +112,10 @@ final class BlockStateNames{ public const ROTATION = "rotation"; public const SCULK_SENSOR_PHASE = "sculk_sensor_phase"; public const SEA_GRASS_TYPE = "sea_grass_type"; - public const SPONGE_TYPE = "sponge_type"; public const STABILITY = "stability"; public const STABILITY_CHECK = "stability_check"; public const STRIPPED_BIT = "stripped_bit"; public const STRUCTURE_BLOCK_TYPE = "structure_block_type"; - public const STRUCTURE_VOID_TYPE = "structure_void_type"; public const SUSPENDED_BIT = "suspended_bit"; public const TOGGLE_BIT = "toggle_bit"; public const TORCH_FACING_DIRECTION = "torch_facing_direction"; @@ -134,7 +128,6 @@ final class BlockStateNames{ public const UPSIDE_DOWN_BIT = "upside_down_bit"; public const VAULT_STATE = "vault_state"; public const VINE_DIRECTION_BITS = "vine_direction_bits"; - public const WALL_BLOCK_TYPE = "wall_block_type"; public const WALL_CONNECTION_TYPE_EAST = "wall_connection_type_east"; public const WALL_CONNECTION_TYPE_NORTH = "wall_connection_type_north"; public const WALL_CONNECTION_TYPE_SOUTH = "wall_connection_type_south"; diff --git a/src/data/bedrock/block/BlockStateStringValues.php b/src/data/bedrock/block/BlockStateStringValues.php index 1794e240d..9dfdcfb63 100644 --- a/src/data/bedrock/block/BlockStateStringValues.php +++ b/src/data/bedrock/block/BlockStateStringValues.php @@ -52,16 +52,6 @@ final class BlockStateStringValues{ public const CAULDRON_LIQUID_POWDER_SNOW = "powder_snow"; public const CAULDRON_LIQUID_WATER = "water"; - public const CHEMISTRY_TABLE_TYPE_COMPOUND_CREATOR = "compound_creator"; - public const CHEMISTRY_TABLE_TYPE_ELEMENT_CONSTRUCTOR = "element_constructor"; - public const CHEMISTRY_TABLE_TYPE_LAB_TABLE = "lab_table"; - public const CHEMISTRY_TABLE_TYPE_MATERIAL_REDUCER = "material_reducer"; - - public const CHISEL_TYPE_CHISELED = "chiseled"; - public const CHISEL_TYPE_DEFAULT = "default"; - public const CHISEL_TYPE_LINES = "lines"; - public const CHISEL_TYPE_SMOOTH = "smooth"; - public const CRACKED_STATE_CRACKED = "cracked"; public const CRACKED_STATE_MAX_CRACKED = "max_cracked"; public const CRACKED_STATE_NO_CRACKS = "no_cracks"; @@ -128,9 +118,6 @@ final class BlockStateStringValues{ public const SEA_GRASS_TYPE_DOUBLE_BOT = "double_bot"; public const SEA_GRASS_TYPE_DOUBLE_TOP = "double_top"; - public const SPONGE_TYPE_DRY = "dry"; - public const SPONGE_TYPE_WET = "wet"; - public const STRUCTURE_BLOCK_TYPE_CORNER = "corner"; public const STRUCTURE_BLOCK_TYPE_DATA = "data"; public const STRUCTURE_BLOCK_TYPE_EXPORT = "export"; @@ -138,9 +125,6 @@ final class BlockStateStringValues{ public const STRUCTURE_BLOCK_TYPE_LOAD = "load"; public const STRUCTURE_BLOCK_TYPE_SAVE = "save"; - public const STRUCTURE_VOID_TYPE_AIR = "air"; - public const STRUCTURE_VOID_TYPE_VOID = "void"; - public const TORCH_FACING_DIRECTION_EAST = "east"; public const TORCH_FACING_DIRECTION_NORTH = "north"; public const TORCH_FACING_DIRECTION_SOUTH = "south"; @@ -158,21 +142,6 @@ final class BlockStateStringValues{ public const VAULT_STATE_INACTIVE = "inactive"; public const VAULT_STATE_UNLOCKING = "unlocking"; - public const WALL_BLOCK_TYPE_ANDESITE = "andesite"; - public const WALL_BLOCK_TYPE_BRICK = "brick"; - public const WALL_BLOCK_TYPE_COBBLESTONE = "cobblestone"; - public const WALL_BLOCK_TYPE_DIORITE = "diorite"; - public const WALL_BLOCK_TYPE_END_BRICK = "end_brick"; - public const WALL_BLOCK_TYPE_GRANITE = "granite"; - public const WALL_BLOCK_TYPE_MOSSY_COBBLESTONE = "mossy_cobblestone"; - public const WALL_BLOCK_TYPE_MOSSY_STONE_BRICK = "mossy_stone_brick"; - public const WALL_BLOCK_TYPE_NETHER_BRICK = "nether_brick"; - public const WALL_BLOCK_TYPE_PRISMARINE = "prismarine"; - public const WALL_BLOCK_TYPE_RED_NETHER_BRICK = "red_nether_brick"; - public const WALL_BLOCK_TYPE_RED_SANDSTONE = "red_sandstone"; - public const WALL_BLOCK_TYPE_SANDSTONE = "sandstone"; - public const WALL_BLOCK_TYPE_STONE_BRICK = "stone_brick"; - public const WALL_CONNECTION_TYPE_EAST_NONE = "none"; public const WALL_CONNECTION_TYPE_EAST_SHORT = "short"; public const WALL_CONNECTION_TYPE_EAST_TALL = "tall"; diff --git a/src/data/bedrock/block/BlockTypeNames.php b/src/data/bedrock/block/BlockTypeNames.php index f74f858ce..ec5565715 100644 --- a/src/data/bedrock/block/BlockTypeNames.php +++ b/src/data/bedrock/block/BlockTypeNames.php @@ -59,6 +59,7 @@ final class BlockTypeNames{ public const ANDESITE_DOUBLE_SLAB = "minecraft:andesite_double_slab"; public const ANDESITE_SLAB = "minecraft:andesite_slab"; public const ANDESITE_STAIRS = "minecraft:andesite_stairs"; + public const ANDESITE_WALL = "minecraft:andesite_wall"; public const ANVIL = "minecraft:anvil"; public const AZALEA = "minecraft:azalea"; public const AZALEA_LEAVES = "minecraft:azalea_leaves"; @@ -154,6 +155,7 @@ final class BlockTypeNames{ public const BRICK_DOUBLE_SLAB = "minecraft:brick_double_slab"; public const BRICK_SLAB = "minecraft:brick_slab"; public const BRICK_STAIRS = "minecraft:brick_stairs"; + public const BRICK_WALL = "minecraft:brick_wall"; public const BROWN_CANDLE = "minecraft:brown_candle"; public const BROWN_CANDLE_CAKE = "minecraft:brown_candle_cake"; public const BROWN_CARPET = "minecraft:brown_carpet"; @@ -191,7 +193,6 @@ final class BlockTypeNames{ public const CHAIN = "minecraft:chain"; public const CHAIN_COMMAND_BLOCK = "minecraft:chain_command_block"; public const CHEMICAL_HEAT = "minecraft:chemical_heat"; - public const CHEMISTRY_TABLE = "minecraft:chemistry_table"; public const CHERRY_BUTTON = "minecraft:cherry_button"; public const CHERRY_DOOR = "minecraft:cherry_door"; public const CHERRY_DOUBLE_SLAB = "minecraft:cherry_double_slab"; @@ -239,10 +240,13 @@ final class BlockTypeNames{ public const COBBLESTONE_SLAB = "minecraft:cobblestone_slab"; public const COBBLESTONE_WALL = "minecraft:cobblestone_wall"; public const COCOA = "minecraft:cocoa"; - public const COLORED_TORCH_BP = "minecraft:colored_torch_bp"; - public const COLORED_TORCH_RG = "minecraft:colored_torch_rg"; + public const COLORED_TORCH_BLUE = "minecraft:colored_torch_blue"; + public const COLORED_TORCH_GREEN = "minecraft:colored_torch_green"; + public const COLORED_TORCH_PURPLE = "minecraft:colored_torch_purple"; + public const COLORED_TORCH_RED = "minecraft:colored_torch_red"; public const COMMAND_BLOCK = "minecraft:command_block"; public const COMPOSTER = "minecraft:composter"; + public const COMPOUND_CREATOR = "minecraft:compound_creator"; public const CONDUIT = "minecraft:conduit"; public const COPPER_BLOCK = "minecraft:copper_block"; public const COPPER_BULB = "minecraft:copper_bulb"; @@ -365,6 +369,8 @@ final class BlockTypeNames{ public const DEEPSLATE_TILES = "minecraft:deepslate_tiles"; public const DENY = "minecraft:deny"; public const DEPRECATED_ANVIL = "minecraft:deprecated_anvil"; + public const DEPRECATED_PURPUR_BLOCK_1 = "minecraft:deprecated_purpur_block_1"; + public const DEPRECATED_PURPUR_BLOCK_2 = "minecraft:deprecated_purpur_block_2"; public const DETECTOR_RAIL = "minecraft:detector_rail"; public const DIAMOND_BLOCK = "minecraft:diamond_block"; public const DIAMOND_ORE = "minecraft:diamond_ore"; @@ -372,6 +378,7 @@ final class BlockTypeNames{ public const DIORITE_DOUBLE_SLAB = "minecraft:diorite_double_slab"; public const DIORITE_SLAB = "minecraft:diorite_slab"; public const DIORITE_STAIRS = "minecraft:diorite_stairs"; + public const DIORITE_WALL = "minecraft:diorite_wall"; public const DIRT = "minecraft:dirt"; public const DIRT_WITH_ROOTS = "minecraft:dirt_with_roots"; public const DISPENSER = "minecraft:dispenser"; @@ -499,6 +506,7 @@ final class BlockTypeNames{ public const ELEMENT_97 = "minecraft:element_97"; public const ELEMENT_98 = "minecraft:element_98"; public const ELEMENT_99 = "minecraft:element_99"; + public const ELEMENT_CONSTRUCTOR = "minecraft:element_constructor"; public const EMERALD_BLOCK = "minecraft:emerald_block"; public const EMERALD_ORE = "minecraft:emerald_ore"; public const ENCHANTING_TABLE = "minecraft:enchanting_table"; @@ -511,6 +519,7 @@ final class BlockTypeNames{ public const END_STONE = "minecraft:end_stone"; public const END_STONE_BRICK_DOUBLE_SLAB = "minecraft:end_stone_brick_double_slab"; public const END_STONE_BRICK_SLAB = "minecraft:end_stone_brick_slab"; + public const END_STONE_BRICK_WALL = "minecraft:end_stone_brick_wall"; public const ENDER_CHEST = "minecraft:ender_chest"; public const EXPOSED_CHISELED_COPPER = "minecraft:exposed_chiseled_copper"; public const EXPOSED_COPPER = "minecraft:exposed_copper"; @@ -553,6 +562,7 @@ final class BlockTypeNames{ public const GRANITE_DOUBLE_SLAB = "minecraft:granite_double_slab"; public const GRANITE_SLAB = "minecraft:granite_slab"; public const GRANITE_STAIRS = "minecraft:granite_stairs"; + public const GRANITE_WALL = "minecraft:granite_wall"; public const GRASS_BLOCK = "minecraft:grass_block"; public const GRASS_PATH = "minecraft:grass_path"; public const GRAVEL = "minecraft:gravel"; @@ -661,6 +671,7 @@ final class BlockTypeNames{ public const JUNGLE_WALL_SIGN = "minecraft:jungle_wall_sign"; public const JUNGLE_WOOD = "minecraft:jungle_wood"; public const KELP = "minecraft:kelp"; + public const LAB_TABLE = "minecraft:lab_table"; public const LADDER = "minecraft:ladder"; public const LANTERN = "minecraft:lantern"; public const LAPIS_BLOCK = "minecraft:lapis_block"; @@ -761,6 +772,7 @@ final class BlockTypeNames{ public const MANGROVE_TRAPDOOR = "minecraft:mangrove_trapdoor"; public const MANGROVE_WALL_SIGN = "minecraft:mangrove_wall_sign"; public const MANGROVE_WOOD = "minecraft:mangrove_wood"; + public const MATERIAL_REDUCER = "minecraft:material_reducer"; public const MEDIUM_AMETHYST_BUD = "minecraft:medium_amethyst_bud"; public const MELON_BLOCK = "minecraft:melon_block"; public const MELON_STEM = "minecraft:melon_stem"; @@ -771,9 +783,11 @@ final class BlockTypeNames{ public const MOSSY_COBBLESTONE_DOUBLE_SLAB = "minecraft:mossy_cobblestone_double_slab"; public const MOSSY_COBBLESTONE_SLAB = "minecraft:mossy_cobblestone_slab"; public const MOSSY_COBBLESTONE_STAIRS = "minecraft:mossy_cobblestone_stairs"; + public const MOSSY_COBBLESTONE_WALL = "minecraft:mossy_cobblestone_wall"; public const MOSSY_STONE_BRICK_DOUBLE_SLAB = "minecraft:mossy_stone_brick_double_slab"; public const MOSSY_STONE_BRICK_SLAB = "minecraft:mossy_stone_brick_slab"; public const MOSSY_STONE_BRICK_STAIRS = "minecraft:mossy_stone_brick_stairs"; + public const MOSSY_STONE_BRICK_WALL = "minecraft:mossy_stone_brick_wall"; public const MOSSY_STONE_BRICKS = "minecraft:mossy_stone_bricks"; public const MOVING_BLOCK = "minecraft:moving_block"; public const MUD = "minecraft:mud"; @@ -789,6 +803,7 @@ final class BlockTypeNames{ public const NETHER_BRICK_FENCE = "minecraft:nether_brick_fence"; public const NETHER_BRICK_SLAB = "minecraft:nether_brick_slab"; public const NETHER_BRICK_STAIRS = "minecraft:nether_brick_stairs"; + public const NETHER_BRICK_WALL = "minecraft:nether_brick_wall"; public const NETHER_GOLD_ORE = "minecraft:nether_gold_ore"; public const NETHER_SPROUTS = "minecraft:nether_sprouts"; public const NETHER_WART = "minecraft:nether_wart"; @@ -910,6 +925,7 @@ final class BlockTypeNames{ public const PRISMARINE_DOUBLE_SLAB = "minecraft:prismarine_double_slab"; public const PRISMARINE_SLAB = "minecraft:prismarine_slab"; public const PRISMARINE_STAIRS = "minecraft:prismarine_stairs"; + public const PRISMARINE_WALL = "minecraft:prismarine_wall"; public const PUMPKIN = "minecraft:pumpkin"; public const PUMPKIN_STEM = "minecraft:pumpkin_stem"; public const PURPLE_CANDLE = "minecraft:purple_candle"; @@ -925,6 +941,7 @@ final class BlockTypeNames{ public const PURPLE_WOOL = "minecraft:purple_wool"; public const PURPUR_BLOCK = "minecraft:purpur_block"; public const PURPUR_DOUBLE_SLAB = "minecraft:purpur_double_slab"; + public const PURPUR_PILLAR = "minecraft:purpur_pillar"; public const PURPUR_SLAB = "minecraft:purpur_slab"; public const PURPUR_STAIRS = "minecraft:purpur_stairs"; public const QUARTZ_BLOCK = "minecraft:quartz_block"; @@ -950,11 +967,13 @@ final class BlockTypeNames{ public const RED_NETHER_BRICK_DOUBLE_SLAB = "minecraft:red_nether_brick_double_slab"; public const RED_NETHER_BRICK_SLAB = "minecraft:red_nether_brick_slab"; public const RED_NETHER_BRICK_STAIRS = "minecraft:red_nether_brick_stairs"; + public const RED_NETHER_BRICK_WALL = "minecraft:red_nether_brick_wall"; public const RED_SAND = "minecraft:red_sand"; public const RED_SANDSTONE = "minecraft:red_sandstone"; public const RED_SANDSTONE_DOUBLE_SLAB = "minecraft:red_sandstone_double_slab"; public const RED_SANDSTONE_SLAB = "minecraft:red_sandstone_slab"; public const RED_SANDSTONE_STAIRS = "minecraft:red_sandstone_stairs"; + public const RED_SANDSTONE_WALL = "minecraft:red_sandstone_wall"; public const RED_SHULKER_BOX = "minecraft:red_shulker_box"; public const RED_STAINED_GLASS = "minecraft:red_stained_glass"; public const RED_STAINED_GLASS_PANE = "minecraft:red_stained_glass_pane"; @@ -977,6 +996,7 @@ final class BlockTypeNames{ public const SANDSTONE_DOUBLE_SLAB = "minecraft:sandstone_double_slab"; public const SANDSTONE_SLAB = "minecraft:sandstone_slab"; public const SANDSTONE_STAIRS = "minecraft:sandstone_stairs"; + public const SANDSTONE_WALL = "minecraft:sandstone_wall"; public const SCAFFOLDING = "minecraft:scaffolding"; public const SCULK = "minecraft:sculk"; public const SCULK_CATALYST = "minecraft:sculk_catalyst"; @@ -1047,6 +1067,7 @@ final class BlockTypeNames{ public const STONE_BRICK_DOUBLE_SLAB = "minecraft:stone_brick_double_slab"; public const STONE_BRICK_SLAB = "minecraft:stone_brick_slab"; public const STONE_BRICK_STAIRS = "minecraft:stone_brick_stairs"; + public const STONE_BRICK_WALL = "minecraft:stone_brick_wall"; public const STONE_BRICKS = "minecraft:stone_bricks"; public const STONE_BUTTON = "minecraft:stone_button"; public const STONE_PRESSURE_PLATE = "minecraft:stone_pressure_plate"; @@ -1108,6 +1129,7 @@ final class BlockTypeNames{ public const TUFF_WALL = "minecraft:tuff_wall"; public const TURTLE_EGG = "minecraft:turtle_egg"; public const TWISTING_VINES = "minecraft:twisting_vines"; + public const UNDERWATER_TNT = "minecraft:underwater_tnt"; public const UNDERWATER_TORCH = "minecraft:underwater_torch"; public const UNDYED_SHULKER_BOX = "minecraft:undyed_shulker_box"; public const UNKNOWN = "minecraft:unknown"; @@ -1192,6 +1214,7 @@ final class BlockTypeNames{ public const WEATHERED_DOUBLE_CUT_COPPER_SLAB = "minecraft:weathered_double_cut_copper_slab"; public const WEB = "minecraft:web"; public const WEEPING_VINES = "minecraft:weeping_vines"; + public const WET_SPONGE = "minecraft:wet_sponge"; public const WHEAT = "minecraft:wheat"; public const WHITE_CANDLE = "minecraft:white_candle"; public const WHITE_CANDLE_CAKE = "minecraft:white_candle_cake"; diff --git a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php index ccc9049c5..98a483a86 100644 --- a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php +++ b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php @@ -1097,7 +1097,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ); $this->mapSlab(Blocks::ANDESITE_SLAB(), Ids::ANDESITE_SLAB, Ids::ANDESITE_DOUBLE_SLAB); $this->map(Blocks::ANDESITE_STAIRS(), fn(Stair $block) => Helper::encodeStairs($block, new Writer(Ids::ANDESITE_STAIRS))); - $this->map(Blocks::ANDESITE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_ANDESITE)); + $this->map(Blocks::ANDESITE_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::ANDESITE_WALL))); $this->map(Blocks::ANVIL(), fn(Anvil $block) : Writer => Writer::create( match($damage = $block->getDamage()){ 0 => Ids::ANVIL, @@ -1174,7 +1174,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->mapStairs(Blocks::BLACKSTONE_STAIRS(), Ids::BLACKSTONE_STAIRS); $this->map(Blocks::BLACKSTONE_WALL(), fn(Wall $block) => Helper::encodeWall($block, new Writer(Ids::BLACKSTONE_WALL))); $this->map(Blocks::BLAST_FURNACE(), fn(Furnace $block) => Helper::encodeFurnace($block, Ids::BLAST_FURNACE, Ids::LIT_BLAST_FURNACE)); - $this->map(Blocks::BLUE_TORCH(), fn(Torch $block) => Helper::encodeColoredTorch($block, false, Writer::create(Ids::COLORED_TORCH_BP))); + $this->map(Blocks::BLUE_TORCH(), fn(Torch $block) => Helper::encodeTorch($block, Writer::create(Ids::COLORED_TORCH_BLUE))); $this->map(Blocks::BONE_BLOCK(), function(BoneBlock $block) : Writer{ return Writer::create(Ids::BONE_BLOCK) ->writeInt(StateNames::DEPRECATED, 0) @@ -1188,7 +1188,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ }); $this->mapSlab(Blocks::BRICK_SLAB(), Ids::BRICK_SLAB, Ids::BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::BRICK_STAIRS(), Ids::BRICK_STAIRS); - $this->map(Blocks::BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_BRICK)); + $this->map(Blocks::BRICK_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::BRICK_WALL))); $this->map(Blocks::BROWN_MUSHROOM_BLOCK(), fn(BrownMushroomBlock $block) => Helper::encodeMushroomBlock($block, new Writer(Ids::BROWN_MUSHROOM_BLOCK))); $this->map(Blocks::CACTUS(), function(Cactus $block) : Writer{ return Writer::create(Ids::CACTUS) @@ -1246,7 +1246,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->map(Blocks::COBBLED_DEEPSLATE_WALL(), fn(Wall $block) => Helper::encodeWall($block, new Writer(Ids::COBBLED_DEEPSLATE_WALL))); $this->mapSlab(Blocks::COBBLESTONE_SLAB(), Ids::COBBLESTONE_SLAB, Ids::COBBLESTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::COBBLESTONE_STAIRS(), Ids::STONE_STAIRS); - $this->map(Blocks::COBBLESTONE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_COBBLESTONE)); + $this->map(Blocks::COBBLESTONE_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::COBBLESTONE_WALL))); $this->map(Blocks::COPPER(), function(Copper $block) : Writer{ $oxidation = $block->getOxidation(); return new Writer($block->isWaxed() ? @@ -1326,7 +1326,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ->writeInt(StateNames::AGE, $block->getAge()) ->writeLegacyHorizontalFacing(Facing::opposite($block->getFacing())); }); - $this->map(Blocks::COMPOUND_CREATOR(), fn(ChemistryTable $block) => Helper::encodeChemistryTable($block, StringValues::CHEMISTRY_TABLE_TYPE_COMPOUND_CREATOR, new Writer(Ids::CHEMISTRY_TABLE))); + $this->map(Blocks::COMPOUND_CREATOR(), fn(ChemistryTable $block) => Helper::encodeChemistryTable($block, Writer::create(Ids::COMPOUND_CREATOR))); $this->mapSlab(Blocks::CUT_RED_SANDSTONE_SLAB(), Ids::CUT_RED_SANDSTONE_SLAB, Ids::CUT_RED_SANDSTONE_DOUBLE_SLAB); $this->mapSlab(Blocks::CUT_SANDSTONE_SLAB(), Ids::CUT_SANDSTONE_SLAB, Ids::CUT_SANDSTONE_DOUBLE_SLAB); $this->mapSlab(Blocks::DARK_PRISMARINE_SLAB(), Ids::DARK_PRISMARINE_SLAB, Ids::DARK_PRISMARINE_DOUBLE_SLAB); @@ -1353,7 +1353,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ }); $this->mapSlab(Blocks::DIORITE_SLAB(), Ids::DIORITE_SLAB, Ids::DIORITE_DOUBLE_SLAB); $this->mapStairs(Blocks::DIORITE_STAIRS(), Ids::DIORITE_STAIRS); - $this->map(Blocks::DIORITE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_DIORITE)); + $this->map(Blocks::DIORITE_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::DIORITE_WALL))); $this->map(Blocks::DIRT(), function(Dirt $block) : Writer{ return Writer::create(match($block->getDirtType()){ DirtType::NORMAL => Ids::DIRT, @@ -1362,7 +1362,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ }); }); $this->map(Blocks::DOUBLE_TALLGRASS(), fn(DoubleTallGrass $block) => Helper::encodeDoublePlant($block, Writer::create(Ids::TALL_GRASS))); - $this->map(Blocks::ELEMENT_CONSTRUCTOR(), fn(ChemistryTable $block) => Helper::encodeChemistryTable($block, StringValues::CHEMISTRY_TABLE_TYPE_ELEMENT_CONSTRUCTOR, new Writer(Ids::CHEMISTRY_TABLE))); + $this->map(Blocks::ELEMENT_CONSTRUCTOR(), fn(ChemistryTable $block) => Helper::encodeChemistryTable($block, Writer::create(Ids::ELEMENT_CONSTRUCTOR))); $this->map(Blocks::ENDER_CHEST(), function(EnderChest $block) : Writer{ return Writer::create(Ids::ENDER_CHEST) ->writeCardinalHorizontalFacing($block->getFacing()); @@ -1378,7 +1378,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ }); $this->mapSlab(Blocks::END_STONE_BRICK_SLAB(), Ids::END_STONE_BRICK_SLAB, Ids::END_STONE_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::END_STONE_BRICK_STAIRS(), Ids::END_BRICK_STAIRS); - $this->map(Blocks::END_STONE_BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_END_BRICK)); + $this->map(Blocks::END_STONE_BRICK_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::END_STONE_BRICK_WALL))); $this->mapSlab(Blocks::FAKE_WOODEN_SLAB(), Ids::PETRIFIED_OAK_SLAB, Ids::PETRIFIED_OAK_DOUBLE_SLAB); $this->map(Blocks::FARMLAND(), function(Farmland $block) : Writer{ return Writer::create(Ids::FARMLAND) @@ -1412,8 +1412,8 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->map(Blocks::GLOWING_ITEM_FRAME(), fn(ItemFrame $block) => Helper::encodeItemFrame($block, Ids::GLOW_FRAME)); $this->mapSlab(Blocks::GRANITE_SLAB(), Ids::GRANITE_SLAB, Ids::GRANITE_DOUBLE_SLAB); $this->mapStairs(Blocks::GRANITE_STAIRS(), Ids::GRANITE_STAIRS); - $this->map(Blocks::GRANITE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_GRANITE)); - $this->map(Blocks::GREEN_TORCH(), fn(Torch $block) => Helper::encodeColoredTorch($block, true, Writer::create(Ids::COLORED_TORCH_RG))); + $this->map(Blocks::GRANITE_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::GRANITE_WALL))); + $this->map(Blocks::GREEN_TORCH(), fn(Torch $block) => Helper::encodeTorch($block, Writer::create(Ids::COLORED_TORCH_GREEN))); $this->map(Blocks::HAY_BALE(), function(HayBale $block) : Writer{ return Writer::create(Ids::HAY_BLOCK) ->writeInt(StateNames::DEPRECATED, 0) @@ -1427,7 +1427,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->map(Blocks::IRON_DOOR(), fn(Door $block) => Helper::encodeDoor($block, new Writer(Ids::IRON_DOOR))); $this->map(Blocks::IRON_TRAPDOOR(), fn(Trapdoor $block) => Helper::encodeTrapdoor($block, new Writer(Ids::IRON_TRAPDOOR))); $this->map(Blocks::ITEM_FRAME(), fn(ItemFrame $block) => Helper::encodeItemFrame($block, Ids::FRAME)); - $this->map(Blocks::LAB_TABLE(), fn(ChemistryTable $block) => Helper::encodeChemistryTable($block, StringValues::CHEMISTRY_TABLE_TYPE_LAB_TABLE, new Writer(Ids::CHEMISTRY_TABLE))); + $this->map(Blocks::LAB_TABLE(), fn(ChemistryTable $block) => Helper::encodeChemistryTable($block, Writer::create(Ids::LAB_TABLE))); $this->map(Blocks::LADDER(), function(Ladder $block) : Writer{ return Writer::create(Ids::LADDER) ->writeHorizontalFacing($block->getFacing()); @@ -1491,7 +1491,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ return Writer::create(Ids::LOOM) ->writeLegacyHorizontalFacing($block->getFacing()); }); - $this->map(Blocks::MATERIAL_REDUCER(), fn(ChemistryTable $block) => Helper::encodeChemistryTable($block, StringValues::CHEMISTRY_TABLE_TYPE_MATERIAL_REDUCER, new Writer(Ids::CHEMISTRY_TABLE))); + $this->map(Blocks::MATERIAL_REDUCER(), fn(ChemistryTable $block) => Helper::encodeChemistryTable($block, Writer::create(Ids::MATERIAL_REDUCER))); $this->map(Blocks::MELON_STEM(), fn(MelonStem $block) => Helper::encodeStem($block, new Writer(Ids::MELON_STEM))); $this->map(Blocks::MOB_HEAD(), function(MobHead $block) : Writer{ return Writer::create(Ids::SKULL) @@ -1499,10 +1499,10 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ }); $this->mapSlab(Blocks::MOSSY_COBBLESTONE_SLAB(), Ids::MOSSY_COBBLESTONE_SLAB, Ids::MOSSY_COBBLESTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::MOSSY_COBBLESTONE_STAIRS(), Ids::MOSSY_COBBLESTONE_STAIRS); - $this->map(Blocks::MOSSY_COBBLESTONE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_MOSSY_COBBLESTONE)); + $this->map(Blocks::MOSSY_COBBLESTONE_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::MOSSY_COBBLESTONE_WALL))); $this->mapSlab(Blocks::MOSSY_STONE_BRICK_SLAB(), Ids::MOSSY_STONE_BRICK_SLAB, Ids::MOSSY_STONE_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::MOSSY_STONE_BRICK_STAIRS(), Ids::MOSSY_STONE_BRICK_STAIRS); - $this->map(Blocks::MOSSY_STONE_BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_MOSSY_STONE_BRICK)); + $this->map(Blocks::MOSSY_STONE_BRICK_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::MOSSY_STONE_BRICK_WALL))); $this->mapSlab(Blocks::MUD_BRICK_SLAB(), Ids::MUD_BRICK_SLAB, Ids::MUD_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::MUD_BRICK_STAIRS(), Ids::MUD_BRICK_STAIRS); $this->map(Blocks::MUD_BRICK_WALL(), fn(Wall $block) => Helper::encodeWall($block, new Writer(Ids::MUD_BRICK_WALL))); @@ -1512,7 +1512,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ->writeInt(StateNames::HUGE_MUSHROOM_BITS, BlockLegacyMetadata::MUSHROOM_BLOCK_STEM)); $this->mapSlab(Blocks::NETHER_BRICK_SLAB(), Ids::NETHER_BRICK_SLAB, Ids::NETHER_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::NETHER_BRICK_STAIRS(), Ids::NETHER_BRICK_STAIRS); - $this->map(Blocks::NETHER_BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_NETHER_BRICK)); + $this->map(Blocks::NETHER_BRICK_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::NETHER_BRICK_WALL))); $this->map(Blocks::NETHER_PORTAL(), function(NetherPortal $block) : Writer{ return Writer::create(Ids::PORTAL) ->writeString(StateNames::PORTAL_AXIS, match($block->getAxis()){ @@ -1579,21 +1579,16 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->mapStairs(Blocks::PRISMARINE_BRICKS_STAIRS(), Ids::PRISMARINE_BRICKS_STAIRS); $this->mapSlab(Blocks::PRISMARINE_SLAB(), Ids::PRISMARINE_SLAB, Ids::PRISMARINE_DOUBLE_SLAB); $this->mapStairs(Blocks::PRISMARINE_STAIRS(), Ids::PRISMARINE_STAIRS); - $this->map(Blocks::PRISMARINE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_PRISMARINE)); + $this->map(Blocks::PRISMARINE_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::PRISMARINE_WALL))); $this->map(Blocks::PUMPKIN(), function() : Writer{ return Writer::create(Ids::PUMPKIN) ->writeCardinalHorizontalFacing(Facing::SOUTH); //no longer used }); $this->map(Blocks::PUMPKIN_STEM(), fn(PumpkinStem $block) => Helper::encodeStem($block, new Writer(Ids::PUMPKIN_STEM))); - $this->map(Blocks::PURPLE_TORCH(), fn(Torch $block) => Helper::encodeColoredTorch($block, true, Writer::create(Ids::COLORED_TORCH_BP))); - $this->map(Blocks::PURPUR(), function() : Writer{ - return Writer::create(Ids::PURPUR_BLOCK) - ->writeString(StateNames::CHISEL_TYPE, StringValues::CHISEL_TYPE_DEFAULT) - ->writePillarAxis(Axis::Y); //useless, but MCPE wants it - }); + $this->map(Blocks::PURPUR(), fn() => Writer::create(Ids::PURPUR_BLOCK)->writePillarAxis(Axis::Y)); + $this->map(Blocks::PURPLE_TORCH(), fn(Torch $block) => Helper::encodeTorch($block, Writer::create(Ids::COLORED_TORCH_PURPLE))); $this->map(Blocks::PURPUR_PILLAR(), function(SimplePillar $block) : Writer{ - return Writer::create(Ids::PURPUR_BLOCK) - ->writeString(StateNames::CHISEL_TYPE, StringValues::CHISEL_TYPE_LINES) + return Writer::create(Ids::PURPUR_PILLAR) ->writePillarAxis($block->getAxis()); }); $this->mapSlab(Blocks::PURPUR_SLAB(), Ids::PURPUR_SLAB, Ids::PURPUR_DOUBLE_SLAB); @@ -1630,15 +1625,15 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->map(Blocks::RED_MUSHROOM_BLOCK(), fn(RedMushroomBlock $block) => Helper::encodeMushroomBlock($block, new Writer(Ids::RED_MUSHROOM_BLOCK))); $this->mapSlab(Blocks::RED_NETHER_BRICK_SLAB(), Ids::RED_NETHER_BRICK_SLAB, Ids::RED_NETHER_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::RED_NETHER_BRICK_STAIRS(), Ids::RED_NETHER_BRICK_STAIRS); - $this->map(Blocks::RED_NETHER_BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_RED_NETHER_BRICK)); + $this->map(Blocks::RED_NETHER_BRICK_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::RED_NETHER_BRICK_WALL))); $this->mapSlab(Blocks::RED_SANDSTONE_SLAB(), Ids::RED_SANDSTONE_SLAB, Ids::RED_SANDSTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::RED_SANDSTONE_STAIRS(), Ids::RED_SANDSTONE_STAIRS); - $this->map(Blocks::RED_SANDSTONE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_RED_SANDSTONE)); - $this->map(Blocks::RED_TORCH(), fn(Torch $block) => Helper::encodeColoredTorch($block, false, Writer::create(Ids::COLORED_TORCH_RG))); + $this->map(Blocks::RED_SANDSTONE_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::RED_SANDSTONE_WALL))); + $this->map(Blocks::RED_TORCH(), fn(Torch $block) => Helper::encodeTorch($block, Writer::create(Ids::COLORED_TORCH_RED))); $this->map(Blocks::ROSE_BUSH(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, Writer::create(Ids::ROSE_BUSH))); $this->mapSlab(Blocks::SANDSTONE_SLAB(), Ids::SANDSTONE_SLAB, Ids::SANDSTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::SANDSTONE_STAIRS(), Ids::SANDSTONE_STAIRS); - $this->map(Blocks::SANDSTONE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_SANDSTONE)); + $this->map(Blocks::SANDSTONE_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::SANDSTONE_WALL))); $this->map(Blocks::SEA_PICKLE(), function(SeaPickle $block) : Writer{ return Writer::create(Ids::SEA_PICKLE) ->writeBool(StateNames::DEAD_BIT, !$block->isUnderwater()) @@ -1680,15 +1675,12 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ return Writer::create(Ids::SOUL_TORCH) ->writeTorchFacing($block->getFacing()); }); - $this->map(Blocks::SPONGE(), function(Sponge $block) : Writer{ - return Writer::create(Ids::SPONGE) - ->writeString(StateNames::SPONGE_TYPE, $block->isWet() ? StringValues::SPONGE_TYPE_WET : StringValues::SPONGE_TYPE_DRY); - }); + $this->map(Blocks::SPONGE(), fn(Sponge $block) => Writer::create($block->isWet() ? Ids::WET_SPONGE : Ids::SPONGE)); $this->map(Blocks::STONECUTTER(), fn(Stonecutter $block) => Writer::create(Ids::STONECUTTER_BLOCK) ->writeCardinalHorizontalFacing($block->getFacing())); $this->mapSlab(Blocks::STONE_BRICK_SLAB(), Ids::STONE_BRICK_SLAB, Ids::STONE_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::STONE_BRICK_STAIRS(), Ids::STONE_BRICK_STAIRS); - $this->map(Blocks::STONE_BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_STONE_BRICK)); + $this->map(Blocks::STONE_BRICK_WALL(), fn(Wall $block) => Helper::encodeWall($block, Writer::create(Ids::STONE_BRICK_WALL))); $this->map(Blocks::STONE_BUTTON(), fn(StoneButton $block) => Helper::encodeButton($block, new Writer(Ids::STONE_BUTTON))); $this->map(Blocks::STONE_PRESSURE_PLATE(), fn(StonePressurePlate $block) => Helper::encodeSimplePressurePlate($block, new Writer(Ids::STONE_PRESSURE_PLATE))); $this->mapSlab(Blocks::STONE_SLAB(), Ids::NORMAL_STONE_SLAB, Ids::NORMAL_STONE_DOUBLE_SLAB); @@ -1702,11 +1694,9 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ return Writer::create(Ids::SWEET_BERRY_BUSH) ->writeInt(StateNames::GROWTH, $block->getAge()); }); - $this->map(Blocks::TNT(), function(TNT $block) : Writer{ - return Writer::create(Ids::TNT) - ->writeBool(StateNames::ALLOW_UNDERWATER_BIT, $block->worksUnderwater()) - ->writeBool(StateNames::EXPLODE_BIT, $block->isUnstable()); - }); + $this->map(Blocks::TNT(), fn(TNT $block) => Writer::create($block->worksUnderwater() ? Ids::UNDERWATER_TNT : Ids::TNT) + ->writeBool(StateNames::EXPLODE_BIT, $block->isUnstable()) + ); $this->map(Blocks::TORCH(), function(Torch $block) : Writer{ return Writer::create(Ids::TORCH) ->writeTorchFacing($block->getFacing()); diff --git a/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php b/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php index c7447bd53..c0807c8a6 100644 --- a/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php +++ b/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php @@ -50,7 +50,6 @@ use pocketmine\block\utils\ICopper; use pocketmine\block\utils\SlabType; use pocketmine\block\VanillaBlocks; use pocketmine\block\Wall; -use pocketmine\block\WallCoralFan; use pocketmine\block\WallSign; use pocketmine\block\WeightedPressurePlate; use pocketmine\block\Wood; @@ -58,7 +57,6 @@ use pocketmine\data\bedrock\block\BlockLegacyMetadata; use pocketmine\data\bedrock\block\BlockStateDeserializeException; use pocketmine\data\bedrock\block\BlockStateNames; use pocketmine\data\bedrock\block\BlockStateNames as StateNames; -use pocketmine\data\bedrock\block\BlockStateStringValues as StringValues; use pocketmine\data\bedrock\MushroomBlockTypeIdMap; use pocketmine\math\Axis; use pocketmine\math\Facing; @@ -286,13 +284,6 @@ final class BlockStateDeserializerHelper{ return $block; } - /** @throws BlockStateDeserializeException */ - public static function decodeWallCoralFan(WallCoralFan $block, BlockStateReader $in) : WallCoralFan{ - return $block - ->setDead($in->readBool(BlockStateNames::DEAD_BIT)) - ->setFacing($in->readCoralFacing()); - } - /** @throws BlockStateDeserializeException */ public static function decodeWallSign(WallSign $block, BlockStateReader $in) : WallSign{ return $block @@ -303,25 +294,4 @@ final class BlockStateDeserializerHelper{ return $block ->setOutputSignalStrength($in->readBoundedInt(BlockStateNames::REDSTONE_SIGNAL, 0, 15)); } - - /** @throws BlockStateDeserializeException */ - public static function mapLegacyWallType(BlockStateReader $in) : Wall{ - return self::decodeWall(match($type = $in->readString(BlockStateNames::WALL_BLOCK_TYPE)){ - StringValues::WALL_BLOCK_TYPE_ANDESITE => VanillaBlocks::ANDESITE_WALL(), - StringValues::WALL_BLOCK_TYPE_BRICK => VanillaBlocks::BRICK_WALL(), - StringValues::WALL_BLOCK_TYPE_COBBLESTONE => VanillaBlocks::COBBLESTONE_WALL(), - StringValues::WALL_BLOCK_TYPE_DIORITE => VanillaBlocks::DIORITE_WALL(), - StringValues::WALL_BLOCK_TYPE_END_BRICK => VanillaBlocks::END_STONE_BRICK_WALL(), - StringValues::WALL_BLOCK_TYPE_GRANITE => VanillaBlocks::GRANITE_WALL(), - StringValues::WALL_BLOCK_TYPE_MOSSY_COBBLESTONE => VanillaBlocks::MOSSY_COBBLESTONE_WALL(), - StringValues::WALL_BLOCK_TYPE_MOSSY_STONE_BRICK => VanillaBlocks::MOSSY_STONE_BRICK_WALL(), - StringValues::WALL_BLOCK_TYPE_NETHER_BRICK => VanillaBlocks::NETHER_BRICK_WALL(), - StringValues::WALL_BLOCK_TYPE_PRISMARINE => VanillaBlocks::PRISMARINE_WALL(), - StringValues::WALL_BLOCK_TYPE_RED_NETHER_BRICK => VanillaBlocks::RED_NETHER_BRICK_WALL(), - StringValues::WALL_BLOCK_TYPE_RED_SANDSTONE => VanillaBlocks::RED_SANDSTONE_WALL(), - StringValues::WALL_BLOCK_TYPE_SANDSTONE => VanillaBlocks::SANDSTONE_WALL(), - StringValues::WALL_BLOCK_TYPE_STONE_BRICK => VanillaBlocks::STONE_BRICK_WALL(), - default => throw $in->badValueException(BlockStateNames::WALL_BLOCK_TYPE, $type), - }, $in); - } } diff --git a/src/data/bedrock/block/convert/BlockStateSerializerHelper.php b/src/data/bedrock/block/convert/BlockStateSerializerHelper.php index 9dfb17ca0..3e2215746 100644 --- a/src/data/bedrock/block/convert/BlockStateSerializerHelper.php +++ b/src/data/bedrock/block/convert/BlockStateSerializerHelper.php @@ -68,9 +68,8 @@ final class BlockStateSerializerHelper{ ->writeInt(StateNames::CANDLES, $block->getCount() - 1); } - public static function encodeChemistryTable(ChemistryTable $block, string $chemistryTableType, Writer $out) : Writer{ + public static function encodeChemistryTable(ChemistryTable $block, Writer $out) : Writer{ return $out - ->writeString(BlockStateNames::CHEMISTRY_TABLE_TYPE, $chemistryTableType) ->writeLegacyHorizontalFacing(Facing::opposite($block->getFacing())); } @@ -78,9 +77,8 @@ final class BlockStateSerializerHelper{ return $out->writeInt(BlockStateNames::GROWTH, $block->getAge()); } - public static function encodeColoredTorch(Torch $block, bool $highBit, Writer $out) : Writer{ + public static function encodeTorch(Torch $block, Writer $out) : Writer{ return $out - ->writeBool(BlockStateNames::COLOR_BIT, $highBit) ->writeTorchFacing($block->getFacing()); } @@ -225,11 +223,6 @@ final class BlockStateSerializerHelper{ ->writeWallConnectionType(BlockStateNames::WALL_CONNECTION_TYPE_WEST, $block->getConnection(Facing::WEST)); } - public static function encodeLegacyWall(Wall $block, string $type) : Writer{ - return self::encodeWall($block, Writer::create(Ids::COBBLESTONE_WALL)) - ->writeString(BlockStateNames::WALL_BLOCK_TYPE, $type); - } - public static function encodeWallSign(WallSign $block, Writer $out) : Writer{ return $out ->writeHorizontalFacing($block->getFacing()); diff --git a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php index 2c2e75e99..49365799c 100644 --- a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php +++ b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php @@ -963,6 +963,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->mapSimple(Ids::SOUL_SAND, fn() => Blocks::SOUL_SAND()); $this->mapSimple(Ids::SOUL_SOIL, fn() => Blocks::SOUL_SOIL()); $this->mapSimple(Ids::SPORE_BLOSSOM, fn() => Blocks::SPORE_BLOSSOM()); + $this->mapSimple(Ids::SPONGE, fn() => Blocks::SPONGE()); $this->mapSimple(Ids::STONE, fn() => Blocks::STONE()); $this->mapSimple(Ids::STONECUTTER, fn() => Blocks::LEGACY_STONECUTTER()); $this->mapSimple(Ids::STONE_BRICKS, fn() => Blocks::STONE_BRICKS()); @@ -975,6 +976,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->mapSimple(Ids::WARPED_ROOTS, fn() => Blocks::WARPED_ROOTS()); $this->mapSimple(Ids::WATERLILY, fn() => Blocks::LILY_PAD()); $this->mapSimple(Ids::WEB, fn() => Blocks::COBWEB()); + $this->mapSimple(Ids::WET_SPONGE, fn() => Blocks::SPONGE()->setWet(true)); $this->mapSimple(Ids::WITHER_ROSE, fn() => Blocks::WITHER_ROSE()); $this->mapSimple(Ids::DANDELION, fn() => Blocks::DANDELION()); @@ -1004,6 +1006,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ }); $this->mapSlab(Ids::ANDESITE_SLAB, Ids::ANDESITE_DOUBLE_SLAB, fn() => Blocks::ANDESITE_SLAB()); $this->mapStairs(Ids::ANDESITE_STAIRS, fn() => Blocks::ANDESITE_STAIRS()); + $this->map(Ids::ANDESITE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::ANDESITE_WALL(), $in)); $this->map(Ids::ANVIL, function(Reader $in) : Block{ return Blocks::ANVIL() ->setDamage(Anvil::UNDAMAGED) @@ -1099,6 +1102,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ }); $this->mapSlab(Ids::BRICK_SLAB, Ids::BRICK_DOUBLE_SLAB, fn() => Blocks::BRICK_SLAB()); $this->mapStairs(Ids::BRICK_STAIRS, fn() => Blocks::BRICK_STAIRS()); + $this->map(Ids::BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::BRICK_WALL(), $in)); $this->map(Ids::BROWN_MUSHROOM_BLOCK, fn(Reader $in) => Helper::decodeMushroomBlock(Blocks::BROWN_MUSHROOM_BLOCK(), $in)); $this->map(Ids::CACTUS, function(Reader $in) : Block{ return Blocks::CACTUS() @@ -1156,15 +1160,6 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ return Blocks::CHISELED_QUARTZ() ->setAxis($in->readPillarAxis()); }); - $this->map(Ids::CHEMISTRY_TABLE, function(Reader $in) : Block{ - return (match($type = $in->readString(StateNames::CHEMISTRY_TABLE_TYPE)){ - StringValues::CHEMISTRY_TABLE_TYPE_COMPOUND_CREATOR => Blocks::COMPOUND_CREATOR(), - StringValues::CHEMISTRY_TABLE_TYPE_ELEMENT_CONSTRUCTOR => Blocks::ELEMENT_CONSTRUCTOR(), - StringValues::CHEMISTRY_TABLE_TYPE_LAB_TABLE => Blocks::LAB_TABLE(), - StringValues::CHEMISTRY_TABLE_TYPE_MATERIAL_REDUCER => Blocks::MATERIAL_REDUCER(), - default => throw $in->badValueException(StateNames::CHEMISTRY_TABLE_TYPE, $type), - })->setFacing(Facing::opposite($in->readLegacyHorizontalFacing())); - }); $this->map(Ids::CHEST, function(Reader $in) : Block{ return Blocks::CHEST() ->setFacing($in->readCardinalHorizontalFacing()); @@ -1178,22 +1173,19 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->mapStairs(Ids::COBBLED_DEEPSLATE_STAIRS, fn() => Blocks::COBBLED_DEEPSLATE_STAIRS()); $this->map(Ids::COBBLED_DEEPSLATE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::COBBLED_DEEPSLATE_WALL(), $in)); $this->mapSlab(Ids::COBBLESTONE_SLAB, Ids::COBBLESTONE_DOUBLE_SLAB, fn() => Blocks::COBBLESTONE_SLAB()); - $this->map(Ids::COBBLESTONE_WALL, fn(Reader $in) => Helper::mapLegacyWallType($in)); + $this->map(Ids::COBBLESTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::COBBLESTONE_WALL(), $in)); $this->map(Ids::COCOA, function(Reader $in) : Block{ return Blocks::COCOA_POD() ->setAge($in->readBoundedInt(StateNames::AGE, 0, 2)) ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing())); }); - $this->map(Ids::COLORED_TORCH_BP, function(Reader $in) : Block{ - return $in->readBool(StateNames::COLOR_BIT) ? - Blocks::PURPLE_TORCH()->setFacing($in->readTorchFacing()) : - Blocks::BLUE_TORCH()->setFacing($in->readTorchFacing()); - }); - $this->map(Ids::COLORED_TORCH_RG, function(Reader $in) : Block{ - return $in->readBool(StateNames::COLOR_BIT) ? - Blocks::GREEN_TORCH()->setFacing($in->readTorchFacing()) : - Blocks::RED_TORCH()->setFacing($in->readTorchFacing()); - }); + $this->map(Ids::COLORED_TORCH_BLUE, fn(Reader $in) => Blocks::BLUE_TORCH()->setFacing($in->readTorchFacing())); + $this->map(Ids::COLORED_TORCH_GREEN, fn(Reader $in) => Blocks::GREEN_TORCH()->setFacing($in->readTorchFacing())); + $this->map(Ids::COLORED_TORCH_PURPLE, fn(Reader $in) => Blocks::PURPLE_TORCH()->setFacing($in->readTorchFacing())); + $this->map(Ids::COLORED_TORCH_RED, fn(Reader $in) => Blocks::RED_TORCH()->setFacing($in->readTorchFacing())); + $this->map(Ids::COMPOUND_CREATOR, fn(Reader $in) => Blocks::COMPOUND_CREATOR() + ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing())) + ); $this->map(Ids::COPPER_BLOCK, fn() => Helper::decodeCopper(Blocks::COPPER(), CopperOxidation::NONE)); $this->map(Ids::CUT_COPPER, fn() => Helper::decodeCopper(Blocks::CUT_COPPER(), CopperOxidation::NONE)); $this->mapSlab(Ids::CUT_COPPER_SLAB, Ids::DOUBLE_CUT_COPPER_SLAB, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_SLAB(), CopperOxidation::NONE)); @@ -1224,6 +1216,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ }); $this->mapSlab(Ids::DIORITE_SLAB, Ids::DIORITE_DOUBLE_SLAB, fn() => Blocks::DIORITE_SLAB()); $this->mapStairs(Ids::DIORITE_STAIRS, fn() => Blocks::DIORITE_STAIRS()); + $this->map(Ids::DIORITE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::DIORITE_WALL(), $in)); $this->map(Ids::DIRT, fn() => Blocks::DIRT()->setDirtType(DirtType::NORMAL)); $this->map(Ids::DIRT_WITH_ROOTS, fn() => Blocks::DIRT()->setDirtType(DirtType::ROOTED)); $this->map(Ids::LARGE_FERN, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::LARGE_FERN(), $in)); @@ -1232,7 +1225,11 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->map(Ids::ROSE_BUSH, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::ROSE_BUSH(), $in)); $this->map(Ids::SUNFLOWER, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::SUNFLOWER(), $in)); $this->map(Ids::LILAC, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::LILAC(), $in)); + $this->map(Ids::ELEMENT_CONSTRUCTOR, fn(Reader $in) => Blocks::ELEMENT_CONSTRUCTOR() + ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing())) + ); $this->mapStairs(Ids::END_BRICK_STAIRS, fn() => Blocks::END_STONE_BRICK_STAIRS()); + $this->map(Ids::END_STONE_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::END_STONE_BRICK_WALL(), $in)); $this->map(Ids::END_PORTAL_FRAME, function(Reader $in) : Block{ return Blocks::END_PORTAL_FRAME() ->setEye($in->readBool(StateNames::END_PORTAL_EYE_BIT)) @@ -1284,6 +1281,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ }); $this->mapSlab(Ids::GRANITE_SLAB, Ids::GRANITE_DOUBLE_SLAB, fn() => Blocks::GRANITE_SLAB()); $this->mapStairs(Ids::GRANITE_STAIRS, fn() => Blocks::GRANITE_STAIRS()); + $this->map(Ids::GRANITE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::GRANITE_WALL(), $in)); $this->map(Ids::HAY_BLOCK, function(Reader $in) : Block{ $in->ignored(StateNames::DEPRECATED); return Blocks::HAY_BALE()->setAxis($in->readPillarAxis()); @@ -1296,6 +1294,9 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ }); $this->map(Ids::IRON_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::IRON_DOOR(), $in)); $this->map(Ids::IRON_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::IRON_TRAPDOOR(), $in)); + $this->map(Ids::LAB_TABLE, fn(Reader $in) => Blocks::LAB_TABLE() + ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing())) + ); $this->map(Ids::LADDER, function(Reader $in) : Block{ return Blocks::LADDER() ->setFacing($in->readHorizontalFacing()); @@ -1367,6 +1368,9 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ return Blocks::LOOM() ->setFacing($in->readLegacyHorizontalFacing()); }); + $this->map(Ids::MATERIAL_REDUCER, fn(Reader $in) => Blocks::MATERIAL_REDUCER() + ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing())) + ); $this->map(Ids::MEDIUM_AMETHYST_BUD, function(Reader $in) : Block{ return Blocks::AMETHYST_CLUSTER() ->setStage(AmethystCluster::STAGE_MEDIUM_BUD) @@ -1375,8 +1379,10 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->map(Ids::MELON_STEM, fn(Reader $in) => Helper::decodeStem(Blocks::MELON_STEM(), $in)); $this->mapSlab(Ids::MOSSY_COBBLESTONE_SLAB, Ids::MOSSY_COBBLESTONE_DOUBLE_SLAB, fn() => Blocks::MOSSY_COBBLESTONE_SLAB()); $this->mapStairs(Ids::MOSSY_COBBLESTONE_STAIRS, fn() => Blocks::MOSSY_COBBLESTONE_STAIRS()); + $this->map(Ids::MOSSY_COBBLESTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::MOSSY_COBBLESTONE_WALL(), $in)); $this->mapSlab(Ids::MOSSY_STONE_BRICK_SLAB, Ids::MOSSY_STONE_BRICK_DOUBLE_SLAB, fn() => Blocks::MOSSY_STONE_BRICK_SLAB()); $this->mapStairs(Ids::MOSSY_STONE_BRICK_STAIRS, fn() => Blocks::MOSSY_STONE_BRICK_STAIRS()); + $this->map(Ids::MOSSY_STONE_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::MOSSY_STONE_BRICK_WALL(), $in)); $this->mapSlab(Ids::MUD_BRICK_SLAB, Ids::MUD_BRICK_DOUBLE_SLAB, fn() => Blocks::MUD_BRICK_SLAB()); $this->mapStairs(Ids::MUD_BRICK_STAIRS, fn() => Blocks::MUD_BRICK_STAIRS()); $this->map(Ids::MUD_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::MUD_BRICK_WALL(), $in)); @@ -1386,6 +1392,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ }); $this->mapSlab(Ids::NETHER_BRICK_SLAB, Ids::NETHER_BRICK_DOUBLE_SLAB, fn() => Blocks::NETHER_BRICK_SLAB()); $this->mapStairs(Ids::NETHER_BRICK_STAIRS, fn() => Blocks::NETHER_BRICK_STAIRS()); + $this->map(Ids::NETHER_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::NETHER_BRICK_WALL(), $in)); $this->map(Ids::NETHER_WART, function(Reader $in) : Block{ return Blocks::NETHER_WART() ->setAge($in->readBoundedInt(StateNames::AGE, 0, 3)); @@ -1461,6 +1468,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ ->setPowered(true)); $this->mapSlab(Ids::PRISMARINE_BRICK_SLAB, Ids::PRISMARINE_BRICK_DOUBLE_SLAB, fn() => Blocks::PRISMARINE_BRICKS_SLAB()); $this->mapStairs(Ids::PRISMARINE_BRICKS_STAIRS, fn() => Blocks::PRISMARINE_BRICKS_STAIRS()); + $this->map(Ids::PRISMARINE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::PRISMARINE_WALL(), $in)); $this->mapSlab(Ids::PRISMARINE_SLAB, Ids::PRISMARINE_DOUBLE_SLAB, fn() => Blocks::PRISMARINE_SLAB()); $this->mapStairs(Ids::PRISMARINE_STAIRS, fn() => Blocks::PRISMARINE_STAIRS()); $this->map(Ids::PUMPKIN, function(Reader $in) : Block{ @@ -1469,19 +1477,10 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ }); $this->map(Ids::PUMPKIN_STEM, fn(Reader $in) => Helper::decodeStem(Blocks::PUMPKIN_STEM(), $in)); $this->map(Ids::PURPUR_BLOCK, function(Reader $in) : Block{ - $type = $in->readString(StateNames::CHISEL_TYPE); - if($type === StringValues::CHISEL_TYPE_LINES){ - return Blocks::PURPUR_PILLAR()->setAxis($in->readPillarAxis()); - }else{ - $in->ignored(StateNames::PILLAR_AXIS); //axis only applies to pillars - return match($type){ - StringValues::CHISEL_TYPE_CHISELED, //TODO: bug in MCPE - StringValues::CHISEL_TYPE_SMOOTH, //TODO: bug in MCPE - StringValues::CHISEL_TYPE_DEFAULT => Blocks::PURPUR(), - default => throw $in->badValueException(StateNames::CHISEL_TYPE, $type), - }; - } + $in->ignored(StateNames::PILLAR_AXIS); //??? + return Blocks::PURPUR(); }); + $this->map(Ids::PURPUR_PILLAR, fn(Reader $in) => Blocks::PURPUR_PILLAR()->setAxis($in->readPillarAxis())); $this->mapSlab(Ids::PURPUR_SLAB, Ids::PURPUR_DOUBLE_SLAB, fn() => Blocks::PURPUR_SLAB()); $this->mapStairs(Ids::PURPUR_STAIRS, fn() => Blocks::PURPUR_STAIRS()); $this->map(Ids::QUARTZ_BLOCK, function(Reader $in) : Opaque{ @@ -1501,8 +1500,10 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->map(Ids::RED_MUSHROOM_BLOCK, fn(Reader $in) => Helper::decodeMushroomBlock(Blocks::RED_MUSHROOM_BLOCK(), $in)); $this->mapSlab(Ids::RED_NETHER_BRICK_SLAB, Ids::RED_NETHER_BRICK_DOUBLE_SLAB, fn() => Blocks::RED_NETHER_BRICK_SLAB()); $this->mapStairs(Ids::RED_NETHER_BRICK_STAIRS, fn() => Blocks::RED_NETHER_BRICK_STAIRS()); + $this->map(Ids::RED_NETHER_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::RED_NETHER_BRICK_WALL(), $in)); $this->mapSlab(Ids::RED_SANDSTONE_SLAB, Ids::RED_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::RED_SANDSTONE_SLAB()); $this->mapStairs(Ids::RED_SANDSTONE_STAIRS, fn() => Blocks::RED_SANDSTONE_STAIRS()); + $this->map(Ids::RED_SANDSTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::RED_SANDSTONE_WALL(), $in)); $this->map(Ids::REDSTONE_LAMP, function() : Block{ return Blocks::REDSTONE_LAMP() ->setPowered(false); @@ -1526,6 +1527,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ }); $this->mapSlab(Ids::SANDSTONE_SLAB, Ids::SANDSTONE_DOUBLE_SLAB, fn() => Blocks::SANDSTONE_SLAB()); $this->mapStairs(Ids::SANDSTONE_STAIRS, fn() => Blocks::SANDSTONE_STAIRS()); + $this->map(Ids::SANDSTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::SANDSTONE_WALL(), $in)); $this->map(Ids::SEA_PICKLE, function(Reader $in) : Block{ return Blocks::SEA_PICKLE() ->setCount($in->readBoundedInt(StateNames::CLUSTER_COUNT, 0, 3) + 1) @@ -1582,19 +1584,13 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ return Blocks::SOUL_TORCH() ->setFacing($in->readTorchFacing()); }); - $this->map(Ids::SPONGE, function(Reader $in) : Block{ - return Blocks::SPONGE()->setWet(match($type = $in->readString(StateNames::SPONGE_TYPE)){ - StringValues::SPONGE_TYPE_DRY => false, - StringValues::SPONGE_TYPE_WET => true, - default => throw $in->badValueException(StateNames::SPONGE_TYPE, $type), - }); - }); $this->map(Ids::STANDING_BANNER, function(Reader $in) : Block{ return Blocks::BANNER() ->setRotation($in->readBoundedInt(StateNames::GROUND_SIGN_DIRECTION, 0, 15)); }); $this->mapSlab(Ids::STONE_BRICK_SLAB, Ids::STONE_BRICK_DOUBLE_SLAB, fn() => Blocks::STONE_BRICK_SLAB()); $this->mapStairs(Ids::STONE_BRICK_STAIRS, fn() => Blocks::STONE_BRICK_STAIRS()); + $this->map(Ids::STONE_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::STONE_BRICK_WALL(), $in)); $this->map(Ids::STONE_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::STONE_BUTTON(), $in)); $this->map(Ids::STONE_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::STONE_PRESSURE_PLATE(), $in)); $this->mapStairs(Ids::STONE_STAIRS, fn() => Blocks::COBBLESTONE_STAIRS()); @@ -1611,7 +1607,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->map(Ids::TNT, function(Reader $in) : Block{ return Blocks::TNT() ->setUnstable($in->readBool(StateNames::EXPLODE_BIT)) - ->setWorksUnderwater($in->readBool(StateNames::ALLOW_UNDERWATER_BIT)); + ->setWorksUnderwater(false); }); $this->map(Ids::TORCH, function(Reader $in) : Block{ return Blocks::TORCH() @@ -1649,6 +1645,11 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ return Blocks::TWISTING_VINES() ->setAge($in->readBoundedInt(StateNames::TWISTING_VINES_AGE, 0, 25)); }); + $this->map(Ids::UNDERWATER_TNT, function(Reader $in) : Block{ + return Blocks::TNT() + ->setUnstable($in->readBool(StateNames::EXPLODE_BIT)) + ->setWorksUnderwater(true); + }); $this->map(Ids::UNDERWATER_TORCH, function(Reader $in) : Block{ return Blocks::UNDERWATER_TORCH() ->setFacing($in->readTorchFacing()); diff --git a/src/data/bedrock/item/ItemTypeNames.php b/src/data/bedrock/item/ItemTypeNames.php index db6594c43..06ae28cec 100644 --- a/src/data/bedrock/item/ItemTypeNames.php +++ b/src/data/bedrock/item/ItemTypeNames.php @@ -109,6 +109,7 @@ final class ItemTypeNames{ public const CHAINMAIL_HELMET = "minecraft:chainmail_helmet"; public const CHAINMAIL_LEGGINGS = "minecraft:chainmail_leggings"; public const CHARCOAL = "minecraft:charcoal"; + public const CHEMISTRY_TABLE = "minecraft:chemistry_table"; public const CHERRY_BOAT = "minecraft:cherry_boat"; public const CHERRY_CHEST_BOAT = "minecraft:cherry_chest_boat"; public const CHERRY_DOOR = "minecraft:cherry_door"; @@ -127,6 +128,8 @@ final class ItemTypeNames{ public const COD = "minecraft:cod"; public const COD_BUCKET = "minecraft:cod_bucket"; public const COD_SPAWN_EGG = "minecraft:cod_spawn_egg"; + public const COLORED_TORCH_BP = "minecraft:colored_torch_bp"; + public const COLORED_TORCH_RG = "minecraft:colored_torch_rg"; public const COMMAND_BLOCK_MINECART = "minecraft:command_block_minecart"; public const COMPARATOR = "minecraft:comparator"; public const COMPASS = "minecraft:compass"; diff --git a/src/inventory/ArmorInventory.php b/src/inventory/ArmorInventory.php index dcb3c04cb..0b3ae5b7b 100644 --- a/src/inventory/ArmorInventory.php +++ b/src/inventory/ArmorInventory.php @@ -23,8 +23,13 @@ declare(strict_types=1); namespace pocketmine\inventory; +use pocketmine\block\BlockTypeIds; use pocketmine\entity\Living; +use pocketmine\inventory\transaction\action\validator\CallbackSlotValidator; +use pocketmine\inventory\transaction\TransactionValidationException; +use pocketmine\item\Armor; use pocketmine\item\Item; +use pocketmine\item\ItemBlock; class ArmorInventory extends SimpleInventory{ public const SLOT_HEAD = 0; @@ -36,6 +41,8 @@ class ArmorInventory extends SimpleInventory{ protected Living $holder ){ parent::__construct(4); + + $this->validators->add(new CallbackSlotValidator($this->validate(...))); } public function getHolder() : Living{ @@ -73,4 +80,20 @@ class ArmorInventory extends SimpleInventory{ public function setBoots(Item $boots) : void{ $this->setItem(self::SLOT_FEET, $boots); } + + private function validate(Inventory $inventory, Item $item, int $slot) : ?TransactionValidationException{ + if($item instanceof Armor){ + if($item->getArmorSlot() !== $slot){ + return new TransactionValidationException("Armor item is in wrong slot"); + } + }else{ + if(!($slot === ArmorInventory::SLOT_HEAD && $item instanceof ItemBlock && ( + $item->getBlock()->getTypeId() === BlockTypeIds::CARVED_PUMPKIN || + $item->getBlock()->getTypeId() === BlockTypeIds::MOB_HEAD + ))){ + return new TransactionValidationException("Item is not accepted in an armor slot"); + } + } + return null; + } } diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 254e44b1e..522c827a4 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -36,8 +36,10 @@ use function spl_object_id; /** * This class provides everything needed to implement an inventory, minus the underlying storage system. + * + * @phpstan-import-type SlotValidators from SlotValidatedInventory */ -abstract class BaseInventory implements Inventory{ +abstract class BaseInventory implements Inventory, SlotValidatedInventory{ protected int $maxStackSize = Inventory::MAX_STACK; /** @var Player[] */ protected array $viewers = []; @@ -46,9 +48,12 @@ abstract class BaseInventory implements Inventory{ * @phpstan-var ObjectSet */ protected ObjectSet $listeners; + /** @phpstan-var SlotValidators */ + protected ObjectSet $validators; public function __construct(){ $this->listeners = new ObjectSet(); + $this->validators = new ObjectSet(); } public function getMaxStackSize() : int{ @@ -398,4 +403,8 @@ abstract class BaseInventory implements Inventory{ public function getListeners() : ObjectSet{ return $this->listeners; } + + public function getSlotValidators() : ObjectSet{ + return $this->validators; + } } diff --git a/src/inventory/SlotValidatedInventory.php b/src/inventory/SlotValidatedInventory.php new file mode 100644 index 000000000..f30ebf8a0 --- /dev/null +++ b/src/inventory/SlotValidatedInventory.php @@ -0,0 +1,46 @@ + + */ +interface SlotValidatedInventory{ + /** + * Returns a set of validators that will be used to determine whether an item can be placed in a particular slot. + * All validators need to return null for the transaction to be allowed. + * If one of the validators returns an exception, the transaction will be cancelled. + * + * There is no guarantee that the validators will be called in any particular order. + * + * @phpstan-return SlotValidators + */ + public function getSlotValidators() : ObjectSet; +} diff --git a/src/inventory/transaction/action/SlotChangeAction.php b/src/inventory/transaction/action/SlotChangeAction.php index 453f0c4d2..68c3dba1b 100644 --- a/src/inventory/transaction/action/SlotChangeAction.php +++ b/src/inventory/transaction/action/SlotChangeAction.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; use pocketmine\inventory\Inventory; +use pocketmine\inventory\SlotValidatedInventory; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; @@ -74,6 +75,14 @@ class SlotChangeAction extends InventoryAction{ if($this->targetItem->getCount() > $this->inventory->getMaxStackSize()){ throw new TransactionValidationException("Target item exceeds inventory max stack size"); } + if($this->inventory instanceof SlotValidatedInventory && !$this->targetItem->isNull()){ + foreach($this->inventory->getSlotValidators() as $validator){ + $ret = $validator->validate($this->inventory, $this->targetItem, $this->inventorySlot); + if($ret !== null){ + throw new TransactionValidationException("Target item is not accepted by the inventory at slot #" . $this->inventorySlot . ": " . $ret->getMessage(), 0, $ret); + } + } + } } /** diff --git a/src/inventory/transaction/action/validator/CallbackSlotValidator.php b/src/inventory/transaction/action/validator/CallbackSlotValidator.php new file mode 100644 index 000000000..1670dc623 --- /dev/null +++ b/src/inventory/transaction/action/validator/CallbackSlotValidator.php @@ -0,0 +1,44 @@ +validate)($inventory, $item, $slot); + } +} diff --git a/src/inventory/transaction/action/validator/SlotValidator.php b/src/inventory/transaction/action/validator/SlotValidator.php new file mode 100644 index 000000000..1b78c91f7 --- /dev/null +++ b/src/inventory/transaction/action/validator/SlotValidator.php @@ -0,0 +1,38 @@ +session->sendDataPacket(InventorySlotPacket::create( $windowId, $netSlot, - new ItemStackWrapper(0, ItemStack::null()), - 0 + new FullContainerName($this->lastInventoryNetworkId), + 0, + new ItemStackWrapper(0, ItemStack::null()) )); } //now send the real contents $this->session->sendDataPacket(InventorySlotPacket::create( $windowId, $netSlot, - $itemStackWrapper, - 0 + new FullContainerName($this->lastInventoryNetworkId), + 0, + $itemStackWrapper )); } @@ -528,10 +531,11 @@ class InventoryManager{ $this->session->sendDataPacket(InventoryContentPacket::create( $windowId, array_fill_keys(array_keys($itemStackWrappers), new ItemStackWrapper(0, ItemStack::null())), + new FullContainerName($this->lastInventoryNetworkId), 0 )); //now send the real contents - $this->session->sendDataPacket(InventoryContentPacket::create($windowId, $itemStackWrappers, 0)); + $this->session->sendDataPacket(InventoryContentPacket::create($windowId, $itemStackWrappers, new FullContainerName($this->lastInventoryNetworkId), 0)); } public function syncSlot(Inventory $inventory, int $slot, ItemStack $itemStack) : void{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 33a9303a3..2dce5bbb8 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -787,7 +787,7 @@ class NetworkSession{ public function transfer(string $ip, int $port, Translatable|string|null $reason = null) : void{ $reason ??= KnownTranslationFactory::pocketmine_disconnect_transfer(); $this->tryDisconnect(function() use ($ip, $port, $reason) : void{ - $this->sendDataPacket(TransferPacket::create($ip, $port), true); + $this->sendDataPacket(TransferPacket::create($ip, $port, false), true); if($this->player !== null){ $this->player->onPostDisconnect($reason, null); } diff --git a/src/network/mcpe/StandardEntityEventBroadcaster.php b/src/network/mcpe/StandardEntityEventBroadcaster.php index e2a707a3d..3e2df3994 100644 --- a/src/network/mcpe/StandardEntityEventBroadcaster.php +++ b/src/network/mcpe/StandardEntityEventBroadcaster.php @@ -38,8 +38,8 @@ use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; use pocketmine\network\mcpe\protocol\SetActorDataPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; -use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute; use pocketmine\network\mcpe\protocol\types\entity\PropertySyncData; +use pocketmine\network\mcpe\protocol\types\entity\UpdateAttribute; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; @@ -67,7 +67,7 @@ final class StandardEntityEventBroadcaster implements EntityEventBroadcaster{ if(count($attributes) > 0){ $this->sendDataPacket($recipients, UpdateAttributesPacket::create( $entity->getId(), - array_map(fn(Attribute $attr) => new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue(), []), $attributes), + array_map(fn(Attribute $attr) => new UpdateAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getDefaultValue(), []), $attributes), 0 )); } @@ -142,6 +142,13 @@ final class StandardEntityEventBroadcaster implements EntityEventBroadcaster{ } public function onEmote(array $recipients, Human $from, string $emoteId) : void{ - $this->sendDataPacket($recipients, EmotePacket::create($from->getId(), $emoteId, "", "", EmotePacket::FLAG_SERVER | EmotePacket::FLAG_MUTE_ANNOUNCEMENT)); + $this->sendDataPacket($recipients, EmotePacket::create( + $from->getId(), + $emoteId, + 0, //seems to be irrelevant for the client, we cannot risk rebroadcasting random values received + "", + "", + EmotePacket::FLAG_SERVER | EmotePacket::FLAG_MUTE_ANNOUNCEMENT + )); } } diff --git a/src/network/mcpe/handler/ItemStackRequestExecutor.php b/src/network/mcpe/handler/ItemStackRequestExecutor.php index a1d5e4812..54a192590 100644 --- a/src/network/mcpe/handler/ItemStackRequestExecutor.php +++ b/src/network/mcpe/handler/ItemStackRequestExecutor.php @@ -343,7 +343,7 @@ class ItemStackRequestExecutor{ $this->setNextCreatedItem($window->getOutput($optionId)); } }else{ - $this->beginCrafting($action->getRecipeId(), 1); + $this->beginCrafting($action->getRecipeId(), $action->getRepetitions()); } }elseif($action instanceof CraftRecipeAutoStackRequestAction){ $this->beginCrafting($action->getRecipeId(), $action->getRepetitions()); diff --git a/src/network/mcpe/handler/ItemStackResponseBuilder.php b/src/network/mcpe/handler/ItemStackResponseBuilder.php index a947eae72..1369e3ba7 100644 --- a/src/network/mcpe/handler/ItemStackResponseBuilder.php +++ b/src/network/mcpe/handler/ItemStackResponseBuilder.php @@ -100,7 +100,7 @@ final class ItemStackResponseBuilder{ $responseContainerInfos = []; foreach($responseInfosByContainer as $containerInterfaceId => $responseInfos){ - $responseContainerInfos[] = new ItemStackResponseContainerInfo(new FullContainerName($containerInterfaceId, 0), $responseInfos); + $responseContainerInfos[] = new ItemStackResponseContainerInfo(new FullContainerName($containerInterfaceId), $responseInfos); } return new ItemStackResponse(ItemStackResponse::RESULT_OK, $this->requestId, $responseContainerInfos); diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index b99775886..5f7fb0e4b 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -115,11 +115,9 @@ class ResourcePacksPacketHandler extends PacketHandler{ //TODO: support forcing server packs $this->session->sendDataPacket(ResourcePacksInfoPacket::create( resourcePackEntries: $resourcePackEntries, - behaviorPackEntries: [], mustAccept: $this->mustAccept, hasAddons: false, hasScripts: false, - forceServerPacks: false, cdnUrls: [] )); $this->session->getLogger()->debug("Waiting for client to accept resource packs"); diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 709dadf97..1612e7d84 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -51,12 +51,12 @@ use function time; class BedrockWorldData extends BaseNbtWorldData{ public const CURRENT_STORAGE_VERSION = 10; - public const CURRENT_STORAGE_NETWORK_VERSION = 712; + public const CURRENT_STORAGE_NETWORK_VERSION = 729; public const CURRENT_CLIENT_VERSION_TARGET = [ 1, //major 21, //minor - 20, //patch - 0, //revision + 30, //patch + 3, //revision 0 //is beta ]; diff --git a/start.sh b/start.sh index 0121f3887..4d4787114 100755 --- a/start.sh +++ b/start.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash DIR="$(cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" -cd "$DIR" +cd "$DIR" || { echo "Couldn't change directory to $DIR"; exit 1; } while getopts "p:f:l" OPTION 2> /dev/null; do case ${OPTION} in diff --git a/tests/travis.sh b/tests/travis.sh index 467db5e62..1ad9fb6a8 100755 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -7,6 +7,9 @@ while getopts "t:" OPTION 2> /dev/null; do t) PM_WORKERS="$OPTARG" ;; + \?) + break + ;; esac done @@ -42,7 +45,7 @@ if [ "$result" != "" ]; then echo "$result" echo Some tests did not complete successfully, changing build status to failed exit 1 -elif [ $(grep -c "ERROR\|CRITICAL\|EMERGENCY" "$DATA_DIR/server.log") -ne 0 ]; then +elif [ "$(grep -c "ERROR\|CRITICAL\|EMERGENCY" "$DATA_DIR/server.log")" -ne 0 ]; then echo Server log contains error messages, changing build status to failed exit 1 else