From 371eccd0079a1916c3c0802390920cd878631553 Mon Sep 17 00:00:00 2001 From: Max <43801744+ItsMax123@users.noreply.github.com> Date: Tue, 7 May 2024 07:02:50 -0400 Subject: [PATCH 01/37] Make access modifier consistent with parent abstract class (#6341) --- src/item/VanillaItems.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index bbd0dfc01..5115ee48a 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -591,12 +591,12 @@ final class VanillaItems{ } }); self::register("squid_spawn_egg", new class(new IID(Ids::SQUID_SPAWN_EGG), "Squid Spawn Egg") extends SpawnEgg{ - public function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ + protected function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ return new Squid(Location::fromObject($pos, $world, $yaw, $pitch)); } }); self::register("villager_spawn_egg", new class(new IID(Ids::VILLAGER_SPAWN_EGG), "Villager Spawn Egg") extends SpawnEgg{ - public function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ + protected function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ return new Villager(Location::fromObject($pos, $world, $yaw, $pitch)); } }); From 1b082f99e944e35f37ff9fde214ecbdb9b7187e8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 May 2024 12:34:42 +0100 Subject: [PATCH 02/37] DefaultPermissions: fixed typo --- src/permission/DefaultPermissions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 4af3d1b09..c72765af6 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -83,7 +83,7 @@ abstract class DefaultPermissions{ self::registerPermission(new Permission(Names::COMMAND_PLUGINS, l10n::pocketmine_permission_command_plugins()), [$operatorRoot]); self::registerPermission(new Permission(Names::COMMAND_SAVE_DISABLE, l10n::pocketmine_permission_command_save_disable()), [$operatorRoot]); self::registerPermission(new Permission(Names::COMMAND_SAVE_ENABLE, l10n::pocketmine_permission_command_save_enable()), [$operatorRoot]); - self::registerPermission(new Permission(Names::COMMAND_SAVE_PERFORM, l10n::pocketmine_permission_command_save_enable()), [$operatorRoot]); + self::registerPermission(new Permission(Names::COMMAND_SAVE_PERFORM, l10n::pocketmine_permission_command_save_perform()), [$operatorRoot]); self::registerPermission(new Permission(Names::COMMAND_SAY, l10n::pocketmine_permission_command_say()), [$operatorRoot]); self::registerPermission(new Permission(Names::COMMAND_SEED, l10n::pocketmine_permission_command_seed()), [$operatorRoot]); self::registerPermission(new Permission(Names::COMMAND_SETWORLDSPAWN, l10n::pocketmine_permission_command_setworldspawn()), [$operatorRoot]); From 5ef247620a7c6301a849b54e5ef1009217729fc8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 May 2024 12:46:31 +0100 Subject: [PATCH 03/37] Attach permission doc to every release --- .github/workflows/draft-release.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index e0eae836d..d8a972585 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -76,6 +76,9 @@ jobs: ${{ steps.php-binary-url.outputs.PHP_BINARY_URL }} \ > build_info.json + - name: Generate core permission doc for doc.pmmp.io + run: php tools/generate-permission-doc.php rst + - name: Upload release artifacts uses: actions/upload-artifact@v4 with: @@ -84,6 +87,7 @@ jobs: ${{ github.workspace }}/PocketMine-MP.phar ${{ github.workspace }}/start.* ${{ github.workspace }}/build_info.json + ${{ github.workspace }}/core-permissions.rst - name: Create draft release uses: ncipollo/release-action@v1.14.0 From f772bb738433b15d70cf5515314bab973a419991 Mon Sep 17 00:00:00 2001 From: Hugo_ <55756021+Dhaiven@users.noreply.github.com> Date: Mon, 13 May 2024 10:34:18 +0200 Subject: [PATCH 04/37] WoodenStairs can be a fuel (#6345) --- src/block/WoodenStairs.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/block/WoodenStairs.php b/src/block/WoodenStairs.php index 30fa7e602..0d9ba62ce 100644 --- a/src/block/WoodenStairs.php +++ b/src/block/WoodenStairs.php @@ -28,6 +28,10 @@ use pocketmine\block\utils\WoodTypeTrait; class WoodenStairs extends Stair{ use WoodTypeTrait; + public function getFuelTime() : int{ + return $this->woodType->isFlammable() ? 300 : 0; + } + public function getFlameEncouragement() : int{ return 5; } From 373dd9938ca2f16f809a11684d9a185ee915a528 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 May 2024 11:36:56 +0100 Subject: [PATCH 05/37] Update composer dependencies --- composer.lock | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/composer.lock b/composer.lock index b4d012ce4..22fdd9305 100644 --- a/composer.lock +++ b/composer.lock @@ -67,25 +67,25 @@ }, { "name": "brick/math", - "version": "0.11.0", + "version": "0.12.1", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478" + "reference": "f510c0a40911935b77b86859eb5223d58d660df1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478", - "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478", + "url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1", + "reference": "f510c0a40911935b77b86859eb5223d58d660df1", "shasum": "" }, "require": { - "php": "^8.0" + "php": "^8.1" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^9.0", - "vimeo/psalm": "5.0.0" + "phpunit/phpunit": "^10.1", + "vimeo/psalm": "5.16.0" }, "type": "library", "autoload": { @@ -105,12 +105,17 @@ "arithmetic", "bigdecimal", "bignum", + "bignumber", "brick", - "math" + "decimal", + "integer", + "math", + "mathematics", + "rational" ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.11.0" + "source": "https://github.com/brick/math/tree/0.12.1" }, "funding": [ { @@ -118,7 +123,7 @@ "type": "github" } ], - "time": "2023-01-15T23:15:59+00:00" + "time": "2023-11-29T23:19:16+00:00" }, { "name": "pocketmine/bedrock-block-upgrade-schema", @@ -829,20 +834,20 @@ }, { "name": "ramsey/uuid", - "version": "4.7.5", + "version": "4.7.6", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e" + "reference": "91039bc1faa45ba123c4328958e620d382ec7088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", - "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", + "reference": "91039bc1faa45ba123c4328958e620d382ec7088", "shasum": "" }, "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", "ext-json": "*", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" @@ -905,7 +910,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.7.5" + "source": "https://github.com/ramsey/uuid/tree/4.7.6" }, "funding": [ { @@ -917,7 +922,7 @@ "type": "tidelift" } ], - "time": "2023-11-08T05:53:05+00:00" + "time": "2024-04-27T21:32:50+00:00" }, { "name": "symfony/filesystem", From 554775841e1944eec3d3baa8808729522e74cbb7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 May 2024 11:48:23 +0100 Subject: [PATCH 06/37] Added script for linking local versions of Bedrock* deps for testing --- install-local-protocol.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 install-local-protocol.sh diff --git a/install-local-protocol.sh b/install-local-protocol.sh new file mode 100644 index 000000000..0f25a0390 --- /dev/null +++ b/install-local-protocol.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +echo "--- Installing BedrockProtocol, BedrockData, BedrockBlockUpgradeSchema, BedrockItemUpgradeSchema dependencies from local repositories." +echo "--- This allows you to perform integration tests using PocketMine-MP, without immediately publishing new versions of these libraries." + +cp composer.json composer-local-protocol.json +cp composer.lock composer-local-protocol.lock + +export COMPOSER=composer-local-protocol.json +composer config repositories.bedrock-protocol path ../deps/BedrockProtocol +composer config repositories.bedrock-data path ../deps/BedrockData +composer config repositories.bedrock-block-upgrade-schema path ../deps/BedrockBlockUpgradeSchema +composer config repositories.bedrock-item-upgrade-schema path ../deps/BedrockItemUpgradeSchema + +composer require pocketmine/bedrock-protocol:*@dev pocketmine/bedrock-data:*@dev pocketmine/bedrock-block-upgrade-schema:*@dev pocketmine/bedrock-item-upgrade-schema:*@dev + +composer install + +echo "--- Local dependencies have been successfully installed." +echo "--- This script does not modify composer.json. To go back to the original dependency versions, simply run 'composer install'." + From fb9a74e8799c71ed8292cfa53abe7a4c9204629d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 May 2024 11:52:31 +0100 Subject: [PATCH 07/37] gitignore files generated by install-local-protocol.sh --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 13c347376..6456250a6 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,6 @@ Documentation/* # php-cs-fixer /.php_cs.cache /.php-cs-fixer.cache + +# install-local-protocol.sh +/composer-local-protocol.* From 4c418b43182c9c0120238d739fbade3b91060737 Mon Sep 17 00:00:00 2001 From: Vega Nicholas S <142091702+nicholass003@users.noreply.github.com> Date: Fri, 31 May 2024 22:54:50 +0700 Subject: [PATCH 08/37] Remove unnecessary return statement (#6350) --- .../bedrock/block/convert/BlockStateToObjectDeserializer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php index 7220c0f8b..6b0c720f7 100644 --- a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php +++ b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php @@ -1437,7 +1437,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $in->ignored(StateNames::PILLAR_AXIS); return Blocks::SMOOTH_QUARTZ(); default: - return throw $in->badValueException(StateNames::CHISEL_TYPE, $type); + throw $in->badValueException(StateNames::CHISEL_TYPE, $type); } }); $this->mapStairs(Ids::QUARTZ_STAIRS, fn() => Blocks::QUARTZ_STAIRS()); From 08c6e63aac45a450fe3b437616ee8aa2500e04e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 May 2024 17:01:51 +0100 Subject: [PATCH 09/37] Bump phpstan/phpstan from 1.10.67 to 1.11.2 (#6352) Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 1.10.67 to 1.11.2. - [Release notes](https://github.com/phpstan/phpstan/releases) - [Changelog](https://github.com/phpstan/phpstan/blob/1.11.x/CHANGELOG.md) - [Commits](https://github.com/phpstan/phpstan/compare/1.10.67...1.11.2) --- updated-dependencies: - dependency-name: phpstan/phpstan dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 14be6f0d2..74bf14585 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "symfony/filesystem": "~6.4.0" }, "require-dev": { - "phpstan/phpstan": "1.10.67", + "phpstan/phpstan": "1.11.2", "phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-strict-rules": "^1.2.0", "phpunit/phpunit": "~10.3.0 || ~10.2.0 || ~10.1.0" diff --git a/composer.lock b/composer.lock index 22fdd9305..2e9138219 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": "99069514f4fb8ee6b03b0da07a77a486", + "content-hash": "833c1bb38c1ceaf36938a4d9fd0b7978", "packages": [ { "name": "adhocore/json-comment", @@ -1447,16 +1447,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.67", + "version": "1.11.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "16ddbe776f10da6a95ebd25de7c1dbed397dc493" + "reference": "0d5d4294a70deb7547db655c47685d680e39cfec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/16ddbe776f10da6a95ebd25de7c1dbed397dc493", - "reference": "16ddbe776f10da6a95ebd25de7c1dbed397dc493", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d5d4294a70deb7547db655c47685d680e39cfec", + "reference": "0d5d4294a70deb7547db655c47685d680e39cfec", "shasum": "" }, "require": { @@ -1501,7 +1501,7 @@ "type": "github" } ], - "time": "2024-04-16T07:22:02+00:00" + "time": "2024-05-24T13:23:04+00:00" }, { "name": "phpstan/phpstan-phpunit", From f121654452e21fb8ccba872ffbf805f607b5425d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2024 18:41:41 +0100 Subject: [PATCH 10/37] Assemble 1.21.0 --- composer.json | 8 +-- composer.lock | 52 +++++++-------- .../CraftingManagerFromDataHelper.php | 2 + src/crafting/json/ShapedRecipeData.php | 23 ++++++- src/crafting/json/ShapelessRecipeData.php | 23 ++++++- src/data/bedrock/block/BlockStateData.php | 4 +- src/data/bedrock/block/BlockStateNames.php | 4 +- .../bedrock/block/BlockStateStringValues.php | 18 ------ src/data/bedrock/block/BlockTypeNames.php | 30 +++++++-- .../convert/BlockObjectToStateSerializer.php | 49 ++++++++------- .../convert/BlockStateDeserializerHelper.php | 19 ++++++ .../block/convert/BlockStateReader.php | 13 ---- .../convert/BlockStateSerializerHelper.php | 31 ++++++--- .../BlockStateToObjectDeserializer.php | 63 ++++++++++--------- .../block/convert/BlockStateWriter.php | 13 ---- src/data/bedrock/item/ItemTypeNames.php | 9 +++ src/network/mcpe/InventoryManager.php | 14 ++++- src/network/mcpe/cache/CraftingDataCache.php | 4 ++ src/world/format/io/data/BedrockWorldData.php | 8 +-- .../data/bedrock/block/BlockStateDataTest.php | 14 ++++- tools/generate-bedrock-data-from-packets.php | 10 ++- 21 files changed, 251 insertions(+), 160 deletions(-) diff --git a/composer.json b/composer.json index 74bf14585..f14070552 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.1.0+bedrock-1.20.80", - "pocketmine/bedrock-data": "~2.10.0+bedrock-1.20.80", - "pocketmine/bedrock-item-upgrade-schema": "~1.9.0+bedrock-1.20.80", - "pocketmine/bedrock-protocol": "~30.0.0+bedrock-1.20.80", + "pocketmine/bedrock-block-upgrade-schema": "~4.2.0+bedrock-1.21.0", + "pocketmine/bedrock-data": "~2.11.0+bedrock-1.21.0", + "pocketmine/bedrock-item-upgrade-schema": "~1.10.0+bedrock-1.21.0", + "pocketmine/bedrock-protocol": "~31.0.0+bedrock-1.21.0", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/color": "^0.3.0", diff --git a/composer.lock b/composer.lock index 2e9138219..b2f82093b 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": "833c1bb38c1ceaf36938a4d9fd0b7978", + "content-hash": "941b6d463cb044438aa7908b76f7a6bb", "packages": [ { "name": "adhocore/json-comment", @@ -127,16 +127,16 @@ }, { "name": "pocketmine/bedrock-block-upgrade-schema", - "version": "4.1.0", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockBlockUpgradeSchema.git", - "reference": "d6b10cb0a5e69fb1dfe3b7f493bf4f519723a9cb" + "reference": "8a327197b3b462fa282f40f76b070ffe585a25d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/d6b10cb0a5e69fb1dfe3b7f493bf4f519723a9cb", - "reference": "d6b10cb0a5e69fb1dfe3b7f493bf4f519723a9cb", + "url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/8a327197b3b462fa282f40f76b070ffe585a25d2", + "reference": "8a327197b3b462fa282f40f76b070ffe585a25d2", "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.1.0" + "source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/4.2.0" }, - "time": "2024-04-05T17:28:14+00:00" + "time": "2024-06-13T17:28:26+00:00" }, { "name": "pocketmine/bedrock-data", - "version": "2.10.0+bedrock-1.20.80", + "version": "2.11.0+bedrock-1.21.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockData.git", - "reference": "d7d709fec3848f56ca77f5ff0e5d4741b59f9d69" + "reference": "cae40bde98081b388c4d3ab59d45b8d1cf5d8761" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/d7d709fec3848f56ca77f5ff0e5d4741b59f9d69", - "reference": "d7d709fec3848f56ca77f5ff0e5d4741b59f9d69", + "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/cae40bde98081b388c4d3ab59d45b8d1cf5d8761", + "reference": "cae40bde98081b388c4d3ab59d45b8d1cf5d8761", "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.20.80" + "source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.21.0" }, - "time": "2024-04-25T10:08:23+00:00" + "time": "2024-06-13T17:17:55+00:00" }, { "name": "pocketmine/bedrock-item-upgrade-schema", - "version": "1.9.0", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockItemUpgradeSchema.git", - "reference": "24a89457c17c271b5378b195931e720873865a79" + "reference": "b4687afa19f91eacebd46c40d487f4cc515be504" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/24a89457c17c271b5378b195931e720873865a79", - "reference": "24a89457c17c271b5378b195931e720873865a79", + "url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/b4687afa19f91eacebd46c40d487f4cc515be504", + "reference": "b4687afa19f91eacebd46c40d487f4cc515be504", "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.9.0" + "source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.10.0" }, - "time": "2024-04-05T18:46:07+00:00" + "time": "2024-05-15T15:15:55+00:00" }, { "name": "pocketmine/bedrock-protocol", - "version": "30.0.0+bedrock-1.20.80", + "version": "31.0.0+bedrock-1.21.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "dc7606a9f778eeeeccfae393bd58e0b62ec6f85a" + "reference": "972373b6b8068963649f0a95163424eb5b645e29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/dc7606a9f778eeeeccfae393bd58e0b62ec6f85a", - "reference": "dc7606a9f778eeeeccfae393bd58e0b62ec6f85a", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/972373b6b8068963649f0a95163424eb5b645e29", + "reference": "972373b6b8068963649f0a95163424eb5b645e29", "shasum": "" }, "require": { @@ -227,7 +227,7 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "1.10.59", + "phpstan/phpstan": "1.11.2", "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/30.0.0+bedrock-1.20.80" + "source": "https://github.com/pmmp/BedrockProtocol/tree/31.0.0+bedrock-1.21.0" }, - "time": "2024-04-05T17:53:35+00:00" + "time": "2024-06-13T17:34:14+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php index 8315f2b3b..6e5bbcd1f 100644 --- a/src/crafting/CraftingManagerFromDataHelper.php +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -236,6 +236,7 @@ final class CraftingManagerFromDataHelper{ } $outputs[] = $output; } + //TODO: check unlocking requirements - our current system doesn't support this $result->registerShapelessRecipe(new ShapelessRecipe( $inputs, $outputs, @@ -262,6 +263,7 @@ final class CraftingManagerFromDataHelper{ } $outputs[] = $output; } + //TODO: check unlocking requirements - our current system doesn't support this $result->registerShapedRecipe(new ShapedRecipe( $recipe->shape, $inputs, diff --git a/src/crafting/json/ShapedRecipeData.php b/src/crafting/json/ShapedRecipeData.php index dd040f516..965a437ea 100644 --- a/src/crafting/json/ShapedRecipeData.php +++ b/src/crafting/json/ShapedRecipeData.php @@ -23,7 +23,9 @@ declare(strict_types=1); namespace pocketmine\crafting\json; -final class ShapedRecipeData{ +use function count; + +final class ShapedRecipeData implements \JsonSerializable{ /** * @required * @var string[] @@ -51,22 +53,39 @@ final class ShapedRecipeData{ /** @required */ public int $priority; + /** @var RecipeIngredientData[] */ + public array $unlockingIngredients = []; + /** * TODO: convert this to use promoted properties - avoiding them for now since it would break JsonMapper * * @param string[] $shape * @param RecipeIngredientData[] $input * @param ItemStackData[] $output + * @param RecipeIngredientData[] $unlockingIngredients * * @phpstan-param list $shape * @phpstan-param array $input * @phpstan-param list $output + * @phpstan-param list $unlockingIngredients */ - public function __construct(array $shape, array $input, array $output, string $block, int $priority){ + public function __construct(array $shape, array $input, array $output, string $block, int $priority, array $unlockingIngredients = []){ $this->block = $block; $this->priority = $priority; $this->shape = $shape; $this->input = $input; $this->output = $output; + $this->unlockingIngredients = $unlockingIngredients; + } + + /** + * @return mixed[] + */ + public function jsonSerialize() : array{ + $result = (array) $this; + if(count($this->unlockingIngredients) === 0){ + unset($result["unlockingIngredients"]); + } + return $result; } } diff --git a/src/crafting/json/ShapelessRecipeData.php b/src/crafting/json/ShapelessRecipeData.php index d59bafbbf..23cfebde0 100644 --- a/src/crafting/json/ShapelessRecipeData.php +++ b/src/crafting/json/ShapelessRecipeData.php @@ -23,7 +23,9 @@ declare(strict_types=1); namespace pocketmine\crafting\json; -final class ShapelessRecipeData{ +use function count; + +final class ShapelessRecipeData implements \JsonSerializable{ /** * @required @@ -45,17 +47,34 @@ final class ShapelessRecipeData{ /** @required */ public int $priority; + /** @var RecipeIngredientData[] */ + public array $unlockingIngredients = []; + /** * @param RecipeIngredientData[] $input * @param ItemStackData[] $output + * @param RecipeIngredientData[] $unlockingIngredients * * @phpstan-param list $input * @phpstan-param list $output + * @phpstan-param list $unlockingIngredients */ - public function __construct(array $input, array $output, string $block, int $priority){ + public function __construct(array $input, array $output, string $block, int $priority, array $unlockingIngredients = []){ $this->block = $block; $this->priority = $priority; $this->input = $input; $this->output = $output; + $this->unlockingIngredients = $unlockingIngredients; + } + + /** + * @return mixed[] + */ + public function jsonSerialize() : array{ + $result = (array) $this; + if(count($this->unlockingIngredients) === 0){ + unset($result["unlockingIngredients"]); + } + return $result; } } diff --git a/src/data/bedrock/block/BlockStateData.php b/src/data/bedrock/block/BlockStateData.php index 21f2bc53c..51899b72b 100644 --- a/src/data/bedrock/block/BlockStateData.php +++ b/src/data/bedrock/block/BlockStateData.php @@ -41,8 +41,8 @@ final class BlockStateData{ */ public const CURRENT_VERSION = (1 << 24) | //major - (20 << 16) | //minor - (80 << 8) | //patch + (21 << 16) | //minor + (0 << 8) | //patch (3); //revision public const TAG_NAME = "name"; diff --git a/src/data/bedrock/block/BlockStateNames.php b/src/data/bedrock/block/BlockStateNames.php index b996acf04..4564f696e 100644 --- a/src/data/bedrock/block/BlockStateNames.php +++ b/src/data/bedrock/block/BlockStateNames.php @@ -59,7 +59,6 @@ final class BlockStateNames{ public const COLOR_BIT = "color_bit"; public const COMPOSTER_FILL_LEVEL = "composter_fill_level"; public const CONDITIONAL_BIT = "conditional_bit"; - public const CORAL_COLOR = "coral_color"; public const CORAL_DIRECTION = "coral_direction"; public const CORAL_FAN_DIRECTION = "coral_fan_direction"; public const CORAL_HANG_TYPE_BIT = "coral_hang_type_bit"; @@ -73,7 +72,6 @@ final class BlockStateNames{ public const DIRT_TYPE = "dirt_type"; public const DISARMED_BIT = "disarmed_bit"; public const DOOR_HINGE_BIT = "door_hinge_bit"; - public const DOUBLE_PLANT_TYPE = "double_plant_type"; public const DRAG_DOWN = "drag_down"; public const DRIPSTONE_THICKNESS = "dripstone_thickness"; public const END_PORTAL_EYE_BIT = "end_portal_eye_bit"; @@ -105,6 +103,7 @@ final class BlockStateNames{ public const MONSTER_EGG_STONE_TYPE = "monster_egg_stone_type"; public const MULTI_FACE_DIRECTION_BITS = "multi_face_direction_bits"; public const OCCUPIED_BIT = "occupied_bit"; + public const OMINOUS = "ominous"; public const OPEN_BIT = "open_bit"; public const ORIENTATION = "orientation"; public const OUTPUT_LIT_BIT = "output_lit_bit"; @@ -137,7 +136,6 @@ final class BlockStateNames{ public const STRUCTURE_BLOCK_TYPE = "structure_block_type"; public const STRUCTURE_VOID_TYPE = "structure_void_type"; public const SUSPENDED_BIT = "suspended_bit"; - public const TALL_GRASS_TYPE = "tall_grass_type"; public const TOGGLE_BIT = "toggle_bit"; public const TORCH_FACING_DIRECTION = "torch_facing_direction"; public const TRIAL_SPAWNER_STATE = "trial_spawner_state"; diff --git a/src/data/bedrock/block/BlockStateStringValues.php b/src/data/bedrock/block/BlockStateStringValues.php index 2b45c4738..8538c3deb 100644 --- a/src/data/bedrock/block/BlockStateStringValues.php +++ b/src/data/bedrock/block/BlockStateStringValues.php @@ -62,12 +62,6 @@ final class BlockStateStringValues{ public const CHISEL_TYPE_LINES = "lines"; public const CHISEL_TYPE_SMOOTH = "smooth"; - public const CORAL_COLOR_BLUE = "blue"; - public const CORAL_COLOR_PINK = "pink"; - public const CORAL_COLOR_PURPLE = "purple"; - public const CORAL_COLOR_RED = "red"; - public const CORAL_COLOR_YELLOW = "yellow"; - public const CRACKED_STATE_CRACKED = "cracked"; public const CRACKED_STATE_MAX_CRACKED = "max_cracked"; public const CRACKED_STATE_NO_CRACKS = "no_cracks"; @@ -80,13 +74,6 @@ final class BlockStateStringValues{ public const DIRT_TYPE_COARSE = "coarse"; public const DIRT_TYPE_NORMAL = "normal"; - public const DOUBLE_PLANT_TYPE_FERN = "fern"; - public const DOUBLE_PLANT_TYPE_GRASS = "grass"; - public const DOUBLE_PLANT_TYPE_PAEONIA = "paeonia"; - public const DOUBLE_PLANT_TYPE_ROSE = "rose"; - public const DOUBLE_PLANT_TYPE_SUNFLOWER = "sunflower"; - public const DOUBLE_PLANT_TYPE_SYRINGA = "syringa"; - public const DRIPSTONE_THICKNESS_BASE = "base"; public const DRIPSTONE_THICKNESS_FRUSTUM = "frustum"; public const DRIPSTONE_THICKNESS_MERGE = "merge"; @@ -220,11 +207,6 @@ final class BlockStateStringValues{ public const STRUCTURE_VOID_TYPE_AIR = "air"; public const STRUCTURE_VOID_TYPE_VOID = "void"; - public const TALL_GRASS_TYPE_DEFAULT = "default"; - public const TALL_GRASS_TYPE_FERN = "fern"; - public const TALL_GRASS_TYPE_SNOW = "snow"; - public const TALL_GRASS_TYPE_TALL = "tall"; - public const TORCH_FACING_DIRECTION_EAST = "east"; public const TORCH_FACING_DIRECTION_NORTH = "north"; public const TORCH_FACING_DIRECTION_SOUTH = "south"; diff --git a/src/data/bedrock/block/BlockTypeNames.php b/src/data/bedrock/block/BlockTypeNames.php index 9dc0961d2..25433e6eb 100644 --- a/src/data/bedrock/block/BlockTypeNames.php +++ b/src/data/bedrock/block/BlockTypeNames.php @@ -144,9 +144,11 @@ final class BlockTypeNames{ public const BOOKSHELF = "minecraft:bookshelf"; public const BORDER_BLOCK = "minecraft:border_block"; public const BRAIN_CORAL = "minecraft:brain_coral"; + public const BRAIN_CORAL_BLOCK = "minecraft:brain_coral_block"; public const BRAIN_CORAL_FAN = "minecraft:brain_coral_fan"; public const BREWING_STAND = "minecraft:brewing_stand"; public const BRICK_BLOCK = "minecraft:brick_block"; + public const BRICK_SLAB = "minecraft:brick_slab"; public const BRICK_STAIRS = "minecraft:brick_stairs"; public const BROWN_CANDLE = "minecraft:brown_candle"; public const BROWN_CANDLE_CAKE = "minecraft:brown_candle_cake"; @@ -163,6 +165,7 @@ final class BlockTypeNames{ public const BROWN_WOOL = "minecraft:brown_wool"; public const BUBBLE_COLUMN = "minecraft:bubble_column"; public const BUBBLE_CORAL = "minecraft:bubble_coral"; + public const BUBBLE_CORAL_BLOCK = "minecraft:bubble_coral_block"; public const BUBBLE_CORAL_FAN = "minecraft:bubble_coral_fan"; public const BUDDING_AMETHYST = "minecraft:budding_amethyst"; public const CACTUS = "minecraft:cactus"; @@ -221,6 +224,7 @@ final class BlockTypeNames{ public const COBBLED_DEEPSLATE_STAIRS = "minecraft:cobbled_deepslate_stairs"; public const COBBLED_DEEPSLATE_WALL = "minecraft:cobbled_deepslate_wall"; public const COBBLESTONE = "minecraft:cobblestone"; + 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"; @@ -234,7 +238,6 @@ final class BlockTypeNames{ public const COPPER_GRATE = "minecraft:copper_grate"; public const COPPER_ORE = "minecraft:copper_ore"; public const COPPER_TRAPDOOR = "minecraft:copper_trapdoor"; - public const CORAL_BLOCK = "minecraft:coral_block"; public const CORAL_FAN_HANG = "minecraft:coral_fan_hang"; public const CORAL_FAN_HANG2 = "minecraft:coral_fan_hang2"; public const CORAL_FAN_HANG3 = "minecraft:coral_fan_hang3"; @@ -299,14 +302,19 @@ final class BlockTypeNames{ public const DAYLIGHT_DETECTOR = "minecraft:daylight_detector"; public const DAYLIGHT_DETECTOR_INVERTED = "minecraft:daylight_detector_inverted"; public const DEAD_BRAIN_CORAL = "minecraft:dead_brain_coral"; + public const DEAD_BRAIN_CORAL_BLOCK = "minecraft:dead_brain_coral_block"; public const DEAD_BRAIN_CORAL_FAN = "minecraft:dead_brain_coral_fan"; public const DEAD_BUBBLE_CORAL = "minecraft:dead_bubble_coral"; + public const DEAD_BUBBLE_CORAL_BLOCK = "minecraft:dead_bubble_coral_block"; public const DEAD_BUBBLE_CORAL_FAN = "minecraft:dead_bubble_coral_fan"; public const DEAD_FIRE_CORAL = "minecraft:dead_fire_coral"; + public const DEAD_FIRE_CORAL_BLOCK = "minecraft:dead_fire_coral_block"; public const DEAD_FIRE_CORAL_FAN = "minecraft:dead_fire_coral_fan"; public const DEAD_HORN_CORAL = "minecraft:dead_horn_coral"; + public const DEAD_HORN_CORAL_BLOCK = "minecraft:dead_horn_coral_block"; public const DEAD_HORN_CORAL_FAN = "minecraft:dead_horn_coral_fan"; public const DEAD_TUBE_CORAL = "minecraft:dead_tube_coral"; + public const DEAD_TUBE_CORAL_BLOCK = "minecraft:dead_tube_coral_block"; public const DEAD_TUBE_CORAL_FAN = "minecraft:dead_tube_coral_fan"; public const DEADBUSH = "minecraft:deadbush"; public const DECORATED_POT = "minecraft:decorated_pot"; @@ -339,7 +347,6 @@ final class BlockTypeNames{ public const DIRT_WITH_ROOTS = "minecraft:dirt_with_roots"; public const DISPENSER = "minecraft:dispenser"; public const DOUBLE_CUT_COPPER_SLAB = "minecraft:double_cut_copper_slab"; - public const DOUBLE_PLANT = "minecraft:double_plant"; public const DOUBLE_STONE_BLOCK_SLAB = "minecraft:double_stone_block_slab"; public const DOUBLE_STONE_BLOCK_SLAB2 = "minecraft:double_stone_block_slab2"; public const DOUBLE_STONE_BLOCK_SLAB3 = "minecraft:double_stone_block_slab3"; @@ -490,8 +497,10 @@ final class BlockTypeNames{ public const EXPOSED_DOUBLE_CUT_COPPER_SLAB = "minecraft:exposed_double_cut_copper_slab"; public const FARMLAND = "minecraft:farmland"; public const FENCE_GATE = "minecraft:fence_gate"; + public const FERN = "minecraft:fern"; public const FIRE = "minecraft:fire"; public const FIRE_CORAL = "minecraft:fire_coral"; + public const FIRE_CORAL_BLOCK = "minecraft:fire_coral_block"; public const FIRE_CORAL_FAN = "minecraft:fire_coral_fan"; public const FLETCHING_TABLE = "minecraft:fletching_table"; public const FLOWER_POT = "minecraft:flower_pot"; @@ -583,6 +592,7 @@ final class BlockTypeNames{ public const HONEYCOMB_BLOCK = "minecraft:honeycomb_block"; public const HOPPER = "minecraft:hopper"; public const HORN_CORAL = "minecraft:horn_coral"; + public const HORN_CORAL_BLOCK = "minecraft:horn_coral_block"; public const HORN_CORAL_FAN = "minecraft:horn_coral_fan"; public const ICE = "minecraft:ice"; public const INFESTED_DEEPSLATE = "minecraft:infested_deepslate"; @@ -619,6 +629,7 @@ final class BlockTypeNames{ public const LAPIS_BLOCK = "minecraft:lapis_block"; public const LAPIS_ORE = "minecraft:lapis_ore"; public const LARGE_AMETHYST_BUD = "minecraft:large_amethyst_bud"; + public const LARGE_FERN = "minecraft:large_fern"; public const LAVA = "minecraft:lava"; public const LECTERN = "minecraft:lectern"; public const LEVER = "minecraft:lever"; @@ -646,6 +657,7 @@ final class BlockTypeNames{ public const LIGHT_GRAY_WOOL = "minecraft:light_gray_wool"; public const LIGHT_WEIGHTED_PRESSURE_PLATE = "minecraft:light_weighted_pressure_plate"; public const LIGHTNING_ROD = "minecraft:lightning_rod"; + public const LILAC = "minecraft:lilac"; public const LILY_OF_THE_VALLEY = "minecraft:lily_of_the_valley"; public const LIME_CANDLE = "minecraft:lime_candle"; public const LIME_CANDLE_CAKE = "minecraft:lime_candle_cake"; @@ -718,6 +730,7 @@ final class BlockTypeNames{ public const MYCELIUM = "minecraft:mycelium"; public const NETHER_BRICK = "minecraft:nether_brick"; 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_GOLD_ORE = "minecraft:nether_gold_ore"; public const NETHER_SPROUTS = "minecraft:nether_sprouts"; @@ -767,6 +780,8 @@ final class BlockTypeNames{ public const PACKED_ICE = "minecraft:packed_ice"; public const PACKED_MUD = "minecraft:packed_mud"; public const PEARLESCENT_FROGLIGHT = "minecraft:pearlescent_froglight"; + public const PEONY = "minecraft:peony"; + public const PETRIFIED_OAK_SLAB = "minecraft:petrified_oak_slab"; public const PINK_CANDLE = "minecraft:pink_candle"; public const PINK_CANDLE_CAKE = "minecraft:pink_candle_cake"; public const PINK_CARPET = "minecraft:pink_carpet"; @@ -842,6 +857,7 @@ final class BlockTypeNames{ public const QUARTZ_BLOCK = "minecraft:quartz_block"; public const QUARTZ_BRICKS = "minecraft:quartz_bricks"; public const QUARTZ_ORE = "minecraft:quartz_ore"; + public const QUARTZ_SLAB = "minecraft:quartz_slab"; public const QUARTZ_STAIRS = "minecraft:quartz_stairs"; public const RAIL = "minecraft:rail"; public const RAW_COPPER_BLOCK = "minecraft:raw_copper_block"; @@ -875,8 +891,10 @@ final class BlockTypeNames{ public const REPEATING_COMMAND_BLOCK = "minecraft:repeating_command_block"; public const RESERVED6 = "minecraft:reserved6"; public const RESPAWN_ANCHOR = "minecraft:respawn_anchor"; + public const ROSE_BUSH = "minecraft:rose_bush"; public const SAND = "minecraft:sand"; public const SANDSTONE = "minecraft:sandstone"; + public const SANDSTONE_SLAB = "minecraft:sandstone_slab"; public const SANDSTONE_STAIRS = "minecraft:sandstone_stairs"; public const SCAFFOLDING = "minecraft:scaffolding"; public const SCULK = "minecraft:sculk"; @@ -887,6 +905,7 @@ final class BlockTypeNames{ public const SEA_LANTERN = "minecraft:sea_lantern"; public const SEA_PICKLE = "minecraft:sea_pickle"; public const SEAGRASS = "minecraft:seagrass"; + public const SHORT_GRASS = "minecraft:short_grass"; public const SHROOMLIGHT = "minecraft:shroomlight"; public const SILVER_GLAZED_TERRACOTTA = "minecraft:silver_glazed_terracotta"; public const SKULL = "minecraft:skull"; @@ -900,6 +919,7 @@ final class BlockTypeNames{ public const SMOOTH_RED_SANDSTONE_STAIRS = "minecraft:smooth_red_sandstone_stairs"; public const SMOOTH_SANDSTONE_STAIRS = "minecraft:smooth_sandstone_stairs"; public const SMOOTH_STONE = "minecraft:smooth_stone"; + public const SMOOTH_STONE_SLAB = "minecraft:smooth_stone_slab"; public const SNIFFER_EGG = "minecraft:sniffer_egg"; public const SNOW = "minecraft:snow"; public const SNOW_LAYER = "minecraft:snow_layer"; @@ -933,10 +953,10 @@ final class BlockTypeNames{ public const STICKY_PISTON = "minecraft:sticky_piston"; public const STICKY_PISTON_ARM_COLLISION = "minecraft:sticky_piston_arm_collision"; public const STONE = "minecraft:stone"; - public const STONE_BLOCK_SLAB = "minecraft:stone_block_slab"; public const STONE_BLOCK_SLAB2 = "minecraft:stone_block_slab2"; public const STONE_BLOCK_SLAB3 = "minecraft:stone_block_slab3"; public const STONE_BLOCK_SLAB4 = "minecraft:stone_block_slab4"; + public const STONE_BRICK_SLAB = "minecraft:stone_brick_slab"; public const STONE_BRICK_STAIRS = "minecraft:stone_brick_stairs"; public const STONE_BUTTON = "minecraft:stone_button"; public const STONE_PRESSURE_PLATE = "minecraft:stone_pressure_plate"; @@ -967,10 +987,11 @@ final class BlockTypeNames{ public const STRIPPED_WARPED_STEM = "minecraft:stripped_warped_stem"; public const STRUCTURE_BLOCK = "minecraft:structure_block"; public const STRUCTURE_VOID = "minecraft:structure_void"; + public const SUNFLOWER = "minecraft:sunflower"; public const SUSPICIOUS_GRAVEL = "minecraft:suspicious_gravel"; public const SUSPICIOUS_SAND = "minecraft:suspicious_sand"; public const SWEET_BERRY_BUSH = "minecraft:sweet_berry_bush"; - public const TALLGRASS = "minecraft:tallgrass"; + public const TALL_GRASS = "minecraft:tall_grass"; public const TARGET = "minecraft:target"; public const TINTED_GLASS = "minecraft:tinted_glass"; public const TNT = "minecraft:tnt"; @@ -983,6 +1004,7 @@ final class BlockTypeNames{ public const TRIP_WIRE = "minecraft:trip_wire"; public const TRIPWIRE_HOOK = "minecraft:tripwire_hook"; public const TUBE_CORAL = "minecraft:tube_coral"; + public const TUBE_CORAL_BLOCK = "minecraft:tube_coral_block"; public const TUBE_CORAL_FAN = "minecraft:tube_coral_fan"; public const TUFF = "minecraft:tuff"; public const TUFF_BRICK_DOUBLE_SLAB = "minecraft:tuff_brick_double_slab"; diff --git a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php index e0c570ee4..ab98e75f3 100644 --- a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php +++ b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php @@ -552,6 +552,16 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ Axis::Z => 1, default => throw new BlockStateSerializeException("Invalid axis {$axis}"), })); + + $this->map(Blocks::CORAL_BLOCK(), fn(CoralBlock $block) => Writer::create( + match($block->getCoralType()){ + CoralType::BRAIN => $block->isDead() ? Ids::DEAD_BRAIN_CORAL_BLOCK : Ids::BRAIN_CORAL_BLOCK, + CoralType::BUBBLE => $block->isDead() ? Ids::DEAD_BUBBLE_CORAL_BLOCK : Ids::BUBBLE_CORAL_BLOCK, + CoralType::FIRE => $block->isDead() ? Ids::DEAD_FIRE_CORAL_BLOCK : Ids::FIRE_CORAL_BLOCK, + CoralType::HORN => $block->isDead() ? Ids::DEAD_HORN_CORAL_BLOCK : Ids::HORN_CORAL_BLOCK, + CoralType::TUBE => $block->isDead() ? Ids::DEAD_TUBE_CORAL_BLOCK : Ids::TUBE_CORAL_BLOCK, + } + )); } private function registerCauldronSerializers() : void{ @@ -928,6 +938,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->mapSimple(Blocks::ENCHANTING_TABLE(), Ids::ENCHANTING_TABLE); $this->mapSimple(Blocks::END_STONE(), Ids::END_STONE); $this->mapSimple(Blocks::END_STONE_BRICKS(), Ids::END_BRICKS); + $this->mapSimple(Blocks::FERN(), Ids::FERN); $this->mapSimple(Blocks::FLETCHING_TABLE(), Ids::FLETCHING_TABLE); $this->mapSimple(Blocks::GILDED_BLACKSTONE(), Ids::GILDED_BLACKSTONE); $this->mapSimple(Blocks::GLASS(), Ids::GLASS); @@ -1006,6 +1017,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->mapSimple(Blocks::SOUL_SOIL(), Ids::SOUL_SOIL); $this->mapSimple(Blocks::SPORE_BLOSSOM(), Ids::SPORE_BLOSSOM); $this->mapSimple(Blocks::STONE(), Ids::STONE); + $this->mapSimple(Blocks::TALL_GRASS(), Ids::SHORT_GRASS); //no, this is not a typo - tall_grass is now the double block, just to be confusing :( $this->mapSimple(Blocks::TINTED_GLASS(), Ids::TINTED_GLASS); $this->mapSimple(Blocks::TORCHFLOWER(), Ids::TORCHFLOWER); $this->mapSimple(Blocks::TUFF(), Ids::TUFF); @@ -1136,7 +1148,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ->writeBool(StateNames::BREWING_STAND_SLOT_B_BIT, $block->hasSlot(BrewingStandSlot::SOUTHWEST)) ->writeBool(StateNames::BREWING_STAND_SLOT_C_BIT, $block->hasSlot(BrewingStandSlot::NORTHWEST)); }); - $this->map(Blocks::BRICK_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, StringValues::STONE_SLAB_TYPE_BRICK)); + $this->map(Blocks::BRICK_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, Ids::BRICK_SLAB, StringValues::STONE_SLAB_TYPE_BRICK)); $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::BROWN_MUSHROOM_BLOCK(), fn(BrownMushroomBlock $block) => Helper::encodeMushroomBlock($block, new Writer(Ids::BROWN_MUSHROOM_BLOCK))); @@ -1192,7 +1204,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->mapSlab(Blocks::COBBLED_DEEPSLATE_SLAB(), Ids::COBBLED_DEEPSLATE_SLAB, Ids::COBBLED_DEEPSLATE_DOUBLE_SLAB); $this->mapStairs(Blocks::COBBLED_DEEPSLATE_STAIRS(), Ids::COBBLED_DEEPSLATE_STAIRS); $this->map(Blocks::COBBLED_DEEPSLATE_WALL(), fn(Wall $block) => Helper::encodeWall($block, new Writer(Ids::COBBLED_DEEPSLATE_WALL))); - $this->map(Blocks::COBBLESTONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, StringValues::STONE_SLAB_TYPE_COBBLESTONE)); + $this->map(Blocks::COBBLESTONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, Ids::COBBLESTONE_SLAB, StringValues::STONE_SLAB_TYPE_COBBLESTONE)); $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::COPPER(), function(Copper $block) : Writer{ @@ -1275,11 +1287,6 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ->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::CORAL_BLOCK(), function(CoralBlock $block) : Writer{ - return Writer::create(Ids::CORAL_BLOCK) - ->writeBool(StateNames::DEAD_BIT, $block->isDead()) - ->writeCoralType($block->getCoralType()); - }); $this->map(Blocks::CRACKED_STONE_BRICKS(), fn() => Helper::encodeStoneBricks(StringValues::STONE_BRICK_TYPE_CRACKED)); $this->map(Blocks::CUT_RED_SANDSTONE(), fn() => Helper::encodeSandstone(Ids::RED_SANDSTONE, StringValues::SAND_STONE_TYPE_CUT)); $this->map(Blocks::CUT_RED_SANDSTONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab4($block, StringValues::STONE_SLAB_TYPE_4_CUT_RED_SANDSTONE)); @@ -1324,7 +1331,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ //ROOTED was already checked above }); }); - $this->map(Blocks::DOUBLE_TALLGRASS(), fn(DoubleTallGrass $block) => Helper::encodeDoublePlant($block, StringValues::DOUBLE_PLANT_TYPE_GRASS, Writer::create(Ids::DOUBLE_PLANT))); + $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::ENDER_CHEST(), function(EnderChest $block) : Writer{ return Writer::create(Ids::ENDER_CHEST) @@ -1342,13 +1349,11 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->map(Blocks::END_STONE_BRICK_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab3($block, StringValues::STONE_SLAB_TYPE_3_END_STONE_BRICK)); $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::FAKE_WOODEN_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, StringValues::STONE_SLAB_TYPE_WOOD)); + $this->map(Blocks::FAKE_WOODEN_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, Ids::PETRIFIED_OAK_SLAB, StringValues::STONE_SLAB_TYPE_WOOD)); $this->map(Blocks::FARMLAND(), function(Farmland $block) : Writer{ return Writer::create(Ids::FARMLAND) ->writeInt(StateNames::MOISTURIZED_AMOUNT, $block->getWetness()); }); - $this->map(Blocks::FERN(), fn() => Writer::create(Ids::TALLGRASS) - ->writeString(StateNames::TALL_GRASS_TYPE, StringValues::TALL_GRASS_TYPE_FERN)); $this->map(Blocks::FIRE(), function(Fire $block) : Writer{ return Writer::create(Ids::FIRE) ->writeInt(StateNames::AGE, $block->getAge()); @@ -1413,7 +1418,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ return Writer::create(Ids::LANTERN) ->writeBool(StateNames::HANGING, $block->isHanging()); }); - $this->map(Blocks::LARGE_FERN(), fn(DoubleTallGrass $block) => Helper::encodeDoublePlant($block, StringValues::DOUBLE_PLANT_TYPE_FERN, Writer::create(Ids::DOUBLE_PLANT))); + $this->map(Blocks::LARGE_FERN(), fn(DoubleTallGrass $block) => Helper::encodeDoublePlant($block, Writer::create(Ids::LARGE_FERN))); $this->map(Blocks::LAVA(), fn(Lava $block) => Helper::encodeLiquid($block, Ids::LAVA, Ids::FLOWING_LAVA)); $this->map(Blocks::LECTERN(), function(Lectern $block) : Writer{ return Writer::create(Ids::LECTERN) @@ -1442,7 +1447,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ return Writer::create(Ids::LIGHTNING_ROD) ->writeFacingDirection($block->getFacing()); }); - $this->map(Blocks::LILAC(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, StringValues::DOUBLE_PLANT_TYPE_SYRINGA, Writer::create(Ids::DOUBLE_PLANT))); + $this->map(Blocks::LILAC(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, Writer::create(Ids::LILAC))); $this->map(Blocks::LIT_PUMPKIN(), function(LitPumpkin $block) : Writer{ return Writer::create(Ids::LIT_PUMPKIN) ->writeCardinalHorizontalFacing($block->getFacing()); @@ -1471,7 +1476,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ->writePillarAxis($block->getAxis())); $this->map(Blocks::MUSHROOM_STEM(), fn() => Writer::create(Ids::BROWN_MUSHROOM_BLOCK) ->writeInt(StateNames::HUGE_MUSHROOM_BITS, BlockLegacyMetadata::MUSHROOM_BLOCK_STEM)); - $this->map(Blocks::NETHER_BRICK_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, StringValues::STONE_SLAB_TYPE_NETHER_BRICK)); + $this->map(Blocks::NETHER_BRICK_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, Ids::NETHER_BRICK_SLAB, StringValues::STONE_SLAB_TYPE_NETHER_BRICK)); $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_PORTAL(), function(NetherPortal $block) : Writer{ @@ -1486,7 +1491,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ return Writer::create(Ids::NETHER_WART) ->writeInt(StateNames::AGE, $block->getAge()); }); - $this->map(Blocks::PEONY(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, StringValues::DOUBLE_PLANT_TYPE_PAEONIA, Writer::create(Ids::DOUBLE_PLANT))); + $this->map(Blocks::PEONY(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, Writer::create(Ids::PEONY))); $this->map(Blocks::PINK_PETALS(), function(PinkPetals $block) : Writer{ return Writer::create(Ids::PINK_PETALS) ->writeCardinalHorizontalFacing($block->getFacing()) @@ -1562,7 +1567,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->mapStairs(Blocks::PURPUR_STAIRS(), Ids::PURPUR_STAIRS); $this->map(Blocks::QUARTZ(), fn() => Helper::encodeQuartz(StringValues::CHISEL_TYPE_DEFAULT, Axis::Y)); $this->map(Blocks::QUARTZ_PILLAR(), fn(SimplePillar $block) => Helper::encodeQuartz(StringValues::CHISEL_TYPE_LINES, $block->getAxis())); - $this->map(Blocks::QUARTZ_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, StringValues::STONE_SLAB_TYPE_QUARTZ)); + $this->map(Blocks::QUARTZ_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, Ids::QUARTZ_SLAB, StringValues::STONE_SLAB_TYPE_QUARTZ)); $this->mapStairs(Blocks::QUARTZ_STAIRS(), Ids::QUARTZ_STAIRS); $this->map(Blocks::RAIL(), function(Rail $block) : Writer{ return Writer::create(Ids::RAIL) @@ -1600,11 +1605,11 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $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::ROSE_BUSH(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, StringValues::DOUBLE_PLANT_TYPE_ROSE, Writer::create(Ids::DOUBLE_PLANT))); + $this->map(Blocks::ROSE_BUSH(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, Writer::create(Ids::ROSE_BUSH))); $this->map(Blocks::SAND(), fn() => Writer::create(Ids::SAND) ->writeString(StateNames::SAND_TYPE, StringValues::SAND_TYPE_NORMAL)); $this->map(Blocks::SANDSTONE(), fn() => Helper::encodeSandstone(Ids::SANDSTONE, StringValues::SAND_STONE_TYPE_DEFAULT)); - $this->map(Blocks::SANDSTONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, StringValues::STONE_SLAB_TYPE_SANDSTONE)); + $this->map(Blocks::SANDSTONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, Ids::SANDSTONE_SLAB, StringValues::STONE_SLAB_TYPE_SANDSTONE)); $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::SEA_PICKLE(), function(SeaPickle $block) : Writer{ @@ -1627,7 +1632,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->map(Blocks::SMOOTH_SANDSTONE(), fn() => Helper::encodeSandstone(Ids::SANDSTONE, StringValues::SAND_STONE_TYPE_SMOOTH)); $this->map(Blocks::SMOOTH_SANDSTONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab2($block, StringValues::STONE_SLAB_TYPE_2_SMOOTH_SANDSTONE)); $this->mapStairs(Blocks::SMOOTH_SANDSTONE_STAIRS(), Ids::SMOOTH_SANDSTONE_STAIRS); - $this->map(Blocks::SMOOTH_STONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, StringValues::STONE_SLAB_TYPE_SMOOTH_STONE)); + $this->map(Blocks::SMOOTH_STONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, Ids::SMOOTH_STONE_SLAB, StringValues::STONE_SLAB_TYPE_SMOOTH_STONE)); $this->map(Blocks::SNOW_LAYER(), function(SnowLayer $block) : Writer{ return Writer::create(Ids::SNOW_LAYER) ->writeBool(StateNames::COVERED_BIT, false) @@ -1652,7 +1657,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->map(Blocks::STONECUTTER(), fn(Stonecutter $block) => Writer::create(Ids::STONECUTTER_BLOCK) ->writeCardinalHorizontalFacing($block->getFacing())); $this->map(Blocks::STONE_BRICKS(), fn() => Helper::encodeStoneBricks(StringValues::STONE_BRICK_TYPE_DEFAULT)); - $this->map(Blocks::STONE_BRICK_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, StringValues::STONE_SLAB_TYPE_STONE_BRICK)); + $this->map(Blocks::STONE_BRICK_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, Ids::STONE_BRICK_SLAB, StringValues::STONE_SLAB_TYPE_STONE_BRICK)); $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_BUTTON(), fn(StoneButton $block) => Helper::encodeButton($block, new Writer(Ids::STONE_BUTTON))); @@ -1663,13 +1668,11 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ return Writer::create(Ids::REEDS) ->writeInt(StateNames::AGE, $block->getAge()); }); - $this->map(Blocks::SUNFLOWER(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, StringValues::DOUBLE_PLANT_TYPE_SUNFLOWER, Writer::create(Ids::DOUBLE_PLANT))); + $this->map(Blocks::SUNFLOWER(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, Writer::create(Ids::SUNFLOWER))); $this->map(Blocks::SWEET_BERRY_BUSH(), function(SweetBerryBush $block) : Writer{ return Writer::create(Ids::SWEET_BERRY_BUSH) ->writeInt(StateNames::GROWTH, $block->getAge()); }); - $this->map(Blocks::TALL_GRASS(), fn() => Writer::create(Ids::TALLGRASS) - ->writeString(StateNames::TALL_GRASS_TYPE, StringValues::TALL_GRASS_TYPE_TALL)); $this->map(Blocks::TNT(), function(TNT $block) : Writer{ return Writer::create(Ids::TNT) ->writeBool(StateNames::ALLOW_UNDERWATER_BIT, $block->worksUnderwater()) diff --git a/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php b/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php index de0964a20..6dda9fb81 100644 --- a/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php +++ b/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php @@ -32,6 +32,7 @@ use pocketmine\block\CopperStairs; use pocketmine\block\Crops; use pocketmine\block\DaylightSensor; use pocketmine\block\Door; +use pocketmine\block\DoublePlant; use pocketmine\block\FenceGate; use pocketmine\block\FloorCoralFan; use pocketmine\block\FloorSign; @@ -48,6 +49,7 @@ use pocketmine\block\Stair; use pocketmine\block\Stem; use pocketmine\block\Trapdoor; use pocketmine\block\utils\CopperOxidation; +use pocketmine\block\utils\SlabType; use pocketmine\block\VanillaBlocks; use pocketmine\block\Wall; use pocketmine\block\WallCoralFan; @@ -139,6 +141,12 @@ final class BlockStateDeserializerHelper{ ->setOpen($in->readBool(BlockStateNames::OPEN_BIT)); } + /** @throws BlockStateDeserializeException */ + public static function decodeDoublePlant(DoublePlant $block, BlockStateReader $in) : DoublePlant{ + return $block + ->setTop($in->readBool(BlockStateNames::UPPER_BLOCK_BIT)); + } + /** @throws BlockStateDeserializeException */ public static function decodeFenceGate(FenceGate $block, BlockStateReader $in) : FenceGate{ return $block @@ -233,6 +241,17 @@ final class BlockStateDeserializerHelper{ return $block->setPressed($in->readBoundedInt(BlockStateNames::REDSTONE_SIGNAL, 0, 15) !== 0); } + /** @throws BlockStateDeserializeException */ + public static function decodeSingleSlab(Slab $block, BlockStateReader $in) : Slab{ + return $block->setSlabType($in->readSlabPosition()); + } + + /** @throws BlockStateDeserializeException */ + public static function decodeDoubleSlab(Slab $block, BlockStateReader $in) : Slab{ + $in->ignored(StateNames::MC_VERTICAL_HALF); + return $block->setSlabType(SlabType::DOUBLE); + } + /** @throws BlockStateDeserializeException */ public static function decodeStairs(Stair $block, BlockStateReader $in) : Stair{ return $block diff --git a/src/data/bedrock/block/convert/BlockStateReader.php b/src/data/bedrock/block/convert/BlockStateReader.php index 07effd4f9..e3a02885f 100644 --- a/src/data/bedrock/block/convert/BlockStateReader.php +++ b/src/data/bedrock/block/convert/BlockStateReader.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\data\bedrock\block\convert; use pocketmine\block\utils\BellAttachmentType; -use pocketmine\block\utils\CoralType; use pocketmine\block\utils\SlabType; use pocketmine\block\utils\WallConnectionType; use pocketmine\data\bedrock\block\BlockLegacyMetadata; @@ -309,18 +308,6 @@ final class BlockStateReader{ }; } - /** @throws BlockStateDeserializeException */ - public function readCoralType() : CoralType{ - return match($type = $this->readString(BlockStateNames::CORAL_COLOR)){ - StringValues::CORAL_COLOR_BLUE => CoralType::TUBE, - StringValues::CORAL_COLOR_PINK => CoralType::BRAIN, - StringValues::CORAL_COLOR_PURPLE => CoralType::BUBBLE, - StringValues::CORAL_COLOR_RED => CoralType::FIRE, - StringValues::CORAL_COLOR_YELLOW => CoralType::HORN, - default => throw $this->badValueException(BlockStateNames::CORAL_COLOR, $type), - }; - } - /** @throws BlockStateDeserializeException */ public function readBellAttachmentType() : BellAttachmentType{ return match($type = $this->readString(BlockStateNames::ATTACHMENT)){ diff --git a/src/data/bedrock/block/convert/BlockStateSerializerHelper.php b/src/data/bedrock/block/convert/BlockStateSerializerHelper.php index a7d5ea774..a1f417d89 100644 --- a/src/data/bedrock/block/convert/BlockStateSerializerHelper.php +++ b/src/data/bedrock/block/convert/BlockStateSerializerHelper.php @@ -107,10 +107,9 @@ final class BlockStateSerializerHelper{ ->writeBool(BlockStateNames::OPEN_BIT, $block->isOpen()); } - public static function encodeDoublePlant(DoublePlant $block, string $doublePlantType, Writer $out) : Writer{ + public static function encodeDoublePlant(DoublePlant $block, Writer $out) : Writer{ return $out - ->writeBool(BlockStateNames::UPPER_BLOCK_BIT, $block->isTop()) - ->writeString(BlockStateNames::DOUBLE_PLANT_TYPE, $doublePlantType); + ->writeBool(BlockStateNames::UPPER_BLOCK_BIT, $block->isTop()); } public static function encodeFenceGate(FenceGate $block, Writer $out) : Writer{ @@ -183,11 +182,21 @@ final class BlockStateSerializerHelper{ ->writeInt(BlockStateNames::REDSTONE_SIGNAL, $block->isPressed() ? 15 : 0); } - public static function encodeSlab(Slab $block, string $singleId, string $doubleId) : Writer{ - $slabType = $block->getSlabType(); - return Writer::create($slabType === SlabType::DOUBLE ? $doubleId : $singleId) + private static function encodeSingleSlab(Slab $block, string $id) : Writer{ + return Writer::create($id) + ->writeSlabPosition($block->getSlabType()); + } + + private static function encodeDoubleSlab(Slab $block, string $id) : Writer{ + return Writer::create($id) //this is (intentionally) also written for double slabs (as zero) to maintain bug parity with MCPE - ->writeSlabPosition($slabType === SlabType::DOUBLE ? SlabType::BOTTOM : $slabType); + ->writeSlabPosition(SlabType::BOTTOM); + } + + public static function encodeSlab(Slab $block, string $singleId, string $doubleId) : Writer{ + return $block->getSlabType() === SlabType::DOUBLE ? + self::encodeDoubleSlab($block, $doubleId) : + self::encodeSingleSlab($block, $singleId); } public static function encodeStairs(Stair $block, Writer $out) : Writer{ @@ -215,8 +224,12 @@ final class BlockStateSerializerHelper{ ->writeString($typeKey, $typeValue); } - public static function encodeStoneSlab1(Slab $block, string $typeValue) : Writer{ - return self::encodeStoneSlab($block, Ids::STONE_BLOCK_SLAB, Ids::DOUBLE_STONE_BLOCK_SLAB, BlockStateNames::STONE_SLAB_TYPE, $typeValue); + public static function encodeStoneSlab1(Slab $block, string $singleId, string $doubleTypeValue) : Writer{ + //1.21 made this a mess by flattening single slab IDs but not double ones + return $block->getSlabType() === SlabType::DOUBLE ? + self::encodeDoubleSlab($block, Ids::DOUBLE_STONE_BLOCK_SLAB) + ->writeString(BlockStateNames::STONE_SLAB_TYPE, $doubleTypeValue) : + self::encodeSingleSlab($block, $singleId); } public static function encodeStoneSlab2(Slab $block, string $typeValue) : Writer{ diff --git a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php index 6b0c720f7..4c9ec4b79 100644 --- a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php +++ b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php @@ -44,7 +44,6 @@ use pocketmine\block\utils\DripleafState; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\FroglightType; use pocketmine\block\utils\LeverFacing; -use pocketmine\block\utils\SlabType; use pocketmine\block\VanillaBlocks as Blocks; use pocketmine\block\Wood; use pocketmine\data\bedrock\block\BlockLegacyMetadata; @@ -115,11 +114,8 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ * @phpstan-param \Closure(Reader) : Slab $getBlock */ public function mapSlab(string $singleId, string $doubleId, \Closure $getBlock) : void{ - $this->map($singleId, fn(Reader $in) : Slab => $getBlock($in)->setSlabType($in->readSlabPosition())); - $this->map($doubleId, function(Reader $in) use ($getBlock) : Slab{ - $in->ignored(StateNames::MC_VERTICAL_HALF); - return $getBlock($in)->setSlabType(SlabType::DOUBLE); - }); + $this->map($singleId, fn(Reader $in) => Helper::decodeSingleSlab($getBlock($in), $in)); + $this->map($doubleId, fn(Reader $in) => Helper::decodeDoubleSlab($getBlock($in), $in)); } /** @@ -450,6 +446,17 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->map($aliveId, fn(Reader $in) => Helper::decodeFloorCoralFan(Blocks::CORAL_FAN()->setCoralType($coralType)->setDead(false), $in)); $this->map($deadId, fn(Reader $in) => Helper::decodeFloorCoralFan(Blocks::CORAL_FAN()->setCoralType($coralType)->setDead(true), $in)); } + + foreach([ + [CoralType::BRAIN, Ids::BRAIN_CORAL_BLOCK, Ids::DEAD_BRAIN_CORAL_BLOCK], + [CoralType::BUBBLE, Ids::BUBBLE_CORAL_BLOCK, Ids::DEAD_BUBBLE_CORAL_BLOCK], + [CoralType::FIRE, Ids::FIRE_CORAL_BLOCK, Ids::DEAD_FIRE_CORAL_BLOCK], + [CoralType::HORN, Ids::HORN_CORAL_BLOCK, Ids::DEAD_HORN_CORAL_BLOCK], + [CoralType::TUBE, Ids::TUBE_CORAL_BLOCK, Ids::DEAD_TUBE_CORAL_BLOCK], + ] as [$coralType, $aliveId, $deadId]){ + $this->map($aliveId, fn(Reader $in) => Blocks::CORAL_BLOCK()->setCoralType($coralType)->setDead(false)); + $this->map($deadId, fn(Reader $in) => Blocks::CORAL_BLOCK()->setCoralType($coralType)->setDead(true)); + } } private function registerCauldronDeserializers() : void{ @@ -819,6 +826,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->mapSimple(Ids::ENCHANTING_TABLE, fn() => Blocks::ENCHANTING_TABLE()); $this->mapSimple(Ids::END_BRICKS, fn() => Blocks::END_STONE_BRICKS()); $this->mapSimple(Ids::END_STONE, fn() => Blocks::END_STONE()); + $this->mapSimple(Ids::FERN, fn() => Blocks::FERN()); $this->mapSimple(Ids::FLETCHING_TABLE, fn() => Blocks::FLETCHING_TABLE()); $this->mapSimple(Ids::GILDED_BLACKSTONE, fn() => Blocks::GILDED_BLACKSTONE()); $this->mapSimple(Ids::GLASS, fn() => Blocks::GLASS()); @@ -884,6 +892,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->mapSimple(Ids::RESERVED6, fn() => Blocks::RESERVED6()); $this->mapSimple(Ids::SCULK, fn() => Blocks::SCULK()); $this->mapSimple(Ids::SEA_LANTERN, fn() => Blocks::SEA_LANTERN()); + $this->mapSimple(Ids::SHORT_GRASS, fn() => Blocks::TALL_GRASS()); //no, this is not a typo - tall_grass is now the double block, just to be confusing :( $this->mapSimple(Ids::SHROOMLIGHT, fn() => Blocks::SHROOMLIGHT()); $this->mapSimple(Ids::SLIME, fn() => Blocks::SLIME()); $this->mapSimple(Ids::SMITHING_TABLE, fn() => Blocks::SMITHING_TABLE()); @@ -1109,11 +1118,6 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $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)); $this->mapStairs(Ids::CUT_COPPER_STAIRS, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_STAIRS(), CopperOxidation::NONE)); - $this->map(Ids::CORAL_BLOCK, function(Reader $in) : Block{ - return Blocks::CORAL_BLOCK() - ->setCoralType($in->readCoralType()) - ->setDead($in->readBool(StateNames::DEAD_BIT)); - }); $this->map(Ids::CORAL_FAN_HANG, fn(Reader $in) => Helper::decodeWallCoralFan(Blocks::WALL_CORAL_FAN(), $in) ->setCoralType($in->readBool(StateNames::CORAL_HANG_TYPE_BIT) ? CoralType::BRAIN : CoralType::TUBE)); $this->map(Ids::CORAL_FAN_HANG2, fn(Reader $in) => Helper::decodeWallCoralFan(Blocks::WALL_CORAL_FAN(), $in) @@ -1154,17 +1158,12 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ }); }); $this->map(Ids::DIRT_WITH_ROOTS, fn() => Blocks::DIRT()->setDirtType(DirtType::ROOTED)); - $this->map(Ids::DOUBLE_PLANT, function(Reader $in) : Block{ - return (match($type = $in->readString(StateNames::DOUBLE_PLANT_TYPE)){ - StringValues::DOUBLE_PLANT_TYPE_FERN => Blocks::LARGE_FERN(), - StringValues::DOUBLE_PLANT_TYPE_GRASS => Blocks::DOUBLE_TALLGRASS(), - StringValues::DOUBLE_PLANT_TYPE_PAEONIA => Blocks::PEONY(), - StringValues::DOUBLE_PLANT_TYPE_ROSE => Blocks::ROSE_BUSH(), - StringValues::DOUBLE_PLANT_TYPE_SUNFLOWER => Blocks::SUNFLOWER(), - StringValues::DOUBLE_PLANT_TYPE_SYRINGA => Blocks::LILAC(), - default => throw $in->badValueException(StateNames::DOUBLE_PLANT_TYPE, $type), - })->setTop($in->readBool(StateNames::UPPER_BLOCK_BIT)); - }); + $this->map(Ids::LARGE_FERN, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::LARGE_FERN(), $in)); + $this->map(Ids::TALL_GRASS, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::DOUBLE_TALLGRASS(), $in)); + $this->map(Ids::PEONY, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::PEONY(), $in)); + $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->mapStairs(Ids::END_BRICK_STAIRS, fn() => Blocks::END_STONE_BRICK_STAIRS()); $this->map(Ids::END_PORTAL_FRAME, function(Reader $in) : Block{ return Blocks::END_PORTAL_FRAME() @@ -1552,7 +1551,18 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->mapStairs(Ids::STONE_BRICK_STAIRS, fn() => Blocks::STONE_BRICK_STAIRS()); $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->mapSlab(Ids::STONE_BLOCK_SLAB, Ids::DOUBLE_STONE_BLOCK_SLAB, fn(Reader $in) => Helper::mapStoneSlab1Type($in)); + + //mess for partially flattened slabs - the single IDs were flattened but not the double ones + $this->map(Ids::DOUBLE_STONE_BLOCK_SLAB, fn(Reader $in) => Helper::decodeDoubleSlab(Helper::mapStoneSlab1Type($in), $in)); + $this->map(Ids::BRICK_SLAB, fn(Reader $in) => Helper::decodeSingleSlab(Blocks::BRICK_SLAB(), $in)); + $this->map(Ids::COBBLESTONE_SLAB, fn(Reader $in) => Helper::decodeSingleSlab(Blocks::COBBLESTONE_SLAB(), $in)); + $this->map(Ids::NETHER_BRICK_SLAB, fn(Reader $in) => Helper::decodeSingleSlab(Blocks::NETHER_BRICK_SLAB(), $in)); + $this->map(Ids::PETRIFIED_OAK_SLAB, fn(Reader $in) => Helper::decodeSingleSlab(Blocks::FAKE_WOODEN_SLAB(), $in)); + $this->map(Ids::QUARTZ_SLAB, fn(Reader $in) => Helper::decodeSingleSlab(Blocks::QUARTZ_SLAB(), $in)); + $this->map(Ids::SANDSTONE_SLAB, fn(Reader $in) => Helper::decodeSingleSlab(Blocks::SANDSTONE_SLAB(), $in)); + $this->map(Ids::SMOOTH_STONE_SLAB, fn(Reader $in) => Helper::decodeSingleSlab(Blocks::SMOOTH_STONE_SLAB(), $in)); + $this->map(Ids::STONE_BRICK_SLAB, fn(Reader $in) => Helper::decodeSingleSlab(Blocks::STONE_BRICK_SLAB(), $in)); + $this->mapSlab(Ids::STONE_BLOCK_SLAB2, Ids::DOUBLE_STONE_BLOCK_SLAB2, fn(Reader $in) => Helper::mapStoneSlab2Type($in)); $this->mapSlab(Ids::STONE_BLOCK_SLAB3, Ids::DOUBLE_STONE_BLOCK_SLAB3, fn(Reader $in) => Helper::mapStoneSlab3Type($in)); $this->mapSlab(Ids::STONE_BLOCK_SLAB4, Ids::DOUBLE_STONE_BLOCK_SLAB4, fn(Reader $in) => Helper::mapStoneSlab4Type($in)); @@ -1577,13 +1587,6 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ return Blocks::SWEET_BERRY_BUSH() ->setAge(min($growth, SweetBerryBush::STAGE_MATURE)); }); - $this->map(Ids::TALLGRASS, function(Reader $in) : Block{ - return match($type = $in->readString(StateNames::TALL_GRASS_TYPE)){ - StringValues::TALL_GRASS_TYPE_DEFAULT, StringValues::TALL_GRASS_TYPE_SNOW, StringValues::TALL_GRASS_TYPE_TALL => Blocks::TALL_GRASS(), - StringValues::TALL_GRASS_TYPE_FERN => Blocks::FERN(), - default => throw $in->badValueException(StateNames::TALL_GRASS_TYPE, $type), - }; - }); $this->map(Ids::TNT, function(Reader $in) : Block{ return Blocks::TNT() ->setUnstable($in->readBool(StateNames::EXPLODE_BIT)) diff --git a/src/data/bedrock/block/convert/BlockStateWriter.php b/src/data/bedrock/block/convert/BlockStateWriter.php index 33e82a5c0..63af92d10 100644 --- a/src/data/bedrock/block/convert/BlockStateWriter.php +++ b/src/data/bedrock/block/convert/BlockStateWriter.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\data\bedrock\block\convert; use pocketmine\block\utils\BellAttachmentType; -use pocketmine\block\utils\CoralType; use pocketmine\block\utils\SlabType; use pocketmine\block\utils\WallConnectionType; use pocketmine\data\bedrock\block\BlockLegacyMetadata; @@ -256,18 +255,6 @@ final class BlockStateWriter{ return $this; } - /** @return $this */ - public function writeCoralType(CoralType $coralType) : self{ - $this->writeString(BlockStateNames::CORAL_COLOR, match($coralType){ - CoralType::TUBE => StringValues::CORAL_COLOR_BLUE, - CoralType::BRAIN => StringValues::CORAL_COLOR_PINK, - CoralType::BUBBLE => StringValues::CORAL_COLOR_PURPLE, - CoralType::FIRE => StringValues::CORAL_COLOR_RED, - CoralType::HORN => StringValues::CORAL_COLOR_YELLOW, - }); - return $this; - } - /** @return $this */ public function writeBellAttachmentType(BellAttachmentType $attachmentType) : self{ $this->writeString(BlockStateNames::ATTACHMENT, match($attachmentType){ diff --git a/src/data/bedrock/item/ItemTypeNames.php b/src/data/bedrock/item/ItemTypeNames.php index cadbb7aa6..c2bc71caf 100644 --- a/src/data/bedrock/item/ItemTypeNames.php +++ b/src/data/bedrock/item/ItemTypeNames.php @@ -143,6 +143,7 @@ final class ItemTypeNames{ public const COPPER_DOOR = "minecraft:copper_door"; public const COPPER_INGOT = "minecraft:copper_ingot"; public const CORAL = "minecraft:coral"; + public const CORAL_BLOCK = "minecraft:coral_block"; public const CORAL_FAN = "minecraft:coral_fan"; public const CORAL_FAN_DEAD = "minecraft:coral_fan_dead"; public const COW_SPAWN_EGG = "minecraft:cow_spawn_egg"; @@ -173,6 +174,7 @@ final class ItemTypeNames{ public const DISC_FRAGMENT_5 = "minecraft:disc_fragment_5"; public const DOLPHIN_SPAWN_EGG = "minecraft:dolphin_spawn_egg"; public const DONKEY_SPAWN_EGG = "minecraft:donkey_spawn_egg"; + public const DOUBLE_PLANT = "minecraft:double_plant"; public const DRAGON_BREATH = "minecraft:dragon_breath"; public const DRIED_KELP = "minecraft:dried_kelp"; public const DROWNED_SPAWN_EGG = "minecraft:drowned_spawn_egg"; @@ -331,11 +333,14 @@ final class ItemTypeNames{ public const MUSIC_DISC_BLOCKS = "minecraft:music_disc_blocks"; public const MUSIC_DISC_CAT = "minecraft:music_disc_cat"; public const MUSIC_DISC_CHIRP = "minecraft:music_disc_chirp"; + public const MUSIC_DISC_CREATOR = "minecraft:music_disc_creator"; + public const MUSIC_DISC_CREATOR_MUSIC_BOX = "minecraft:music_disc_creator_music_box"; public const MUSIC_DISC_FAR = "minecraft:music_disc_far"; public const MUSIC_DISC_MALL = "minecraft:music_disc_mall"; public const MUSIC_DISC_MELLOHI = "minecraft:music_disc_mellohi"; public const MUSIC_DISC_OTHERSIDE = "minecraft:music_disc_otherside"; public const MUSIC_DISC_PIGSTEP = "minecraft:music_disc_pigstep"; + public const MUSIC_DISC_PRECIPICE = "minecraft:music_disc_precipice"; public const MUSIC_DISC_RELIC = "minecraft:music_disc_relic"; public const MUSIC_DISC_STAL = "minecraft:music_disc_stal"; public const MUSIC_DISC_STRAD = "minecraft:music_disc_strad"; @@ -366,6 +371,8 @@ final class ItemTypeNames{ public const OAK_HANGING_SIGN = "minecraft:oak_hanging_sign"; public const OAK_SIGN = "minecraft:oak_sign"; public const OCELOT_SPAWN_EGG = "minecraft:ocelot_spawn_egg"; + public const OMINOUS_BOTTLE = "minecraft:ominous_bottle"; + public const OMINOUS_TRIAL_KEY = "minecraft:ominous_trial_key"; public const ORANGE_DYE = "minecraft:orange_dye"; public const OXIDIZED_COPPER_DOOR = "minecraft:oxidized_copper_door"; public const PAINTING = "minecraft:painting"; @@ -467,6 +474,7 @@ final class ItemTypeNames{ public const STAINED_HARDENED_CLAY = "minecraft:stained_hardened_clay"; public const STICK = "minecraft:stick"; public const STONE_AXE = "minecraft:stone_axe"; + public const STONE_BLOCK_SLAB = "minecraft:stone_block_slab"; public const STONE_HOE = "minecraft:stone_hoe"; public const STONE_PICKAXE = "minecraft:stone_pickaxe"; public const STONE_SHOVEL = "minecraft:stone_shovel"; @@ -480,6 +488,7 @@ final class ItemTypeNames{ public const SWEET_BERRIES = "minecraft:sweet_berries"; public const TADPOLE_BUCKET = "minecraft:tadpole_bucket"; public const TADPOLE_SPAWN_EGG = "minecraft:tadpole_spawn_egg"; + public const TALLGRASS = "minecraft:tallgrass"; public const TIDE_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:tide_armor_trim_smithing_template"; public const TNT_MINECART = "minecraft:tnt_minecart"; public const TORCHFLOWER_SEEDS = "minecraft:torchflower_seeds"; diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index e2b71ab31..8c0d5b6e6 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -96,6 +96,7 @@ class InventoryManager{ private array $complexSlotToInventoryMap = []; private int $lastInventoryNetworkId = ContainerIds::FIRST; + private int $currentWindowType = WindowTypes::CONTAINER; private int $clientSelectedHotbarSlot = -1; @@ -327,9 +328,15 @@ class InventoryManager{ foreach($this->containerOpenCallbacks as $callback){ $pks = $callback($windowId, $inventory); if($pks !== null){ + $windowType = null; foreach($pks as $pk){ + if($pk instanceof ContainerOpenPacket){ + //workaround useless bullshit in 1.21 - ContainerClose requires a type now for some reason + $windowType = $pk->windowType; + } $this->session->sendDataPacket($pk); } + $this->currentWindowType = $windowType ?? WindowTypes::CONTAINER; $this->syncContents($inventory); return; } @@ -378,10 +385,11 @@ class InventoryManager{ $this->openWindowDeferred(function() : void{ $windowId = $this->getNewWindowId(); $this->associateIdWithInventory($windowId, $this->player->getInventory()); + $this->currentWindowType = WindowTypes::INVENTORY; $this->session->sendDataPacket(ContainerOpenPacket::entityInv( $windowId, - WindowTypes::INVENTORY, + $this->currentWindowType, $this->player->getId() )); }); @@ -390,7 +398,7 @@ class InventoryManager{ public function onCurrentWindowRemove() : void{ if(isset($this->networkIdToInventoryMap[$this->lastInventoryNetworkId])){ $this->remove($this->lastInventoryNetworkId); - $this->session->sendDataPacket(ContainerClosePacket::create($this->lastInventoryNetworkId, true)); + $this->session->sendDataPacket(ContainerClosePacket::create($this->lastInventoryNetworkId, $this->currentWindowType, true)); if($this->pendingCloseWindowId !== null){ throw new AssumptionFailedError("We should not have opened a new window while a window was waiting to be closed"); } @@ -411,7 +419,7 @@ class InventoryManager{ //Always send this, even if no window matches. If we told the client to close a window, it will behave as if it //initiated the close and expect an ack. - $this->session->sendDataPacket(ContainerClosePacket::create($id, false)); + $this->session->sendDataPacket(ContainerClosePacket::create($id, $this->currentWindowType, false)); if($this->pendingCloseWindowId === $id){ $this->pendingCloseWindowId = null; diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index c4a557863..29f37590e 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -36,6 +36,7 @@ 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\RecipeUnlockingRequirement; use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe as ProtocolShapedRecipe; use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe as ProtocolShapelessRecipe; use pocketmine\timings\Timings; @@ -79,6 +80,7 @@ final class CraftingDataCache{ $converter = TypeConverter::getInstance(); $recipesWithTypeIds = []; + $noUnlockingRequirement = new RecipeUnlockingRequirement(null); foreach($manager->getCraftingRecipeIndex() as $index => $recipe){ if($recipe instanceof ShapelessRecipe){ $typeTag = match($recipe->getType()){ @@ -95,6 +97,7 @@ final class CraftingDataCache{ $nullUUID, $typeTag, 50, + $noUnlockingRequirement, $index ); }elseif($recipe instanceof ShapedRecipe){ @@ -114,6 +117,7 @@ final class CraftingDataCache{ CraftingRecipeBlockName::CRAFTING_TABLE, 50, true, + $noUnlockingRequirement, $index, ); }else{ diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 924021d7e..9dc89ad99 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 = 671; + public const CURRENT_STORAGE_NETWORK_VERSION = 685; public const CURRENT_CLIENT_VERSION_TARGET = [ 1, //major - 20, //minor - 80, //patch - 5, //revision + 21, //minor + 0, //patch + 3, //revision 0 //is beta ]; diff --git a/tests/phpunit/data/bedrock/block/BlockStateDataTest.php b/tests/phpunit/data/bedrock/block/BlockStateDataTest.php index 836edfc38..96202753b 100644 --- a/tests/phpunit/data/bedrock/block/BlockStateDataTest.php +++ b/tests/phpunit/data/bedrock/block/BlockStateDataTest.php @@ -39,7 +39,19 @@ final class BlockStateDataTest extends TestCase{ ) as $schema){ $expected = BlockStateData::CURRENT_VERSION; $actual = $schema->getVersionId(); - self::assertLessThanOrEqual($expected, $actual, "Schema version $actual is newer than the current version $expected"); + self::assertLessThanOrEqual($expected, $actual, sprintf( + "Schema version %d (%d.%d.%d.%d) is newer than the current version %d (%d.%d.%d.%d)", + $actual, + ($actual >> 24) & 0xff, + ($actual >> 16) & 0xff, + ($actual >> 8) & 0xff, + $actual & 0xff, + $expected, + ($expected >> 24) & 0xff, + ($expected >> 16) & 0xff, + ($expected >> 8) & 0xff, + $expected & 0xff + )); } } } diff --git a/tools/generate-bedrock-data-from-packets.php b/tools/generate-bedrock-data-from-packets.php index 795e7ad1f..16c3062b8 100644 --- a/tools/generate-bedrock-data-from-packets.php +++ b/tools/generate-bedrock-data-from-packets.php @@ -195,7 +195,7 @@ class ParserPacketHandler extends PacketHandler{ * @return mixed[] */ private static function objectToOrderedArray(object $object) : array{ - $result = (array) $object; + $result = (array) ($object instanceof \JsonSerializable ? $object->jsonSerialize() : $object); ksort($result, SORT_STRING); foreach($result as $property => $value){ @@ -335,21 +335,25 @@ class ParserPacketHandler extends PacketHandler{ } } } + $unlockingIngredients = $entry->getUnlockingRequirement()->getUnlockingIngredients(); return new ShapedRecipeData( array_map(fn(array $array) => implode('', $array), $shape), $outputsByKey, array_map(fn(ItemStack $output) => $this->itemStackToJson($output), $entry->getOutput()), $entry->getBlockName(), - $entry->getPriority() + $entry->getPriority(), + $unlockingIngredients !== null ? array_map(fn(RecipeIngredient $input) => $this->recipeIngredientToJson($input), $unlockingIngredients) : [] ); } private function shapelessRecipeToJson(ShapelessRecipe $recipe) : ShapelessRecipeData{ + $unlockingIngredients = $recipe->getUnlockingRequirement()->getUnlockingIngredients(); return new ShapelessRecipeData( array_map(fn(RecipeIngredient $input) => $this->recipeIngredientToJson($input), $recipe->getInputs()), array_map(fn(ItemStack $output) => $this->itemStackToJson($output), $recipe->getOutputs()), $recipe->getBlockName(), - $recipe->getPriority() + $recipe->getPriority(), + $unlockingIngredients !== null ? array_map(fn(RecipeIngredient $input) => $this->recipeIngredientToJson($input), $unlockingIngredients) : [] ); } From 0ec8465fcfb795e2b17d0b79d9dbd5d7b2a7d36b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2024 18:43:10 +0100 Subject: [PATCH 11/37] shut! --- tests/phpunit/data/bedrock/block/BlockStateDataTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/phpunit/data/bedrock/block/BlockStateDataTest.php b/tests/phpunit/data/bedrock/block/BlockStateDataTest.php index 96202753b..7add2edda 100644 --- a/tests/phpunit/data/bedrock/block/BlockStateDataTest.php +++ b/tests/phpunit/data/bedrock/block/BlockStateDataTest.php @@ -27,6 +27,7 @@ use PHPUnit\Framework\TestCase; use pocketmine\data\bedrock\block\BlockStateData; use pocketmine\data\bedrock\block\upgrade\BlockStateUpgradeSchemaUtils; use Symfony\Component\Filesystem\Path; +use function sprintf; use const PHP_INT_MAX; use const pocketmine\BEDROCK_BLOCK_UPGRADE_SCHEMA_PATH; From 22a1549998ef0e4668ed48838900ad84258fe04a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2024 18:55:18 +0100 Subject: [PATCH 12/37] Release 5.16.0 --- changelogs/5.16.md | 26 ++++++++++++++++++++++++++ src/VersionInfo.php | 4 ++-- 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 changelogs/5.16.md diff --git a/changelogs/5.16.md b/changelogs/5.16.md new file mode 100644 index 000000000..8b4251d76 --- /dev/null +++ b/changelogs/5.16.md @@ -0,0 +1,26 @@ +# 5.16.0 +Released 13th June 2024. + +**For Minecraft: Bedrock Edition 1.21.0** + +This is a support release for Minecraft: Bedrock Edition 1.21.0. + +**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.0. +- Removed support for earlier versions. +- Generated permission docs are now included with every release. +- Crash throttle message (which appears when the server crashed after being up for less than 120 seconds) now shows the server uptime as well as the wait time. This should make it clearer how the wait time is decided. + +## Tools +- Added `install-local-protocol.sh` script. This allows installing local copies of protocol dependencies without needing to create releases. Useful for integration testing when doing protocol updates. + +## Fixes +- Attacking an entity with a higher damage weapon while it's on attack cooldown from a lower damage weapon (switching) no longer causes additional knockback to the victim. +- Wooden stairs can now be used as fuel in furnaces. +- Fixed incorrect description of the permission `pocketmine.command.save.perform`. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index a7d4111af..c6f88d59b 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,8 +31,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "5.15.1"; - public const IS_DEVELOPMENT_BUILD = true; + public const BASE_VERSION = "5.16.0"; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_CHANNEL = "stable"; /** From 433bd6a8aa4ecad867cb27a751e9dec7b8bf9b80 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2024 18:55:21 +0100 Subject: [PATCH 13/37] 5.16.1 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index c6f88d59b..9b935f8a0 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,8 +31,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "5.16.0"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "5.16.1"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "stable"; /** From 585aee9386a787c95e73dd0a05ffca8329606b68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2024 18:58:32 +0100 Subject: [PATCH 14/37] Fixed an oopsie from 5ef247620a7c6301a849b54e5ef1009217729fc8 I added it to the wrong set of artifacts :( --- .github/workflows/draft-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index d8a972585..311e0c827 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -92,7 +92,7 @@ jobs: - name: Create draft release uses: ncipollo/release-action@v1.14.0 with: - artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json + artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json,${{ github.workspace }}/core-permissions.rst commit: ${{ github.sha }} draft: true prerelease: ${{ steps.get-pm-version.outputs.PRERELEASE }} From b342c497d1f985079f6632930eefc0fd64362ac8 Mon Sep 17 00:00:00 2001 From: ipad54 Date: Sun, 23 Jun 2024 13:27:52 +0300 Subject: [PATCH 15/37] Added 1.21 banner patterns. --- src/block/utils/BannerPatternType.php | 2 ++ src/data/bedrock/BannerPatternTypeIdMap.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/block/utils/BannerPatternType.php b/src/block/utils/BannerPatternType.php index cd63226a7..9b1963603 100644 --- a/src/block/utils/BannerPatternType.php +++ b/src/block/utils/BannerPatternType.php @@ -81,10 +81,12 @@ enum BannerPatternType{ case DIAGONAL_RIGHT; case DIAGONAL_UP_LEFT; case DIAGONAL_UP_RIGHT; + case FLOW; case FLOWER; case GLOBE; case GRADIENT; case GRADIENT_UP; + case GUSTER; case HALF_HORIZONTAL; case HALF_HORIZONTAL_BOTTOM; case HALF_VERTICAL; diff --git a/src/data/bedrock/BannerPatternTypeIdMap.php b/src/data/bedrock/BannerPatternTypeIdMap.php index d1884350f..7d4353d4f 100644 --- a/src/data/bedrock/BannerPatternTypeIdMap.php +++ b/src/data/bedrock/BannerPatternTypeIdMap.php @@ -56,9 +56,11 @@ final class BannerPatternTypeIdMap{ BannerPatternType::DIAGONAL_UP_LEFT => "ld", BannerPatternType::DIAGONAL_UP_RIGHT => "rud", BannerPatternType::FLOWER => "flo", + BannerPatternType::FLOW => "flw", BannerPatternType::GLOBE => "glb", BannerPatternType::GRADIENT => "gra", BannerPatternType::GRADIENT_UP => "gru", + BannerPatternType::GUSTER => "gus", BannerPatternType::HALF_HORIZONTAL => "hh", BannerPatternType::HALF_HORIZONTAL_BOTTOM => "hhb", BannerPatternType::HALF_VERTICAL => "vh", From af4294295ba091204fa872b5f10a1d3f7220621d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 10:19:24 +0000 Subject: [PATCH 16/37] Bump symfony/filesystem from 6.4.7 to 6.4.9 Bumps [symfony/filesystem](https://github.com/symfony/filesystem) from 6.4.7 to 6.4.9. - [Release notes](https://github.com/symfony/filesystem/releases) - [Changelog](https://github.com/symfony/filesystem/blob/7.1/CHANGELOG.md) - [Commits](https://github.com/symfony/filesystem/compare/v6.4.7...v6.4.9) --- updated-dependencies: - dependency-name: symfony/filesystem dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- composer.lock | 103 +++++++++++--------------------------------------- 1 file changed, 22 insertions(+), 81 deletions(-) diff --git a/composer.lock b/composer.lock index b2f82093b..9b9c51756 100644 --- a/composer.lock +++ b/composer.lock @@ -926,23 +926,25 @@ }, { "name": "symfony/filesystem", - "version": "v6.4.7", + "version": "v6.4.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "78dde75f8f6dbbca4ec436a4b0087f7af02076d4" + "reference": "b51ef8059159330b74a4d52f68e671033c0fe463" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/78dde75f8f6dbbca4ec436a4b0087f7af02076d4", - "reference": "78dde75f8f6dbbca4ec436a4b0087f7af02076d4", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b51ef8059159330b74a4d52f68e671033c0fe463", + "reference": "b51ef8059159330b74a4d52f68e671033c0fe463", "shasum": "" }, "require": { "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8", - "symfony/process": "^5.4|^6.4" + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" }, "type": "library", "autoload": { @@ -970,7 +972,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.7" + "source": "https://github.com/symfony/filesystem/tree/v6.4.9" }, "funding": [ { @@ -986,20 +988,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:22:46+00:00" + "time": "2024-06-28T09:49:33+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "0424dff1c58f028c451efff2045f5d92410bd540" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", + "reference": "0424dff1c58f028c451efff2045f5d92410bd540", "shasum": "" }, "require": { @@ -1049,7 +1051,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" }, "funding": [ { @@ -1065,20 +1067,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", "shasum": "" }, "require": { @@ -1129,7 +1131,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" }, "funding": [ { @@ -1145,68 +1147,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" - }, - { - "name": "symfony/process", - "version": "v6.4.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "cdb1c81c145fd5aa9b0038bab694035020943381" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/cdb1c81c145fd5aa9b0038bab694035020943381", - "reference": "cdb1c81c145fd5aa9b0038bab694035020943381", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v6.4.7" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-04-18T09:22:46+00:00" + "time": "2024-06-19T12:30:46+00:00" } ], "packages-dev": [ From 25ea9b2218284daed3a786cb15e0c2e4291dced6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 10:53:54 +0000 Subject: [PATCH 17/37] Bump phpunit/phpunit from 10.3.5 to 10.5.24 Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 10.3.5 to 10.5.24. - [Release notes](https://github.com/sebastianbergmann/phpunit/releases) - [Changelog](https://github.com/sebastianbergmann/phpunit/blob/10.5.24/ChangeLog-10.5.md) - [Commits](https://github.com/sebastianbergmann/phpunit/compare/10.3.5...10.5.24) --- updated-dependencies: - dependency-name: phpunit/phpunit dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- composer.json | 2 +- composer.lock | 43 ++++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/composer.json b/composer.json index f14070552..dbc1b1354 100644 --- a/composer.json +++ b/composer.json @@ -55,7 +55,7 @@ "phpstan/phpstan": "1.11.2", "phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-strict-rules": "^1.2.0", - "phpunit/phpunit": "~10.3.0 || ~10.2.0 || ~10.1.0" + "phpunit/phpunit": "^10.5.24" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 9b9c51756..ce8d52e26 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": "941b6d463cb044438aa7908b76f7a6bb", + "content-hash": "6254ce9a454f8c9acd4936512c4d315a", "packages": [ { "name": "adhocore/json-comment", @@ -1153,16 +1153,16 @@ "packages-dev": [ { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -1170,11 +1170,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -1200,7 +1201,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -1208,7 +1209,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "nikic/php-parser", @@ -1547,16 +1548,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.14", + "version": "10.1.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "e3f51450ebffe8e0efdf7346ae966a656f7d5e5b" + "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e3f51450ebffe8e0efdf7346ae966a656f7d5e5b", - "reference": "e3f51450ebffe8e0efdf7346ae966a656f7d5e5b", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", + "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", "shasum": "" }, "require": { @@ -1613,7 +1614,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.14" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.15" }, "funding": [ { @@ -1621,7 +1622,7 @@ "type": "github" } ], - "time": "2024-03-12T15:33:41+00:00" + "time": "2024-06-29T08:25:15+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1868,16 +1869,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.3.5", + "version": "10.5.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "747c3b2038f1139e3dcd9886a3f5a948648b7503" + "reference": "5f124e3e3e561006047b532fd0431bf5bb6b9015" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/747c3b2038f1139e3dcd9886a3f5a948648b7503", - "reference": "747c3b2038f1139e3dcd9886a3f5a948648b7503", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5f124e3e3e561006047b532fd0431bf5bb6b9015", + "reference": "5f124e3e3e561006047b532fd0431bf5bb6b9015", "shasum": "" }, "require": { @@ -1917,7 +1918,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.3-dev" + "dev-main": "10.5-dev" } }, "autoload": { @@ -1949,7 +1950,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.5" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.24" }, "funding": [ { @@ -1965,7 +1966,7 @@ "type": "tidelift" } ], - "time": "2023-09-19T05:42:37+00:00" + "time": "2024-06-20T13:09:54+00:00" }, { "name": "sebastian/cli-parser", From 20f5741ed751bbd49cf03236520e55b0a578c21a Mon Sep 17 00:00:00 2001 From: Hugo_ <55756021+Dhaiven@users.noreply.github.com> Date: Sat, 6 Jul 2024 00:41:22 +0200 Subject: [PATCH 18/37] Bowl: Add fuel return value (#6384) --- src/item/Bowl.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/item/Bowl.php b/src/item/Bowl.php index d83044307..217346df5 100644 --- a/src/item/Bowl.php +++ b/src/item/Bowl.php @@ -25,5 +25,7 @@ namespace pocketmine\item; class Bowl extends Item{ - //TODO: check fuel + public function getFuelTime() : int{ + return 200; + } } From 2ffc38c835466ee9b202448b456fb99860aac9c3 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Sun, 7 Jul 2024 23:01:34 +0300 Subject: [PATCH 19/37] Implement campfire & soul campfire (#4696) --- src/block/BlockTypeIds.php | 4 +- src/block/Campfire.php | 277 ++++++++++++++++++ src/block/SoulCampfire.php | 48 +++ src/block/VanillaBlocks.php | 8 + src/block/inventory/CampfireInventory.php | 40 +++ src/block/tile/Campfire.php | 143 +++++++++ src/block/tile/TileFactory.php | 2 +- .../CraftingManagerFromDataHelper.php | 3 +- src/crafting/FurnaceType.php | 6 + .../convert/BlockObjectToStateSerializer.php | 12 + .../BlockStateToObjectDeserializer.php | 10 + .../ItemSerializerDeserializerRegistrar.php | 2 + src/event/block/CampfireCookEvent.php | 63 ++++ src/item/StringToItemParser.php | 2 + src/network/mcpe/cache/CraftingDataCache.php | 2 + src/world/sound/CampfireSound.php | 35 +++ tests/phpstan/configs/actual-problems.neon | 5 + .../block_factory_consistency_check.json | 2 + 18 files changed, 661 insertions(+), 3 deletions(-) create mode 100644 src/block/Campfire.php create mode 100644 src/block/SoulCampfire.php create mode 100644 src/block/inventory/CampfireInventory.php create mode 100644 src/block/tile/Campfire.php create mode 100644 src/event/block/CampfireCookEvent.php create mode 100644 src/world/sound/CampfireSound.php diff --git a/src/block/BlockTypeIds.php b/src/block/BlockTypeIds.php index dec31eff1..59c358489 100644 --- a/src/block/BlockTypeIds.php +++ b/src/block/BlockTypeIds.php @@ -745,8 +745,10 @@ final class BlockTypeIds{ public const PITCHER_PLANT = 10715; public const PITCHER_CROP = 10716; public const DOUBLE_PITCHER_CROP = 10717; + public const CAMPFIRE = 10718; + public const SOUL_CAMPFIRE = 10719; - public const FIRST_UNUSED_BLOCK_ID = 10718; + public const FIRST_UNUSED_BLOCK_ID = 10720; private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID; diff --git a/src/block/Campfire.php b/src/block/Campfire.php new file mode 100644 index 000000000..ce759ee87 --- /dev/null +++ b/src/block/Campfire.php @@ -0,0 +1,277 @@ + ticks + * @phpstan-var array + */ + protected array $cookingTimes = []; + + protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{ + $this->encodeFacingState($w); + $this->encodeLitState($w); + } + + public function readStateFromWorld() : Block{ + parent::readStateFromWorld(); + $tile = $this->position->getWorld()->getTile($this->position); + if($tile instanceof TileCampfire){ + $this->inventory = $tile->getInventory(); + $this->cookingTimes = $tile->getCookingTimes(); + }else{ + $this->inventory = new CampfireInventory($this->position); + } + + return $this; + } + + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + $tile = $this->position->getWorld()->getTile($this->position); + if($tile instanceof TileCampfire){ + $tile->setCookingTimes($this->cookingTimes); + } + } + + public function hasEntityCollision() : bool{ + return true; + } + + public function getLightLevel() : int{ + return $this->lit ? 15 : 0; + } + + public function isAffectedBySilkTouch() : bool{ + return true; + } + + public function getDropsForCompatibleTool(Item $item) : array{ + return [ + VanillaItems::CHARCOAL()->setCount(2) + ]; + } + + public function getSupportType(int $facing) : SupportType{ + return SupportType::NONE; + } + + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim(Facing::UP, 9 / 16)]; + } + + public function getInventory() : CampfireInventory{ + return $this->inventory; + } + + protected function getFurnaceType() : FurnaceType{ + return FurnaceType::CAMPFIRE; + } + + protected function getEntityCollisionDamage() : int{ + return 1; + } + + /** + * Sets the number of ticks during the item in the given slot has been cooked. + */ + public function setCookingTime(int $slot, int $time) : void{ + if($slot < 0 || $slot > 3){ + throw new \InvalidArgumentException("Slot must be in range 0-3"); + } + if($time < 0 || $time > $this->getFurnaceType()->getCookDurationTicks()){ + throw new \InvalidArgumentException("CookingTime must be in range 0-" . $this->getFurnaceType()->getCookDurationTicks()); + } + $this->cookingTimes[$slot] = $time; + } + + /** + * Returns the number of ticks during the item in the given slot has been cooked. + */ + public function getCookingTime(int $slot) : int{ + return $this->cookingTimes[$slot] ?? 0; + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($this->getSide(Facing::DOWN) instanceof Campfire){ + return false; + } + if($player !== null){ + $this->facing = $player->getHorizontalFacing(); + } + $this->lit = 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(!$this->lit){ + if($item->getTypeId() === ItemTypeIds::FIRE_CHARGE){ + $item->pop(); + $this->ignite(); + $this->position->getWorld()->addSound($this->position, new BlazeShootSound()); + return true; + }elseif($item->getTypeId() === ItemTypeIds::FLINT_AND_STEEL || $item->hasEnchantment(VanillaEnchantments::FIRE_ASPECT())){ + if($item instanceof Durable){ + $item->applyDamage(1); + } + $this->ignite(); + return true; + } + }elseif($item instanceof Shovel){ + $item->applyDamage(1); + $this->extinguish(); + return true; + } + + if($this->position->getWorld()->getServer()->getCraftingManager()->getFurnaceRecipeManager($this->getFurnaceType())->match($item) !== null){ + $ingredient = clone $item; + $ingredient->setCount(1); + if(count($this->inventory->addItem($ingredient)) === 0){ + $item->pop(); + $this->position->getWorld()->addSound($this->position, new ItemFrameAddItemSound()); + return true; + } + } + return false; + } + + public function onNearbyBlockChange() : void{ + if($this->lit && $this->getSide(Facing::UP)->getTypeId() === BlockTypeIds::WATER){ + $this->extinguish(); + //TODO: Waterlogging + } + } + + public function onEntityInside(Entity $entity) : bool{ + if(!$this->lit){ + if($entity->isOnFire()){ + $this->ignite(); + return false; + } + }elseif($entity instanceof Living){ + $entity->attack(new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, $this->getEntityCollisionDamage())); + } + return true; + } + + public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{ + if($this->lit && $projectile instanceof SplashPotion && $projectile->getPotionType() === PotionType::WATER){ + $this->extinguish(); + } + } + + public function onScheduledUpdate() : void{ + if($this->lit){ + $items = $this->inventory->getContents(); + $furnaceType = $this->getFurnaceType(); + $maxCookDuration = $furnaceType->getCookDurationTicks(); + foreach($items as $slot => $item){ + $this->setCookingTime($slot, min($maxCookDuration, $this->getCookingTime($slot) + self::UPDATE_INTERVAL_TICKS)); + if($this->getCookingTime($slot) >= $maxCookDuration){ + $result = + ($recipe = $this->position->getWorld()->getServer()->getCraftingManager()->getFurnaceRecipeManager($furnaceType)->match($item)) instanceof FurnaceRecipe ? + $recipe->getResult() : + VanillaItems::AIR(); + + $ev = new CampfireCookEvent($this, $slot, $item, $result); + $ev->call(); + + if ($ev->isCancelled()){ + continue; + } + + $this->inventory->setItem($slot, VanillaItems::AIR()); + $this->setCookingTime($slot, 0); + $this->position->getWorld()->dropItem($this->position->add(0.5, 1, 0.5), $ev->getResult()); + } + } + if(count($items) > 0){ + $this->position->getWorld()->setBlock($this->position, $this); + } + if(mt_rand(1, 6) === 1){ + $this->position->getWorld()->addSound($this->position, $furnaceType->getCookSound()); + } + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, self::UPDATE_INTERVAL_TICKS); + } + } + + private function extinguish() : void{ + $this->position->getWorld()->addSound($this->position, new FireExtinguishSound()); + $this->position->getWorld()->setBlock($this->position, $this->setLit(false)); + } + + private function ignite() : void{ + $this->position->getWorld()->addSound($this->position, new FlintSteelSound()); + $this->position->getWorld()->setBlock($this->position, $this->setLit(true)); + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, self::UPDATE_INTERVAL_TICKS); + } +} diff --git a/src/block/SoulCampfire.php b/src/block/SoulCampfire.php new file mode 100644 index 000000000..a9c8fc918 --- /dev/null +++ b/src/block/SoulCampfire.php @@ -0,0 +1,48 @@ +lit ? 10 : 0; + } + + public function getDropsForCompatibleTool(Item $item) : array{ + return [ + VanillaBlocks::SOUL_SOIL()->asItem() + ]; + } + + protected function getEntityCollisionDamage() : int{ + return 2; + } + + protected function getFurnaceType() : FurnaceType{ + return FurnaceType::SOUL_CAMPFIRE; + } +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 9c0e7d3b7..7733f4359 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -36,6 +36,7 @@ use pocketmine\block\tile\Bed as TileBed; use pocketmine\block\tile\Bell as TileBell; use pocketmine\block\tile\BlastFurnace as TileBlastFurnace; use pocketmine\block\tile\BrewingStand as TileBrewingStand; +use pocketmine\block\tile\Campfire as TileCampfire; use pocketmine\block\tile\Cauldron as TileCauldron; use pocketmine\block\tile\Chest as TileChest; use pocketmine\block\tile\ChiseledBookshelf as TileChiseledBookshelf; @@ -154,6 +155,7 @@ use function strtolower; * @method static CakeWithCandle CAKE_WITH_CANDLE() * @method static CakeWithDyedCandle CAKE_WITH_DYED_CANDLE() * @method static Opaque CALCITE() + * @method static Campfire CAMPFIRE() * @method static Candle CANDLE() * @method static Carpet CARPET() * @method static Carrot CARROTS() @@ -685,6 +687,7 @@ use function strtolower; * @method static Slab SMOOTH_STONE_SLAB() * @method static Snow SNOW() * @method static SnowLayer SNOW_LAYER() + * @method static SoulCampfire SOUL_CAMPFIRE() * @method static SoulFire SOUL_FIRE() * @method static Lantern SOUL_LANTERN() * @method static SoulSand SOUL_SAND() @@ -826,6 +829,11 @@ final class VanillaBlocks{ self::register("brown_mushroom", new BrownMushroom(new BID(Ids::BROWN_MUSHROOM), "Brown Mushroom", new Info(BreakInfo::instant(), [Tags::POTTABLE_PLANTS]))); self::register("cactus", new Cactus(new BID(Ids::CACTUS), "Cactus", new Info(new BreakInfo(0.4), [Tags::POTTABLE_PLANTS]))); self::register("cake", new Cake(new BID(Ids::CAKE), "Cake", new Info(new BreakInfo(0.5)))); + + $campfireBreakInfo = new Info(BreakInfo::axe(2.0)); + self::register("campfire", new Campfire(new BID(Ids::CAMPFIRE, TileCampfire::class), "Campfire", $campfireBreakInfo)); + self::register("soul_campfire", new SoulCampfire(new BID(Ids::SOUL_CAMPFIRE, TileCampfire::class), "Soul Campfire", $campfireBreakInfo)); + self::register("carrots", new Carrot(new BID(Ids::CARROTS), "Carrot Block", new Info(BreakInfo::instant()))); $chestBreakInfo = new Info(BreakInfo::axe(2.5)); diff --git a/src/block/inventory/CampfireInventory.php b/src/block/inventory/CampfireInventory.php new file mode 100644 index 000000000..ae762473e --- /dev/null +++ b/src/block/inventory/CampfireInventory.php @@ -0,0 +1,40 @@ +holder = $holder; + parent::__construct(4); + } + + public function getMaxStackSize() : int{ + return 1; + } +} diff --git a/src/block/tile/Campfire.php b/src/block/tile/Campfire.php new file mode 100644 index 000000000..ad4a193d7 --- /dev/null +++ b/src/block/tile/Campfire.php @@ -0,0 +1,143 @@ + */ + private array $cookingTimes = []; + + public function __construct(World $world, Vector3 $pos){ + parent::__construct($world, $pos); + $this->inventory = new CampfireInventory($this->position); + $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange( + static function(Inventory $unused) use ($world, $pos) : void{ + $block = $world->getBlock($pos); + if($block instanceof BlockCampfire){ + $world->setBlock($pos, $block); + } + }) + ); + } + + public function getInventory() : CampfireInventory{ + return $this->inventory; + } + + public function getRealInventory() : CampfireInventory{ + return $this->inventory; + } + + /** + * @return int[] + * @phpstan-return array + */ + public function getCookingTimes() : array{ + return $this->cookingTimes; + } + + /** + * @param int[] $cookingTimes + * @phpstan-param array $cookingTimes + */ + public function setCookingTimes(array $cookingTimes) : void{ + $this->cookingTimes = $cookingTimes; + } + + public function readSaveData(CompoundTag $nbt) : void{ + $items = []; + $listeners = $this->inventory->getListeners()->toArray(); + $this->inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization + + foreach([ + [0, self::TAG_FIRST_INPUT_ITEM, self::TAG_FIRST_COOKING_TIME], + [1, self::TAG_SECOND_INPUT_ITEM, self::TAG_SECOND_COOKING_TIME], + [2, self::TAG_THIRD_INPUT_ITEM, self::TAG_THIRD_COOKING_TIME], + [3, self::TAG_FOURTH_INPUT_ITEM, self::TAG_FOURTH_COOKING_TIME], + ] as [$slot, $itemTag, $cookingTimeTag]){ + if(($tag = $nbt->getTag($itemTag)) instanceof CompoundTag){ + $items[$slot] = Item::nbtDeserialize($tag); + } + if(($tag = $nbt->getTag($cookingTimeTag)) instanceof IntTag){ + $this->cookingTimes[$slot] = $tag->getValue(); + } + } + $this->inventory->setContents($items); + $this->inventory->getListeners()->add(...$listeners); + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + foreach([ + [0, self::TAG_FIRST_INPUT_ITEM, self::TAG_FIRST_COOKING_TIME], + [1, self::TAG_SECOND_INPUT_ITEM, self::TAG_SECOND_COOKING_TIME], + [2, self::TAG_THIRD_INPUT_ITEM, self::TAG_THIRD_COOKING_TIME], + [3, self::TAG_FOURTH_INPUT_ITEM, self::TAG_FOURTH_COOKING_TIME], + ] as [$slot, $itemTag, $cookingTimeTag]){ + $item = $this->inventory->getItem($slot); + if(!$item->isNull()){ + $nbt->setTag($itemTag, $item->nbtSerialize()); + if(isset($this->cookingTimes[$slot])){ + $nbt->setInt($cookingTimeTag, $this->cookingTimes[$slot]); + } + } + } + } + + protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ + foreach([ + 0 => self::TAG_FIRST_INPUT_ITEM, + 1 => self::TAG_SECOND_INPUT_ITEM, + 2 => self::TAG_THIRD_INPUT_ITEM, + 3 => self::TAG_FOURTH_INPUT_ITEM + ] as $slot => $tag){ + $item = $this->inventory->getItem($slot); + if(!$item->isNull()){ + $nbt->setTag($tag, TypeConverter::getInstance()->getItemTranslator()->toNetworkNbt($item)); + } + } + } +} diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 6e87b72ac..515dd8c63 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -57,6 +57,7 @@ final class TileFactory{ $this->register(Bell::class, ["Bell", "minecraft:bell"]); $this->register(BlastFurnace::class, ["BlastFurnace", "minecraft:blast_furnace"]); $this->register(BrewingStand::class, ["BrewingStand", "minecraft:brewing_stand"]); + $this->register(Campfire::class, ["Campfire", "minecraft:campfire"]); $this->register(Cauldron::class, ["Cauldron", "minecraft:cauldron"]); $this->register(Chest::class, ["Chest", "minecraft:chest"]); $this->register(ChiseledBookshelf::class, ["ChiseledBookshelf", "minecraft:chiseled_bookshelf"]); @@ -79,7 +80,6 @@ final class TileFactory{ $this->register(MobHead::class, ["Skull", "minecraft:skull"]); $this->register(GlowingItemFrame::class, ["GlowItemFrame"]); - //TODO: Campfire //TODO: ChalkboardBlock //TODO: ChemistryTable //TODO: CommandBlock diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php index 6e5bbcd1f..616c2a4bd 100644 --- a/src/crafting/CraftingManagerFromDataHelper.php +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -275,7 +275,8 @@ final class CraftingManagerFromDataHelper{ "furnace" => FurnaceType::FURNACE, "blast_furnace" => FurnaceType::BLAST_FURNACE, "smoker" => FurnaceType::SMOKER, - //TODO: campfire + "campfire" => FurnaceType::CAMPFIRE, + "soul_campfire" => FurnaceType::SOUL_CAMPFIRE, default => null }; if($furnaceType === null){ diff --git a/src/crafting/FurnaceType.php b/src/crafting/FurnaceType.php index 0ce5b72ce..89834c821 100644 --- a/src/crafting/FurnaceType.php +++ b/src/crafting/FurnaceType.php @@ -25,6 +25,7 @@ namespace pocketmine\crafting; use pocketmine\utils\LegacyEnumShimTrait; use pocketmine\world\sound\BlastFurnaceSound; +use pocketmine\world\sound\CampfireSound; use pocketmine\world\sound\FurnaceSound; use pocketmine\world\sound\SmokerSound; use pocketmine\world\sound\Sound; @@ -35,8 +36,10 @@ use function spl_object_id; * These are retained for backwards compatibility only. * * @method static FurnaceType BLAST_FURNACE() + * @method static FurnaceType CAMPFIRE() * @method static FurnaceType FURNACE() * @method static FurnaceType SMOKER() + * @method static FurnaceType SOUL_CAMPFIRE() * * @phpstan-type TMetadata array{0: int, 1: Sound} */ @@ -46,6 +49,8 @@ enum FurnaceType{ case FURNACE; case BLAST_FURNACE; case SMOKER; + case CAMPFIRE; + case SOUL_CAMPFIRE; /** * @phpstan-return TMetadata @@ -58,6 +63,7 @@ enum FurnaceType{ self::FURNACE => [200, new FurnaceSound()], self::BLAST_FURNACE => [100, new BlastFurnaceSound()], self::SMOKER => [100, new SmokerSound()], + self::CAMPFIRE, self::SOUL_CAMPFIRE => [600, new CampfireSound()] }; } diff --git a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php index ab98e75f3..a8ca150ba 100644 --- a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php +++ b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php @@ -43,6 +43,7 @@ use pocketmine\block\Cactus; use pocketmine\block\Cake; use pocketmine\block\CakeWithCandle; use pocketmine\block\CakeWithDyedCandle; +use pocketmine\block\Campfire; use pocketmine\block\Candle; use pocketmine\block\Carpet; use pocketmine\block\Carrot; @@ -124,6 +125,7 @@ use pocketmine\block\SimplePressurePlate; use pocketmine\block\Slab; use pocketmine\block\SmallDripleaf; use pocketmine\block\SnowLayer; +use pocketmine\block\SoulCampfire; use pocketmine\block\Sponge; use pocketmine\block\StainedGlass; use pocketmine\block\StainedGlassPane; @@ -1160,6 +1162,11 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ return Writer::create(Ids::CAKE) ->writeInt(StateNames::BITE_COUNTER, $block->getBites()); }); + $this->map(Blocks::CAMPFIRE(), function(Campfire $block) : Writer{ + return Writer::create(Ids::CAMPFIRE) + ->writeCardinalHorizontalFacing($block->getFacing()) + ->writeBool(StateNames::EXTINGUISHED, !$block->isLit()); + }); $this->map(Blocks::CARROTS(), fn(Carrot $block) => Helper::encodeCrops($block, new Writer(Ids::CARROTS))); $this->map(Blocks::CARVED_PUMPKIN(), function(CarvedPumpkin $block) : Writer{ return Writer::create(Ids::CARVED_PUMPKIN) @@ -1638,6 +1645,11 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ->writeBool(StateNames::COVERED_BIT, false) ->writeInt(StateNames::HEIGHT, $block->getLayers() - 1); }); + $this->map(Blocks::SOUL_CAMPFIRE(), function(SoulCampfire $block) : Writer{ + return Writer::create(Ids::SOUL_CAMPFIRE) + ->writeCardinalHorizontalFacing($block->getFacing()) + ->writeBool(StateNames::EXTINGUISHED, !$block->isLit()); + }); $this->map(Blocks::SOUL_FIRE(), function() : Writer{ return Writer::create(Ids::SOUL_FIRE) ->writeInt(StateNames::AGE, 0); //useless for soul fire, we don't track it diff --git a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php index 4c9ec4b79..40478f197 100644 --- a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php +++ b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php @@ -1039,6 +1039,11 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ return Blocks::CAKE() ->setBites($in->readBoundedInt(StateNames::BITE_COUNTER, 0, 6)); }); + $this->map(Ids::CAMPFIRE, function(Reader $in) : Block{ + return Blocks::CAMPFIRE() + ->setFacing($in->readCardinalHorizontalFacing()) + ->setLit(!$in->readBool(StateNames::EXTINGUISHED)); + }); $this->map(Ids::CARROTS, fn(Reader $in) => Helper::decodeCrops(Blocks::CARROTS(), $in)); $this->map(Ids::CARVED_PUMPKIN, function(Reader $in) : Block{ return Blocks::CARVED_PUMPKIN() @@ -1525,6 +1530,11 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $in->ignored(StateNames::COVERED_BIT); //seems to be useless return Blocks::SNOW_LAYER()->setLayers($in->readBoundedInt(StateNames::HEIGHT, 0, 7) + 1); }); + $this->map(Ids::SOUL_CAMPFIRE, function(Reader $in) : Block{ + return Blocks::SOUL_CAMPFIRE() + ->setFacing($in->readCardinalHorizontalFacing()) + ->setLit(!$in->readBool(StateNames::EXTINGUISHED)); + }); $this->map(Ids::SOUL_FIRE, function(Reader $in) : Block{ $in->ignored(StateNames::AGE); //this is useless for soul fire, since it doesn't have the logic associated return Blocks::SOUL_FIRE(); diff --git a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php index 7a720559e..de9b5ae5e 100644 --- a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php +++ b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php @@ -133,6 +133,7 @@ final class ItemSerializerDeserializerRegistrar{ $this->map1to1Block(Ids::BIRCH_DOOR, Blocks::BIRCH_DOOR()); $this->map1to1Block(Ids::BREWING_STAND, Blocks::BREWING_STAND()); $this->map1to1Block(Ids::CAKE, Blocks::CAKE()); + $this->map1to1Block(Ids::CAMPFIRE, Blocks::CAMPFIRE()); $this->map1to1Block(Ids::CAULDRON, Blocks::CAULDRON()); $this->map1to1Block(Ids::CHAIN, Blocks::CHAIN()); $this->map1to1Block(Ids::CHERRY_DOOR, Blocks::CHERRY_DOOR()); @@ -148,6 +149,7 @@ final class ItemSerializerDeserializerRegistrar{ $this->map1to1Block(Ids::MANGROVE_DOOR, Blocks::MANGROVE_DOOR()); $this->map1to1Block(Ids::NETHER_WART, Blocks::NETHER_WART()); $this->map1to1Block(Ids::REPEATER, Blocks::REDSTONE_REPEATER()); + $this->map1to1Block(Ids::SOUL_CAMPFIRE, Blocks::SOUL_CAMPFIRE()); $this->map1to1Block(Ids::SPRUCE_DOOR, Blocks::SPRUCE_DOOR()); $this->map1to1Block(Ids::SUGAR_CANE, Blocks::SUGARCANE()); $this->map1to1Block(Ids::WARPED_DOOR, Blocks::WARPED_DOOR()); diff --git a/src/event/block/CampfireCookEvent.php b/src/event/block/CampfireCookEvent.php new file mode 100644 index 000000000..3762f5848 --- /dev/null +++ b/src/event/block/CampfireCookEvent.php @@ -0,0 +1,63 @@ +input = clone $input; + } + + public function getCampfire() : Campfire{ + return $this->campfire; + } + + public function getSlot() : int{ + return $this->slot; + } + + public function getInput() : Item{ + return $this->input; + } + + public function getResult() : Item{ + return $this->result; + } + + public function setResult(Item $result) : void{ + $this->result = $result; + } +} diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 91fd2ab4a..6a1c1d2e3 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -205,6 +205,7 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("cake", fn() => Blocks::CAKE()); $result->registerBlock("cake_block", fn() => Blocks::CAKE()); $result->registerBlock("calcite", fn() => Blocks::CALCITE()); + $result->registerBlock("campfire", fn() => Blocks::CAMPFIRE()); $result->registerBlock("candle", fn() => Blocks::CANDLE()); $result->registerBlock("carpet", fn() => Blocks::CARPET()); $result->registerBlock("carrot_block", fn() => Blocks::CARROTS()); @@ -1003,6 +1004,7 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("snow", fn() => Blocks::SNOW()); $result->registerBlock("snow_block", fn() => Blocks::SNOW()); $result->registerBlock("snow_layer", fn() => Blocks::SNOW_LAYER()); + $result->registerBlock("soul_campfire", fn() => Blocks::SOUL_CAMPFIRE()); $result->registerBlock("soul_lantern", fn() => Blocks::SOUL_LANTERN()); $result->registerBlock("soul_sand", fn() => Blocks::SOUL_SAND()); $result->registerBlock("soul_soil", fn() => Blocks::SOUL_SOIL()); diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 29f37590e..14523f74c 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -130,6 +130,8 @@ final class CraftingDataCache{ FurnaceType::FURNACE => FurnaceRecipeBlockName::FURNACE, FurnaceType::BLAST_FURNACE => FurnaceRecipeBlockName::BLAST_FURNACE, FurnaceType::SMOKER => FurnaceRecipeBlockName::SMOKER, + FurnaceType::CAMPFIRE => FurnaceRecipeBlockName::CAMPFIRE, + FurnaceType::SOUL_CAMPFIRE => FurnaceRecipeBlockName::SOUL_CAMPFIRE }; foreach($manager->getFurnaceRecipeManager($furnaceType)->getAll() as $recipe){ $input = $converter->coreRecipeIngredientToNet($recipe->getInput())->getDescriptor(); diff --git a/src/world/sound/CampfireSound.php b/src/world/sound/CampfireSound.php new file mode 100644 index 000000000..7e01342ef --- /dev/null +++ b/src/world/sound/CampfireSound.php @@ -0,0 +1,35 @@ + Date: Mon, 8 Jul 2024 03:20:45 +0700 Subject: [PATCH 20/37] Bells always drops themselves (#4802) --- src/block/Bell.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/block/Bell.php b/src/block/Bell.php index ec033cef8..53a6fc7fb 100644 --- a/src/block/Bell.php +++ b/src/block/Bell.php @@ -150,6 +150,10 @@ final class Bell extends Transparent{ } } + public function getDropsForIncompatibleTool(Item $item) : array{ + return [$this->asItem()]; + } + private function isValidFaceToRing(int $faceHit) : bool{ return match($this->attachmentType){ BellAttachmentType::CEILING => true, From 5d60ba36b7ecd9fd1caf79b8cd94e55f72b8c0b0 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 Jul 2024 21:07:47 -0500 Subject: [PATCH 21/37] Support for 1.21.2 --- composer.json | 2 +- composer.lock | 14 +++++++------- src/network/mcpe/NetworkSession.php | 5 +++++ src/player/Player.php | 7 +++++++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index dbc1b1354..299f69f78 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "pocketmine/bedrock-block-upgrade-schema": "~4.2.0+bedrock-1.21.0", "pocketmine/bedrock-data": "~2.11.0+bedrock-1.21.0", "pocketmine/bedrock-item-upgrade-schema": "~1.10.0+bedrock-1.21.0", - "pocketmine/bedrock-protocol": "~31.0.0+bedrock-1.21.0", + "pocketmine/bedrock-protocol": "~32.1.0+bedrock-1.21.2", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/color": "^0.3.0", diff --git a/composer.lock b/composer.lock index ce8d52e26..0547560cc 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": "6254ce9a454f8c9acd4936512c4d315a", + "content-hash": "d459605b85f247204988a879982aab50", "packages": [ { "name": "adhocore/json-comment", @@ -205,16 +205,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "31.0.0+bedrock-1.21.0", + "version": "32.1.0+bedrock-1.21.2", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "972373b6b8068963649f0a95163424eb5b645e29" + "reference": "bb23db51365bdc91d3135c3885986a691ae1cb44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/972373b6b8068963649f0a95163424eb5b645e29", - "reference": "972373b6b8068963649f0a95163424eb5b645e29", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/bb23db51365bdc91d3135c3885986a691ae1cb44", + "reference": "bb23db51365bdc91d3135c3885986a691ae1cb44", "shasum": "" }, "require": { @@ -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/31.0.0+bedrock-1.21.0" + "source": "https://github.com/pmmp/BedrockProtocol/tree/32.1.0+bedrock-1.21.2" }, - "time": "2024-06-13T17:34:14+00:00" + "time": "2024-07-10T01:38:43+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 04cc7b932..218e10253 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -54,6 +54,7 @@ use pocketmine\network\mcpe\handler\SessionStartPacketHandler; use pocketmine\network\mcpe\handler\SpawnResponsePacketHandler; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; +use pocketmine\network\mcpe\protocol\ClientboundCloseFormPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; @@ -1170,6 +1171,10 @@ class NetworkSession{ return $this->sendDataPacket(ModalFormRequestPacket::create($id, json_encode($form, JSON_THROW_ON_ERROR))); } + public function onCloseAllForms() : void{ + $this->sendDataPacket(ClientboundCloseFormPacket::create()); + } + /** * Instructs the networksession to start using the chunk at the given coordinates. This may occur asynchronously. * @param \Closure $onCompletion To be called when chunk sending has completed. diff --git a/src/player/Player.php b/src/player/Player.php index 0cefbe71f..d442c6a3b 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2151,6 +2151,13 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return true; } + /** + * Closes the current viewing form and forms in queue. + */ + public function closeAllForms() : void{ + $this->getNetworkSession()->onCloseAllForms(); + } + /** * Transfers a player to another server. * From 37bf4bc0b0c095758c8ee09e5681a369396da7ce Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 Jul 2024 21:15:18 -0500 Subject: [PATCH 22/37] Release 5.17.0 --- changelogs/5.17.md | 25 +++++++++++++++++++++++++ src/VersionInfo.php | 4 ++-- 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 changelogs/5.17.md diff --git a/changelogs/5.17.md b/changelogs/5.17.md new file mode 100644 index 000000000..1b4084710 --- /dev/null +++ b/changelogs/5.17.md @@ -0,0 +1,25 @@ +# 5.17.0 +Released 10th July 2024. + +**For Minecraft: Bedrock Edition 1.21.2** + +This is a support release for Minecraft: Bedrock Edition 1.21.2. + +**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.2. +- Removed support for earlier versions. + +## API +### `pocketmine\player` +- The following methods have been added: + - `public function closeAllForms() : void` - closes the current viewing form and forms in queue. + +## Fixes +- Bowl can now be used as fuel. +- Bells always drops themselves even when using an incompatible tool. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 9b935f8a0..52a33e39f 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,8 +31,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "5.16.1"; - public const IS_DEVELOPMENT_BUILD = true; + public const BASE_VERSION = "5.17.0"; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_CHANNEL = "stable"; /** From 824e270041af8aaf6c2a767e9ee4a16f9ddaac87 Mon Sep 17 00:00:00 2001 From: IvanCraft623 Date: Tue, 9 Jul 2024 21:16:13 -0500 Subject: [PATCH 23/37] 5.17.1 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 52a33e39f..bc4154e86 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,8 +31,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "5.17.0"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "5.17.1"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "stable"; /** From accaa0acce17f5601a8d3412efac97344f4d7171 Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Wed, 10 Jul 2024 19:15:06 +0300 Subject: [PATCH 24/37] Implement ICopper interface for blocks with common properties (#6390) --- src/block/Copper.php | 3 +- src/block/CopperSlab.php | 3 +- src/block/CopperStairs.php | 3 +- src/block/utils/ICopper.php | 38 +++++++++++++++++++ .../convert/BlockStateDeserializerHelper.php | 12 +++--- 5 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 src/block/utils/ICopper.php diff --git a/src/block/Copper.php b/src/block/Copper.php index 1da253fa4..8e678bf42 100644 --- a/src/block/Copper.php +++ b/src/block/Copper.php @@ -24,7 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\CopperTrait; +use pocketmine\block\utils\ICopper; -class Copper extends Opaque{ +class Copper extends Opaque implements ICopper{ use CopperTrait; } diff --git a/src/block/CopperSlab.php b/src/block/CopperSlab.php index 088ace11e..4194cd854 100644 --- a/src/block/CopperSlab.php +++ b/src/block/CopperSlab.php @@ -24,7 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\CopperTrait; +use pocketmine\block\utils\ICopper; -class CopperSlab extends Slab{ +class CopperSlab extends Slab implements ICopper{ use CopperTrait; } diff --git a/src/block/CopperStairs.php b/src/block/CopperStairs.php index b16d49ec1..dd8f44f7a 100644 --- a/src/block/CopperStairs.php +++ b/src/block/CopperStairs.php @@ -24,7 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\CopperTrait; +use pocketmine\block\utils\ICopper; -class CopperStairs extends Stair{ +class CopperStairs extends Stair implements ICopper{ use CopperTrait; } diff --git a/src/block/utils/ICopper.php b/src/block/utils/ICopper.php new file mode 100644 index 000000000..a749efe63 --- /dev/null +++ b/src/block/utils/ICopper.php @@ -0,0 +1,38 @@ +setOxidation($oxidation); $block->setWaxed(false); return $block; } /** - * @phpstan-template TBlock of Copper|CopperSlab|CopperStairs + * @phpstan-template TBlock of ICopper * * @phpstan-param TBlock $block * @phpstan-return TBlock */ - public static function decodeWaxedCopper(Copper|CopperSlab|CopperStairs $block, CopperOxidation $oxidation) : Copper|CopperSlab|CopperStairs{ + public static function decodeWaxedCopper(ICopper $block, CopperOxidation $oxidation) : ICopper{ $block->setOxidation($oxidation); $block->setWaxed(true); return $block; From 85606925a1b9f747cc65357a1fc5e314503486d2 Mon Sep 17 00:00:00 2001 From: Dylan T <14214667+dktapps@users.noreply.github.com> Date: Fri, 12 Jul 2024 11:26:51 +0100 Subject: [PATCH 25/37] BlockStateData: add a note about CURRENT_VERSION this is not the same as current game version, as the revision is determined by some Mojang internal factors. --- src/data/bedrock/block/BlockStateData.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/data/bedrock/block/BlockStateData.php b/src/data/bedrock/block/BlockStateData.php index 51899b72b..2c67ded73 100644 --- a/src/data/bedrock/block/BlockStateData.php +++ b/src/data/bedrock/block/BlockStateData.php @@ -38,6 +38,9 @@ use function implode; final class BlockStateData{ /** * Bedrock version of the most recent backwards-incompatible change to blockstates. + * + * This is *not* the same as current game version. It should match the numbers in the + * newest blockstate upgrade schema used in BedrockBlockUpgradeSchema. */ public const CURRENT_VERSION = (1 << 24) | //major From d6c48fd3a22b8dae0e2d2a5f1f920a40c2abd837 Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Fri, 12 Jul 2024 07:24:43 -0500 Subject: [PATCH 26/37] Implement new 1.21 paintings (#6393) --- src/entity/object/PaintingMotive.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/entity/object/PaintingMotive.php b/src/entity/object/PaintingMotive.php index a456630fc..00114c508 100644 --- a/src/entity/object/PaintingMotive.php +++ b/src/entity/object/PaintingMotive.php @@ -37,9 +37,11 @@ class PaintingMotive{ new PaintingMotive(1, 1, "Aztec2"), new PaintingMotive(1, 1, "Bomb"), new PaintingMotive(1, 1, "Kebab"), + new PaintingMotive(1, 1, "meditative"), new PaintingMotive(1, 1, "Plant"), new PaintingMotive(1, 1, "Wasteland"), new PaintingMotive(1, 2, "Graham"), + new PaintingMotive(1, 2, "prairie_ride"), new PaintingMotive(1, 2, "Wanderer"), new PaintingMotive(2, 1, "Courbet"), new PaintingMotive(2, 1, "Creebet"), @@ -47,8 +49,10 @@ class PaintingMotive{ new PaintingMotive(2, 1, "Sea"), new PaintingMotive(2, 1, "Sunset"), new PaintingMotive(2, 2, "Bust"), + new PaintingMotive(2, 2, "baroque"), new PaintingMotive(2, 2, "Earth"), new PaintingMotive(2, 2, "Fire"), + new PaintingMotive(2, 2, "humble"), new PaintingMotive(2, 2, "Match"), new PaintingMotive(2, 2, "SkullAndRoses"), new PaintingMotive(2, 2, "Stage"), @@ -56,12 +60,28 @@ class PaintingMotive{ new PaintingMotive(2, 2, "Water"), new PaintingMotive(2, 2, "Wind"), new PaintingMotive(2, 2, "Wither"), + new PaintingMotive(3, 3, "bouquet"), + new PaintingMotive(3, 3, "cavebird"), + new PaintingMotive(3, 3, "cotan"), + new PaintingMotive(3, 3, "endboss"), + new PaintingMotive(3, 3, "fern"), + new PaintingMotive(3, 3, "owlemons"), + new PaintingMotive(3, 3, "sunflowers"), + new PaintingMotive(3, 3, "tides"), + new PaintingMotive(3, 4, "backyard"), + new PaintingMotive(3, 4, "pond"), + new PaintingMotive(4, 2, "changing"), new PaintingMotive(4, 2, "Fighters"), + new PaintingMotive(4, 2, "finding"), + new PaintingMotive(4, 2, "lowmist"), + new PaintingMotive(4, 2, "passage"), new PaintingMotive(4, 3, "DonkeyKong"), new PaintingMotive(4, 3, "Skeleton"), new PaintingMotive(4, 4, "BurningSkull"), + new PaintingMotive(4, 4, "orb"), new PaintingMotive(4, 4, "Pigscene"), - new PaintingMotive(4, 4, "Pointer") + new PaintingMotive(4, 4, "Pointer"), + new PaintingMotive(4, 4, "unpacked") ] as $motive){ self::registerMotive($motive); } From 786d84a9e1af79e7b9114fe1d6725bb291408534 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jul 2024 12:43:18 +0000 Subject: [PATCH 27/37] Bump shivammathur/setup-php from 2.30.4 to 2.31.1 Bumps [shivammathur/setup-php](https://github.com/shivammathur/setup-php) from 2.30.4 to 2.31.1. - [Release notes](https://github.com/shivammathur/setup-php/releases) - [Commits](https://github.com/shivammathur/setup-php/compare/2.30.4...2.31.1) --- updated-dependencies: - dependency-name: shivammathur/setup-php dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/discord-release-notify.yml | 2 +- .github/workflows/draft-release.yml | 2 +- .github/workflows/main.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/discord-release-notify.yml b/.github/workflows/discord-release-notify.yml index ce8a16ebc..8d0add224 100644 --- a/.github/workflows/discord-release-notify.yml +++ b/.github/workflows/discord-release-notify.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup PHP and tools - uses: shivammathur/setup-php@2.30.4 + uses: shivammathur/setup-php@2.31.1 with: php-version: 8.2 diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index 311e0c827..c47a4399b 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -20,7 +20,7 @@ jobs: submodules: true - name: Setup PHP - uses: shivammathur/setup-php@2.30.4 + uses: shivammathur/setup-php@2.31.1 with: php-version: ${{ matrix.php-version }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 92bd7171b..7c92c0b8b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup PHP and tools - uses: shivammathur/setup-php@2.30.4 + uses: shivammathur/setup-php@2.31.1 with: php-version: 8.2 tools: php-cs-fixer:3.49 From f750b01d8be7bc97e1c340b0450240c36520747e Mon Sep 17 00:00:00 2001 From: Dylan T <14214667+dktapps@users.noreply.github.com> Date: Fri, 12 Jul 2024 14:10:14 +0100 Subject: [PATCH 28/37] dependabot: group patch updates into a single PR --- .github/dependabot.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8acff71d6..39d5c68b8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,6 +12,19 @@ updates: update-types: - "version-update:semver-major" - "version-update:semver-minor" + groups: + production-patch-updates: + dependency-type: production + patterns: + - "*" + update-types: + - "patch" + development-patch-updates: + dependency-type: development + patterns: + - "*" + update-types: + - "patch" - package-ecosystem: gitsubmodule directory: "/" From 32be474840630667785b1a5823b41d40e783598a Mon Sep 17 00:00:00 2001 From: Dylan T <14214667+dktapps@users.noreply.github.com> Date: Fri, 12 Jul 2024 14:12:47 +0100 Subject: [PATCH 29/37] dependabot: group PHPStan dependency updates always these typically need to be updated together anyway --- .github/dependabot.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 39d5c68b8..97607ab8f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -25,6 +25,9 @@ updates: - "*" update-types: - "patch" + phpstan: + patterns: + - "phpstan/*" - package-ecosystem: gitsubmodule directory: "/" From 1f510caf88271f25f6e944919cd3bd04c00ad96a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:16:44 +0000 Subject: [PATCH 30/37] Bump the phpstan group with 2 updates (#6401) --- composer.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/composer.lock b/composer.lock index 0547560cc..a68d34533 100644 --- a/composer.lock +++ b/composer.lock @@ -1447,21 +1447,21 @@ }, { "name": "phpstan/phpstan-phpunit", - "version": "1.3.16", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "d5242a59d035e46774f2e634b374bc39ff62cb95" + "reference": "f3ea021866f4263f07ca3636bf22c64be9610c11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/d5242a59d035e46774f2e634b374bc39ff62cb95", - "reference": "d5242a59d035e46774f2e634b374bc39ff62cb95", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/f3ea021866f4263f07ca3636bf22c64be9610c11", + "reference": "f3ea021866f4263f07ca3636bf22c64be9610c11", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10" + "phpstan/phpstan": "^1.11" }, "conflict": { "phpunit/phpunit": "<7.0" @@ -1493,27 +1493,27 @@ "description": "PHPUnit extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-phpunit/issues", - "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.16" + "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.4.0" }, - "time": "2024-02-23T09:51:20+00:00" + "time": "2024-04-20T06:39:00+00:00" }, { "name": "phpstan/phpstan-strict-rules", - "version": "1.5.5", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "2e193a07651a6f4be3baa44ddb21d822681f5918" + "reference": "363f921dd8441777d4fc137deb99beb486c77df1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/2e193a07651a6f4be3baa44ddb21d822681f5918", - "reference": "2e193a07651a6f4be3baa44ddb21d822681f5918", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/363f921dd8441777d4fc137deb99beb486c77df1", + "reference": "363f921dd8441777d4fc137deb99beb486c77df1", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10.60" + "phpstan/phpstan": "^1.11" }, "require-dev": { "nikic/php-parser": "^4.13.0", @@ -1542,9 +1542,9 @@ "description": "Extra strict and opinionated rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", - "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.5" + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.6.0" }, - "time": "2024-04-19T15:12:26+00:00" + "time": "2024-04-20T06:37:51+00:00" }, { "name": "phpunit/php-code-coverage", From a96f1a5083ae6a281736194a3ba70f88ceaae94e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 14 Jul 2024 18:17:41 +0000 Subject: [PATCH 31/37] Bump docker/build-push-action from 5.3.0 to 6.3.0 (#6387) --- .github/workflows/build-docker-image.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 6e035e735..c6d6fb896 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@v5.3.0 + uses: docker/build-push-action@v6.3.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@v5.3.0 + uses: docker/build-push-action@v6.3.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@v5.3.0 + uses: docker/build-push-action@v6.3.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@v5.3.0 + uses: docker/build-push-action@v6.3.0 with: push: true context: ./pocketmine-mp From df4ada81e5d74a14046f27cf44a37dcee69d657e Mon Sep 17 00:00:00 2001 From: Aleksey <45711510+Gaprix@users.noreply.github.com> Date: Tue, 16 Jul 2024 08:51:06 +0300 Subject: [PATCH 32/37] BedrockWorldData: Update version constants to 1.21.2 (#6399) Co-authored-by: Dylan T <14214667+dktapps@users.noreply.github.com> --- src/world/format/io/data/BedrockWorldData.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 9dc89ad99..7bcc44c0b 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 = 685; + public const CURRENT_STORAGE_NETWORK_VERSION = 686; public const CURRENT_CLIENT_VERSION_TARGET = [ 1, //major 21, //minor - 0, //patch - 3, //revision + 2, //patch + 2, //revision 0 //is beta ]; From 787afb6b0007c919f22bd5b955973e3de13223a7 Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Tue, 23 Jul 2024 11:34:46 -0500 Subject: [PATCH 33/37] Implement all new 1.21 tuff blocks (#6391) --- src/block/BlockTypeIds.php | 15 +++++++- src/block/VanillaBlocks.php | 36 ++++++++++++++++++- .../convert/BlockObjectToStateSerializer.php | 13 +++++++ .../BlockStateToObjectDeserializer.php | 13 +++++++ src/item/StringToItemParser.php | 13 +++++++ .../block_factory_consistency_check.json | 13 +++++++ 6 files changed, 101 insertions(+), 2 deletions(-) diff --git a/src/block/BlockTypeIds.php b/src/block/BlockTypeIds.php index 59c358489..29f4e650d 100644 --- a/src/block/BlockTypeIds.php +++ b/src/block/BlockTypeIds.php @@ -747,8 +747,21 @@ final class BlockTypeIds{ public const DOUBLE_PITCHER_CROP = 10717; public const CAMPFIRE = 10718; public const SOUL_CAMPFIRE = 10719; + public const TUFF_SLAB = 10720; + public const TUFF_STAIRS = 10721; + public const TUFF_WALL = 10722; + public const CHISELED_TUFF = 10723; + public const TUFF_BRICKS = 10724; + public const TUFF_BRICK_SLAB = 10725; + public const TUFF_BRICK_STAIRS = 10726; + public const TUFF_BRICK_WALL = 10727; + public const CHISELED_TUFF_BRICKS = 10728; + public const POLISHED_TUFF = 10729; + public const POLISHED_TUFF_SLAB = 10730; + public const POLISHED_TUFF_STAIRS = 10731; + public const POLISHED_TUFF_WALL = 10732; - public const FIRST_UNUSED_BLOCK_ID = 10720; + public const FIRST_UNUSED_BLOCK_ID = 10733; private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID; diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 7733f4359..13c7e869a 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -188,6 +188,8 @@ use function strtolower; * @method static Opaque CHISELED_RED_SANDSTONE() * @method static Opaque CHISELED_SANDSTONE() * @method static Opaque CHISELED_STONE_BRICKS() + * @method static Opaque CHISELED_TUFF() + * @method static Opaque CHISELED_TUFF_BRICKS() * @method static ChorusFlower CHORUS_FLOWER() * @method static ChorusPlant CHORUS_PLANT() * @method static Clay CLAY() @@ -609,6 +611,10 @@ use function strtolower; * @method static Opaque POLISHED_GRANITE() * @method static Slab POLISHED_GRANITE_SLAB() * @method static Stair POLISHED_GRANITE_STAIRS() + * @method static Opaque POLISHED_TUFF() + * @method static Slab POLISHED_TUFF_SLAB() + * @method static Stair POLISHED_TUFF_STAIRS() + * @method static Wall POLISHED_TUFF_WALL() * @method static Flower POPPY() * @method static Potato POTATOES() * @method static PotionCauldron POTION_CAULDRON() @@ -738,6 +744,13 @@ use function strtolower; * @method static Tripwire TRIPWIRE() * @method static TripwireHook TRIPWIRE_HOOK() * @method static Opaque TUFF() + * @method static Opaque TUFF_BRICKS() + * @method static Slab TUFF_BRICK_SLAB() + * @method static Stair TUFF_BRICK_STAIRS() + * @method static Wall TUFF_BRICK_WALL() + * @method static Slab TUFF_SLAB() + * @method static Stair TUFF_STAIRS() + * @method static Wall TUFF_WALL() * @method static NetherVines TWISTING_VINES() * @method static UnderwaterTorch UNDERWATER_TORCH() * @method static Vine VINES() @@ -1269,6 +1282,7 @@ final class VanillaBlocks{ self::registerBlocksR17(); self::registerBlocksR18(); self::registerMudBlocks(); + self::registerTuffBlocks(); self::registerCraftingTables(); self::registerChorusBlocks(); @@ -1576,7 +1590,6 @@ final class VanillaBlocks{ self::register("amethyst_cluster", new AmethystCluster(new BID(Ids::AMETHYST_CLUSTER), "Amethyst Cluster", $amethystInfo)); self::register("calcite", new Opaque(new BID(Ids::CALCITE), "Calcite", new Info(BreakInfo::pickaxe(0.75, ToolTier::WOOD)))); - self::register("tuff", new Opaque(new BID(Ids::TUFF), "Tuff", new Info(BreakInfo::pickaxe(1.5, ToolTier::WOOD, 30.0)))); self::register("raw_copper", new Opaque(new BID(Ids::RAW_COPPER), "Raw Copper Block", new Info(BreakInfo::pickaxe(5, ToolTier::STONE, 30.0)))); self::register("raw_gold", new Opaque(new BID(Ids::RAW_GOLD), "Raw Gold Block", new Info(BreakInfo::pickaxe(5, ToolTier::IRON, 30.0)))); @@ -1667,6 +1680,27 @@ final class VanillaBlocks{ self::register("mud_brick_wall", new Wall(new BID(Ids::MUD_BRICK_WALL), "Mud Brick Wall", $mudBricksBreakInfo)); } + private static function registerTuffBlocks() : void{ + $tuffBreakInfo = new Info(BreakInfo::pickaxe(1.5, ToolTier::WOOD, 30.0)); + + self::register("tuff", new Opaque(new BID(Ids::TUFF), "Tuff", $tuffBreakInfo)); + self::register("tuff_slab", new Slab(new BID(Ids::TUFF_SLAB), "Tuff", $tuffBreakInfo)); + self::register("tuff_stairs", new Stair(new BID(Ids::TUFF_STAIRS), "Tuff Stairs", $tuffBreakInfo)); + self::register("tuff_wall", new Wall(new BID(Ids::TUFF_WALL), "Tuff Wall", $tuffBreakInfo)); + self::register("chiseled_tuff", new Opaque(new BID(Ids::CHISELED_TUFF), "Chiseled Tuff", $tuffBreakInfo)); + + self::register("tuff_bricks", new Opaque(new BID(Ids::TUFF_BRICKS), "Tuff Bricks", $tuffBreakInfo)); + self::register("tuff_brick_slab", new Slab(new BID(Ids::TUFF_BRICK_SLAB), "Tuff Brick", $tuffBreakInfo)); + self::register("tuff_brick_stairs", new Stair(new BID(Ids::TUFF_BRICK_STAIRS), "Tuff Brick Stairs", $tuffBreakInfo)); + self::register("tuff_brick_wall", new Wall(new BID(Ids::TUFF_BRICK_WALL), "Tuff Brick Wall", $tuffBreakInfo)); + self::register("chiseled_tuff_bricks", new Opaque(new BID(Ids::CHISELED_TUFF_BRICKS), "Chiseled Tuff Bricks", $tuffBreakInfo)); + + self::register("polished_tuff", new Opaque(new BID(Ids::POLISHED_TUFF), "Polished Tuff", $tuffBreakInfo)); + self::register("polished_tuff_slab", new Slab(new BID(Ids::POLISHED_TUFF_SLAB), "Polished Tuff", $tuffBreakInfo)); + self::register("polished_tuff_stairs", new Stair(new BID(Ids::POLISHED_TUFF_STAIRS), "Polished Tuff Stairs", $tuffBreakInfo)); + self::register("polished_tuff_wall", new Wall(new BID(Ids::POLISHED_TUFF_WALL), "Polished Tuff Wall", $tuffBreakInfo)); + } + private static function registerCauldronBlocks() : void{ $cauldronBreakInfo = new Info(BreakInfo::pickaxe(2, ToolTier::WOOD)); diff --git a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php index a8ca150ba..1d271b7a5 100644 --- a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php +++ b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php @@ -785,6 +785,8 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->mapSimple(Blocks::CHISELED_DEEPSLATE(), Ids::CHISELED_DEEPSLATE); $this->mapSimple(Blocks::CHISELED_NETHER_BRICKS(), Ids::CHISELED_NETHER_BRICKS); $this->mapSimple(Blocks::CHISELED_POLISHED_BLACKSTONE(), Ids::CHISELED_POLISHED_BLACKSTONE); + $this->mapSimple(Blocks::CHISELED_TUFF(), Ids::CHISELED_TUFF); + $this->mapSimple(Blocks::CHISELED_TUFF_BRICKS(), Ids::CHISELED_TUFF_BRICKS); $this->mapSimple(Blocks::CHORUS_PLANT(), Ids::CHORUS_PLANT); $this->mapSimple(Blocks::CLAY(), Ids::CLAY); $this->mapSimple(Blocks::COAL(), Ids::COAL_BLOCK); @@ -997,6 +999,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->mapSimple(Blocks::POLISHED_DEEPSLATE(), Ids::POLISHED_DEEPSLATE); $this->mapSimple(Blocks::POLISHED_DIORITE(), Ids::POLISHED_DIORITE); $this->mapSimple(Blocks::POLISHED_GRANITE(), Ids::POLISHED_GRANITE); + $this->mapSimple(Blocks::POLISHED_TUFF(), Ids::POLISHED_TUFF); $this->mapSimple(Blocks::QUARTZ_BRICKS(), Ids::QUARTZ_BRICKS); $this->mapSimple(Blocks::RAW_COPPER(), Ids::RAW_COPPER_BLOCK); $this->mapSimple(Blocks::RAW_GOLD(), Ids::RAW_GOLD_BLOCK); @@ -1023,6 +1026,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->mapSimple(Blocks::TINTED_GLASS(), Ids::TINTED_GLASS); $this->mapSimple(Blocks::TORCHFLOWER(), Ids::TORCHFLOWER); $this->mapSimple(Blocks::TUFF(), Ids::TUFF); + $this->mapSimple(Blocks::TUFF_BRICKS(), Ids::TUFF_BRICKS); $this->mapSimple(Blocks::WARPED_WART_BLOCK(), Ids::WARPED_WART_BLOCK); $this->mapSimple(Blocks::WARPED_ROOTS(), Ids::WARPED_ROOTS); $this->mapSimple(Blocks::WITHER_ROSE(), Ids::WITHER_ROSE); @@ -1539,6 +1543,9 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ $this->mapStairs(Blocks::POLISHED_DIORITE_STAIRS(), Ids::POLISHED_DIORITE_STAIRS); $this->map(Blocks::POLISHED_GRANITE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab3($block, StringValues::STONE_SLAB_TYPE_3_POLISHED_GRANITE)); $this->mapStairs(Blocks::POLISHED_GRANITE_STAIRS(), Ids::POLISHED_GRANITE_STAIRS); + $this->mapSlab(Blocks::POLISHED_TUFF_SLAB(), Ids::POLISHED_TUFF_SLAB, Ids::POLISHED_TUFF_DOUBLE_SLAB); + $this->mapStairs(Blocks::POLISHED_TUFF_STAIRS(), Ids::POLISHED_TUFF_STAIRS); + $this->map(Blocks::POLISHED_TUFF_WALL(), fn(Wall $block) => Helper::encodeWall($block, new Writer(Ids::POLISHED_TUFF_WALL))); $this->map(Blocks::POTATOES(), fn(Potato $block) => Helper::encodeCrops($block, new Writer(Ids::POTATOES))); $this->map(Blocks::POWERED_RAIL(), function(PoweredRail $block) : Writer{ return Writer::create(Ids::GOLDEN_RAIL) @@ -1715,6 +1722,12 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ->writeBool(StateNames::POWERED_BIT, $block->isPowered()) ->writeLegacyHorizontalFacing($block->getFacing()); }); + $this->mapSlab(Blocks::TUFF_BRICK_SLAB(), Ids::TUFF_BRICK_SLAB, Ids::TUFF_BRICK_DOUBLE_SLAB); + $this->mapStairs(Blocks::TUFF_BRICK_STAIRS(), Ids::TUFF_BRICK_STAIRS); + $this->map(Blocks::TUFF_BRICK_WALL(), fn(Wall $block) => Helper::encodeWall($block, new Writer(Ids::TUFF_BRICK_WALL))); + $this->mapSlab(Blocks::TUFF_SLAB(), Ids::TUFF_SLAB, Ids::TUFF_DOUBLE_SLAB); + $this->mapStairs(Blocks::TUFF_STAIRS(), Ids::TUFF_STAIRS); + $this->map(Blocks::TUFF_WALL(), fn(Wall $block) => Helper::encodeWall($block, new Writer(Ids::TUFF_WALL))); $this->map(Blocks::TWISTING_VINES(), function(NetherVines $block) : Writer{ return Writer::create(Ids::TWISTING_VINES) ->writeInt(StateNames::TWISTING_VINES_AGE, $block->getAge()); diff --git a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php index 40478f197..afe0fc225 100644 --- a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php +++ b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php @@ -673,6 +673,8 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->mapSimple(Ids::CHISELED_DEEPSLATE, fn() => Blocks::CHISELED_DEEPSLATE()); $this->mapSimple(Ids::CHISELED_NETHER_BRICKS, fn() => Blocks::CHISELED_NETHER_BRICKS()); $this->mapSimple(Ids::CHISELED_POLISHED_BLACKSTONE, fn() => Blocks::CHISELED_POLISHED_BLACKSTONE()); + $this->mapSimple(Ids::CHISELED_TUFF, fn() => Blocks::CHISELED_TUFF()); + $this->mapSimple(Ids::CHISELED_TUFF_BRICKS, fn() => Blocks::CHISELED_TUFF_BRICKS()); $this->mapSimple(Ids::CHORUS_PLANT, fn() => Blocks::CHORUS_PLANT()); $this->mapSimple(Ids::CLAY, fn() => Blocks::CLAY()); $this->mapSimple(Ids::COAL_BLOCK, fn() => Blocks::COAL()); @@ -880,6 +882,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->mapSimple(Ids::POLISHED_DEEPSLATE, fn() => Blocks::POLISHED_DEEPSLATE()); $this->mapSimple(Ids::POLISHED_DIORITE, fn() => Blocks::POLISHED_DIORITE()); $this->mapSimple(Ids::POLISHED_GRANITE, fn() => Blocks::POLISHED_GRANITE()); + $this->mapSimple(Ids::POLISHED_TUFF, fn() => Blocks::POLISHED_TUFF()); $this->mapSimple(Ids::QUARTZ_BRICKS, fn() => Blocks::QUARTZ_BRICKS()); $this->mapSimple(Ids::QUARTZ_ORE, fn() => Blocks::NETHER_QUARTZ_ORE()); $this->mapSimple(Ids::RAW_COPPER_BLOCK, fn() => Blocks::RAW_COPPER()); @@ -907,6 +910,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->mapSimple(Ids::TINTED_GLASS, fn() => Blocks::TINTED_GLASS()); $this->mapSimple(Ids::TORCHFLOWER, fn() => Blocks::TORCHFLOWER()); $this->mapSimple(Ids::TUFF, fn() => Blocks::TUFF()); + $this->mapSimple(Ids::TUFF_BRICKS, fn() => Blocks::TUFF_BRICKS()); $this->mapSimple(Ids::UNDYED_SHULKER_BOX, fn() => Blocks::SHULKER_BOX()); $this->mapSimple(Ids::WARPED_WART_BLOCK, fn() => Blocks::WARPED_WART_BLOCK()); $this->mapSimple(Ids::WARPED_ROOTS, fn() => Blocks::WARPED_ROOTS()); @@ -1385,6 +1389,9 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->map(Ids::POLISHED_DEEPSLATE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::POLISHED_DEEPSLATE_WALL(), $in)); $this->mapStairs(Ids::POLISHED_DIORITE_STAIRS, fn() => Blocks::POLISHED_DIORITE_STAIRS()); $this->mapStairs(Ids::POLISHED_GRANITE_STAIRS, fn() => Blocks::POLISHED_GRANITE_STAIRS()); + $this->mapSlab(Ids::POLISHED_TUFF_SLAB, Ids::POLISHED_TUFF_DOUBLE_SLAB, fn() => Blocks::POLISHED_TUFF_SLAB()); + $this->mapStairs(Ids::POLISHED_TUFF_STAIRS, fn() => Blocks::POLISHED_TUFF_STAIRS()); + $this->map(Ids::POLISHED_TUFF_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::POLISHED_TUFF_WALL(), $in)); $this->map(Ids::PORTAL, function(Reader $in) : Block{ return Blocks::NETHER_PORTAL() ->setAxis(match($value = $in->readString(StateNames::PORTAL_AXIS)){ @@ -1628,6 +1635,12 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ ->setFacing($in->readLegacyHorizontalFacing()) ->setPowered($in->readBool(StateNames::POWERED_BIT)); }); + $this->mapSlab(Ids::TUFF_BRICK_SLAB, Ids::TUFF_BRICK_DOUBLE_SLAB, fn() => Blocks::TUFF_BRICK_SLAB()); + $this->mapStairs(Ids::TUFF_BRICK_STAIRS, fn() => Blocks::TUFF_BRICK_STAIRS()); + $this->map(Ids::TUFF_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::TUFF_BRICK_WALL(), $in)); + $this->mapSlab(Ids::TUFF_SLAB, Ids::TUFF_DOUBLE_SLAB, fn() => Blocks::TUFF_SLAB()); + $this->mapStairs(Ids::TUFF_STAIRS, fn() => Blocks::TUFF_STAIRS()); + $this->map(Ids::TUFF_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::TUFF_WALL(), $in)); $this->map(Ids::TWISTING_VINES, function(Reader $in) : Block{ return Blocks::TWISTING_VINES() ->setAge($in->readBoundedInt(StateNames::TWISTING_VINES_AGE, 0, 25)); diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 6a1c1d2e3..9f5db6950 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -240,6 +240,8 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("chiseled_red_sandstone", fn() => Blocks::CHISELED_RED_SANDSTONE()); $result->registerBlock("chiseled_sandstone", fn() => Blocks::CHISELED_SANDSTONE()); $result->registerBlock("chiseled_stone_bricks", fn() => Blocks::CHISELED_STONE_BRICKS()); + $result->registerBlock("chiseled_tuff", fn() => Blocks::CHISELED_TUFF()); + $result->registerBlock("chiseled_tuff_bricks", fn() => Blocks::CHISELED_TUFF_BRICKS()); $result->registerBlock("chorus_flower", fn() => Blocks::CHORUS_FLOWER()); $result->registerBlock("chorus_plant", fn() => Blocks::CHORUS_PLANT()); $result->registerBlock("clay_block", fn() => Blocks::CLAY()); @@ -898,6 +900,10 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("polished_granite", fn() => Blocks::POLISHED_GRANITE()); $result->registerBlock("polished_granite_slab", fn() => Blocks::POLISHED_GRANITE_SLAB()); $result->registerBlock("polished_granite_stairs", fn() => Blocks::POLISHED_GRANITE_STAIRS()); + $result->registerBlock("polished_tuff", fn() => Blocks::POLISHED_TUFF()); + $result->registerBlock("polished_tuff_slab", fn() => Blocks::POLISHED_TUFF_SLAB()); + $result->registerBlock("polished_tuff_stairs", fn() => Blocks::POLISHED_TUFF_STAIRS()); + $result->registerBlock("polished_tuff_wall", fn() => Blocks::POLISHED_TUFF_WALL()); $result->registerBlock("poppy", fn() => Blocks::POPPY()); $result->registerBlock("portal", fn() => Blocks::NETHER_PORTAL()); $result->registerBlock("portal_block", fn() => Blocks::NETHER_PORTAL()); @@ -1098,6 +1104,13 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("trunk", fn() => Blocks::OAK_PLANKS()); $result->registerBlock("trunk2", fn() => Blocks::ACACIA_LOG()->setStripped(false)); $result->registerBlock("tuff", fn() => Blocks::TUFF()); + $result->registerBlock("tuff_bricks", fn() => Blocks::TUFF_BRICKS()); + $result->registerBlock("tuff_brick_slab", fn() => Blocks::TUFF_BRICK_SLAB()); + $result->registerBlock("tuff_brick_stairs", fn() => Blocks::TUFF_BRICK_STAIRS()); + $result->registerBlock("tuff_brick_wall", fn() => Blocks::TUFF_BRICK_WALL()); + $result->registerBlock("tuff_slab", fn() => Blocks::TUFF_SLAB()); + $result->registerBlock("tuff_stairs", fn() => Blocks::TUFF_STAIRS()); + $result->registerBlock("tuff_wall", fn() => Blocks::TUFF_WALL()); $result->registerBlock("twisting_vines", fn() => Blocks::TWISTING_VINES()); $result->registerBlock("underwater_tnt", fn() => Blocks::TNT()->setWorksUnderwater(true)); $result->registerBlock("underwater_torch", fn() => Blocks::UNDERWATER_TORCH()); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index b40bfa9e3..97c24b52e 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -112,6 +112,8 @@ "CHISELED_RED_SANDSTONE": 1, "CHISELED_SANDSTONE": 1, "CHISELED_STONE_BRICKS": 1, + "CHISELED_TUFF": 1, + "CHISELED_TUFF_BRICKS": 1, "CHORUS_FLOWER": 6, "CHORUS_PLANT": 1, "CLAY": 1, @@ -533,6 +535,10 @@ "POLISHED_GRANITE": 1, "POLISHED_GRANITE_SLAB": 3, "POLISHED_GRANITE_STAIRS": 8, + "POLISHED_TUFF": 1, + "POLISHED_TUFF_SLAB": 3, + "POLISHED_TUFF_STAIRS": 8, + "POLISHED_TUFF_WALL": 162, "POPPY": 1, "POTATOES": 8, "POTION_CAULDRON": 6, @@ -662,6 +668,13 @@ "TRIPWIRE": 16, "TRIPWIRE_HOOK": 16, "TUFF": 1, + "TUFF_BRICKS": 1, + "TUFF_BRICK_SLAB": 3, + "TUFF_BRICK_STAIRS": 8, + "TUFF_BRICK_WALL": 162, + "TUFF_SLAB": 3, + "TUFF_STAIRS": 8, + "TUFF_WALL": 162, "TWISTING_VINES": 26, "UNDERWATER_TORCH": 5, "VINES": 16, From 237677c0286238a65c42082fbbf3148f4cb1e0bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 06:47:56 +0000 Subject: [PATCH 34/37] Bump phpstan/phpstan from 1.11.2 to 1.11.8 in the development-patch-updates group (#6410) --- composer.json | 2 +- composer.lock | 12 ++++++------ src/resourcepacks/ResourcePack.php | 2 ++ src/resourcepacks/ZippedResourcePack.php | 3 +++ .../format/io/region/RegionLocationTableEntry.php | 4 ++++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 299f69f78..d035ff935 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "symfony/filesystem": "~6.4.0" }, "require-dev": { - "phpstan/phpstan": "1.11.2", + "phpstan/phpstan": "1.11.8", "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 a68d34533..7cc34ff98 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": "d459605b85f247204988a879982aab50", + "content-hash": "3ee9506c0be6b8b202d790824344e79c", "packages": [ { "name": "adhocore/json-comment", @@ -1389,16 +1389,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.2", + "version": "1.11.8", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0d5d4294a70deb7547db655c47685d680e39cfec" + "reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d5d4294a70deb7547db655c47685d680e39cfec", - "reference": "0d5d4294a70deb7547db655c47685d680e39cfec", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", + "reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", "shasum": "" }, "require": { @@ -1443,7 +1443,7 @@ "type": "github" } ], - "time": "2024-05-24T13:23:04+00:00" + "time": "2024-07-24T07:01:22+00:00" }, { "name": "phpstan/phpstan-phpunit", diff --git a/src/resourcepacks/ResourcePack.php b/src/resourcepacks/ResourcePack.php index 04feeeb3d..cdab3447b 100644 --- a/src/resourcepacks/ResourcePack.php +++ b/src/resourcepacks/ResourcePack.php @@ -60,6 +60,8 @@ interface ResourcePack{ * @param int $start Offset to start reading the chunk from * @param int $length Maximum length of data to return. * + * @phpstan-param positive-int $length + * * @return string byte-array * @throws \InvalidArgumentException if the chunk does not exist */ diff --git a/src/resourcepacks/ZippedResourcePack.php b/src/resourcepacks/ZippedResourcePack.php index da7db1db7..c4daeedf7 100644 --- a/src/resourcepacks/ZippedResourcePack.php +++ b/src/resourcepacks/ZippedResourcePack.php @@ -154,6 +154,9 @@ class ZippedResourcePack implements ResourcePack{ } public function getPackChunk(int $start, int $length) : string{ + if($length < 1){ + throw new \InvalidArgumentException("Pack length must be positive"); + } fseek($this->fileResource, $start); if(feof($this->fileResource)){ throw new \InvalidArgumentException("Requested a resource pack chunk with invalid start offset"); diff --git a/src/world/format/io/region/RegionLocationTableEntry.php b/src/world/format/io/region/RegionLocationTableEntry.php index abb92accf..ad0b1ce48 100644 --- a/src/world/format/io/region/RegionLocationTableEntry.php +++ b/src/world/format/io/region/RegionLocationTableEntry.php @@ -27,6 +27,7 @@ use function range; class RegionLocationTableEntry{ private int $firstSector; + /** @phpstan-var positive-int */ private int $sectorCount; private int $timestamp; @@ -61,6 +62,9 @@ class RegionLocationTableEntry{ return range($this->getFirstSector(), $this->getLastSector()); } + /** + * @phpstan-return positive-int + */ public function getSectorCount() : int{ return $this->sectorCount; } From 54e7749c0bb02ce64a3dac75bed2f45f9a7086cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 06:52:28 +0000 Subject: [PATCH 35/37] Bump docker/build-push-action from 6.3.0 to 6.5.0 (#6409) --- .github/workflows/build-docker-image.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index c6d6fb896..b3d6661e9 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.3.0 + uses: docker/build-push-action@v6.5.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.3.0 + uses: docker/build-push-action@v6.5.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.3.0 + uses: docker/build-push-action@v6.5.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.3.0 + uses: docker/build-push-action@v6.5.0 with: push: true context: ./pocketmine-mp From c4a2b6494d9293e7473461464087a1f423ca055b Mon Sep 17 00:00:00 2001 From: zSALLAZAR <59490940+zSALLAZAR@users.noreply.github.com> Date: Tue, 6 Aug 2024 16:12:47 +0200 Subject: [PATCH 36/37] Implement Aqua Affinity enchantment (#6408) --- src/data/bedrock/EnchantmentIdMap.php | 1 + src/item/enchantment/AvailableEnchantmentRegistry.php | 1 + src/item/enchantment/StringToEnchantmentParser.php | 1 + src/item/enchantment/VanillaEnchantments.php | 10 ++++++++++ 4 files changed, 13 insertions(+) diff --git a/src/data/bedrock/EnchantmentIdMap.php b/src/data/bedrock/EnchantmentIdMap.php index ae2460cfe..e3d652b19 100644 --- a/src/data/bedrock/EnchantmentIdMap.php +++ b/src/data/bedrock/EnchantmentIdMap.php @@ -43,6 +43,7 @@ final class EnchantmentIdMap{ $this->register(EnchantmentIds::PROJECTILE_PROTECTION, VanillaEnchantments::PROJECTILE_PROTECTION()); $this->register(EnchantmentIds::THORNS, VanillaEnchantments::THORNS()); $this->register(EnchantmentIds::RESPIRATION, VanillaEnchantments::RESPIRATION()); + $this->register(EnchantmentIds::AQUA_AFFINITY, VanillaEnchantments::AQUA_AFFINITY()); $this->register(EnchantmentIds::SHARPNESS, VanillaEnchantments::SHARPNESS()); //TODO: smite, bane of arthropods (these don't make sense now because their applicable mobs don't exist yet) diff --git a/src/item/enchantment/AvailableEnchantmentRegistry.php b/src/item/enchantment/AvailableEnchantmentRegistry.php index 2c6f421ed..cae94c666 100644 --- a/src/item/enchantment/AvailableEnchantmentRegistry.php +++ b/src/item/enchantment/AvailableEnchantmentRegistry.php @@ -56,6 +56,7 @@ final class AvailableEnchantmentRegistry{ $this->register(Enchantments::PROJECTILE_PROTECTION(), [Tags::ARMOR], []); $this->register(Enchantments::THORNS(), [Tags::CHESTPLATE], [Tags::HELMET, Tags::LEGGINGS, Tags::BOOTS]); $this->register(Enchantments::RESPIRATION(), [Tags::HELMET], []); + $this->register(Enchantments::AQUA_AFFINITY(), [Tags::HELMET], []); $this->register(Enchantments::SHARPNESS(), [Tags::SWORD, Tags::AXE], []); $this->register(Enchantments::KNOCKBACK(), [Tags::SWORD], []); $this->register(Enchantments::FIRE_ASPECT(), [Tags::SWORD], []); diff --git a/src/item/enchantment/StringToEnchantmentParser.php b/src/item/enchantment/StringToEnchantmentParser.php index cd57eb203..47a750ff2 100644 --- a/src/item/enchantment/StringToEnchantmentParser.php +++ b/src/item/enchantment/StringToEnchantmentParser.php @@ -52,6 +52,7 @@ final class StringToEnchantmentParser extends StringToTParser{ $result->register("protection", fn() => VanillaEnchantments::PROTECTION()); $result->register("punch", fn() => VanillaEnchantments::PUNCH()); $result->register("respiration", fn() => VanillaEnchantments::RESPIRATION()); + $result->register("aqua_affinity", fn() => VanillaEnchantments::AQUA_AFFINITY()); $result->register("sharpness", fn() => VanillaEnchantments::SHARPNESS()); $result->register("silk_touch", fn() => VanillaEnchantments::SILK_TOUCH()); $result->register("swift_sneak", fn() => VanillaEnchantments::SWIFT_SNEAK()); diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index 779098c77..19ce39716 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -33,6 +33,7 @@ use pocketmine\utils\RegistryTrait; * @see build/generate-registry-annotations.php * @generate-registry-docblock * + * @method static Enchantment AQUA_AFFINITY() * @method static ProtectionEnchantment BLAST_PROTECTION() * @method static Enchantment EFFICIENCY() * @method static ProtectionEnchantment FEATHER_FALLING() @@ -144,6 +145,15 @@ final class VanillaEnchantments{ fn(int $level) : int => 10 * $level, 30 )); + self::register("AQUA_AFFINITY", new Enchantment( + KnownTranslationFactory::enchantment_waterWorker(), + Rarity::RARE, + 0, + 0, + 1, + null, + 40 + )); self::register("SHARPNESS", new SharpnessEnchantment( KnownTranslationFactory::enchantment_damage_all(), From 5a926a79cb97f284c64c754d3f60fba8348435b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:21:20 +0000 Subject: [PATCH 37/37] Bump phpstan/phpstan in the development-patch-updates group (#6412) --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index d035ff935..28ef5e9c2 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "symfony/filesystem": "~6.4.0" }, "require-dev": { - "phpstan/phpstan": "1.11.8", + "phpstan/phpstan": "1.11.9", "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 7cc34ff98..e3211e7c5 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": "3ee9506c0be6b8b202d790824344e79c", + "content-hash": "cddee8096f4b575629ff671000543d3f", "packages": [ { "name": "adhocore/json-comment", @@ -1389,16 +1389,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.8", + "version": "1.11.9", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec" + "reference": "e370bcddadaede0c1716338b262346f40d296f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", - "reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e370bcddadaede0c1716338b262346f40d296f82", + "reference": "e370bcddadaede0c1716338b262346f40d296f82", "shasum": "" }, "require": { @@ -1443,7 +1443,7 @@ "type": "github" } ], - "time": "2024-07-24T07:01:22+00:00" + "time": "2024-08-01T16:25:18+00:00" }, { "name": "phpstan/phpstan-phpunit",