diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8acff71d667..97607ab8fa2 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,6 +12,22 @@ 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" + phpstan: + patterns: + - "phpstan/*" - package-ecosystem: gitsubmodule directory: "/" diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index ea8137f89e6..4f045bdc9b6 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.2.0 + uses: docker/build-push-action@v6.6.1 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.2.0 + uses: docker/build-push-action@v6.6.1 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.2.0 + uses: docker/build-push-action@v6.6.1 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.2.0 + uses: docker/build-push-action@v6.6.1 with: push: true context: ./pocketmine-mp diff --git a/.github/workflows/discord-release-notify.yml b/.github/workflows/discord-release-notify.yml index 2fbfa11f2c8..8d0add224e8 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.0 + 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 4521988a920..c47a4399b1e 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.0 + uses: shivammathur/setup-php@2.31.1 with: php-version: ${{ matrix.php-version }} @@ -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,11 +87,12 @@ 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 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 }} diff --git a/.github/workflows/main-php-matrix.yml b/.github/workflows/main-php-matrix.yml index b81ac8b460c..6d71a0e70ca 100644 --- a/.github/workflows/main-php-matrix.yml +++ b/.github/workflows/main-php-matrix.yml @@ -147,17 +147,8 @@ jobs: - name: Install Composer dependencies run: composer install --no-dev --prefer-dist --no-interaction - - name: Regenerate registry annotations - run: php build/generate-registry-annotations.php src - - - name: Regenerate KnownTranslation APIs - run: php build/generate-known-translation-apis.php - - - name: Regenerate BedrockData available files constants - run: php build/generate-bedrockdata-path-consts.php - - - name: Regenerate YmlServerProperties constants - run: php build/generate-pocketmine-yml-property-consts.php + - name: Update generated code + run: composer update-codegen - name: Verify code is unchanged run: | diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3dbcd6ddd5f..7c92c0b8b28 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.0 + uses: shivammathur/setup-php@2.31.1 with: php-version: 8.2 tools: php-cs-fixer:3.49 diff --git a/.github/workflows/team-pr-auto-approve.yml b/.github/workflows/team-pr-auto-approve.yml new file mode 100644 index 00000000000..a582be32805 --- /dev/null +++ b/.github/workflows/team-pr-auto-approve.yml @@ -0,0 +1,42 @@ +#Due to GitHub awkwardness, it's not easy to reduce the review requirement for collaborators. +#Our policy is that 2 collaborators should be aware of every change. +#For outside PRs, this means 2 collaborator reviews. +#For PRs made by collaborators, this means 1 reviewer + the author. +#We trust that collaborators don't need as much oversight. +name: Auto approve collaborator PRs + +on: + pull_request_target: + types: + - opened + - synchronize + - reopened + - ready_for_review + +permissions: + pull-requests: write + +jobs: + approve: + name: Auto approve + runs-on: ubuntu-latest + + steps: + - name: Check if PR author has write access + id: check-permission + uses: actions-cool/check-user-permission@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + require: write + username: ${{ github.event.pull_request.user.login }} + #technically this would be fine for dependabot but generally bots don't count as team members + check-bot: true + + #TODO: Some way to avoid unnecessary repeated reviews would be nice here + + - name: Approve PR if authorized + if: steps.check-permission.outputs.require-result == 'true' && steps.check-permission.outputs.check-result == 'false' + uses: juliangruber/approve-pull-request-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + number: ${{ github.event.pull_request.number }} diff --git a/.gitignore b/.gitignore index 13c3473764f..6456250a6db 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.* diff --git a/build/generate-block-serializer-consts.php b/build/generate-block-serializer-consts.php index 89cdcbe316a..875729fcf42 100644 --- a/build/generate-block-serializer-consts.php +++ b/build/generate-block-serializer-consts.php @@ -102,6 +102,25 @@ function generateClassHeader(string $className) : string{ return <<
getEquipSound() : ?\pocketmine\world\Sound` - returns the sound to play when this armour is equipped or unequipped +- The following API methods have signature changes: + - `ArmorMaterial->__construct()` now accepts an optional `?Sound $equipSound` parameter + +### `pocketmine\utils` +- The following API methods have signature changes: + - `MainLogger->__construct()` now accepts `null` for the `$logFile` parameter - this disables the creation of a logger thread and log file + - `MainLogger->__construct()` now accepts an optional `?string $logArchiveDir` parameter. If set, this enables log archiving in the specified directory when the current log file exceeds 32 MB. + +## Dependencies +- Now uses [`pocketmine/bedrock-block-upgrade-schema` version 4.0.0](https://github.com/pmmp/BedrockBlockUpgradeSchema/releases/tag/4.0.0). +- Now uses [`pmmp/ext-pmmpthread` version 6.1.0](https://github.com/pmmp/ext-pmmpthread/releases/tag/6.1.0). +- Now uses [`pocketmine/errorhandler` version 0.7.0](https://github.com/pmmp/ErrorHandler/releases/tag/0.7.0). +- Now uses [`pocketmine/raklib` version 1.1.0](https://github.com/pmmp/RakLib/releases/tag/1.1.0). +- Now uses [`pocketmine/raklib-ipc` version 1.0.0](https://github.com/pmmp/RakLibIpc/releases/tag/1.0.0). + +## Internals +- (Re)Added support for RakLib packet ACK receipts. This was used to throttle resource pack sending and prevent network overloading. + - Added `NetworkSession->sendDataPacketWithReceipt()` to make use of this feature. + - `PacketSender` now requires an additional `?int $receiptId` parameter. +- `ResourcePackPacketHandler` now uses `sendDataPacketWithReceipt()` to send resource packs, and delays sending the next chunk until the current one is acknowledged. +- `ResourcePackPacketHandler` now accepts resource pack info directly in the constructor, instead of `ResourcePackManager`. This eases the implementation of `PlayerResourcePackOfferEvent`. +- Increased `ZlibCompressor::DEFAULT_MAX_DECOMPRESSION_SIZE` to 8 MB (previously 2 MB). While this weakens server security, it appears to be necessary to deal with extremely bloated Persona skins. +- Increased max split packet parts accepted by `RakLib` to 512 (previously 128). Again, this is necessary to deal with extremely bloated Persona skins. +- Added a new cache mechanism for `PocketMine-MP.phar`. + - `ext-phar`'s default mechanism is extremely wasteful (generating a separate cache file per thread), and doesn't clean up after itself. + - The new cache mechanism is shared between all threads, and automatically cleans up stale caches. + - The phar stub (`build/server-phar-stub.php`) now converts the phar contents into a `.tar`, and decompresses all the files into `$TMPDIR/PocketMine-MP-phar-cache./`. + - `phar://` URIs still work with this system, but `new Phar(__FILE__)` must be replaced by `new PharData(__FILE__)` within PocketMine-MP core code. + - Backtraces from a `phar`'d server will now point to a location in the extracted phar cache, rather than the phar itself. +- `block_factory_consistency_check` test (actually for `RuntimeBlockStateRegistry`) now stores less data, and is no longer affected by changes to internal state ID construction. + +# 5.14.1 +Released 5th April 2024. + +## Fixes +- Fixed incorrect `pmmpthread` version check in server bootstrap. diff --git a/changelogs/5.15.md b/changelogs/5.15.md new file mode 100644 index 00000000000..536411ec597 --- /dev/null +++ b/changelogs/5.15.md @@ -0,0 +1,16 @@ +# 5.15.0 +Released 25th April 2024. + +**For Minecraft: Bedrock Edition 1.20.80** + +This is a support release for Minecraft: Bedrock Edition 1.20.80. + +**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.20.80. +- Removed support for earlier versions. diff --git a/changelogs/5.16.md b/changelogs/5.16.md new file mode 100644 index 00000000000..8b4251d76d2 --- /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/changelogs/5.17.md b/changelogs/5.17.md new file mode 100644 index 00000000000..b26f38b8a0a --- /dev/null +++ b/changelogs/5.17.md @@ -0,0 +1,38 @@ +# 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. + +# 5.17.1 +Released 13th August 2024. + +## Documentation +- Added a note about `BlockStateData::CURRENT_VERSION`. + +## Fixes +- Fixed anvil placement rotation to match vanilla. +- Fixed outdated `BedrockWorldData` version, this was preventing use newer worlds. + +## Internals +- Dependabot: PHPStan and patch updates are now grouped into a single PR. diff --git a/changelogs/5.18.md b/changelogs/5.18.md new file mode 100644 index 00000000000..4b7911efefc --- /dev/null +++ b/changelogs/5.18.md @@ -0,0 +1,19 @@ +# 5.18.0 +Released 16th August 2024. + +**For Minecraft: Bedrock Edition 1.21.20** + +This is a support release for Minecraft: Bedrock Edition 1.21.20. + +**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.20. +- Removed support for earlier versions. + +## Fixes +- Use `VISIBLE_MOB_EFFECTS` actor metadata property to send effect bubbles, this fixes effect bubbles not showing diff --git a/composer.json b/composer.json index b46e3bfd8b8..5d1167b6d8a 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "ext-openssl": "*", "ext-pcre": "*", "ext-phar": "*", - "ext-pmmpthread": "^6.0.7", + "ext-pmmpthread": "^6.1.0", "ext-reflection": "*", "ext-simplexml": "*", "ext-sockets": "*", @@ -33,14 +33,14 @@ "composer-runtime-api": "^2.0", "adhocore/json-comment": "~1.2.0", "pocketmine/netresearch-jsonmapper": "~v4.4.999", - "pocketmine/bedrock-block-upgrade-schema": "~3.6.0+bedrock-1.20.70", - "pocketmine/bedrock-data": "~2.9.0+bedrock-1.20.70", - "pocketmine/bedrock-item-upgrade-schema": "~1.8.0+bedrock-1.20.70", - "pocketmine/bedrock-protocol": "~29.0.0+bedrock-1.20.70", + "pocketmine/bedrock-block-upgrade-schema": "~4.3.0+bedrock-1.21.20", + "pocketmine/bedrock-data": "~2.12.0+bedrock-1.21.20", + "pocketmine/bedrock-item-upgrade-schema": "~1.11.0+bedrock-1.21.20", + "pocketmine/bedrock-protocol": "~33.0.0+bedrock-1.21.20", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/color": "^0.3.0", - "pocketmine/errorhandler": "^0.6.0", + "pocketmine/errorhandler": "^0.7.0", "pocketmine/locale-data": "~2.19.0", "pocketmine/log": "^0.4.0", "pocketmine/math": "~1.0.0", @@ -52,10 +52,10 @@ "symfony/filesystem": "~6.4.0" }, "require-dev": { - "phpstan/phpstan": "1.10.60", + "phpstan/phpstan": "1.11.10", "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": { @@ -83,11 +83,14 @@ "@composer install --no-dev --classmap-authoritative --ignore-platform-reqs", "@php -dphar.readonly=0 build/server-phar.php" ], - "update-registry-annotations": [ + "update-codegen": [ + "@php build/generate-bedrockdata-path-consts.php", + "@php build/generate-biome-ids.php", + "@php build/generate-block-serializer-consts.php vendor/pocketmine/bedrock-data/canonical_block_states.nbt", + "@php build/generate-item-type-names.php vendor/pocketmine/bedrock-data/required_item_list.json", + "@php build/generate-known-translation-apis.php", + "@php build/generate-pocketmine-yml-property-consts.php", "@php build/generate-registry-annotations.php src" - ], - "update-translation-apis": [ - "@php build/generate-known-translation-apis.php" ] } } diff --git a/composer.lock b/composer.lock index 44a2c1ff0cd..5eb9a215858 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": "f3dd41a25226b5ff1030d822b2c46d02", + "content-hash": "fab1e131dfd049da39a87d4e562f1870", "packages": [ { "name": "adhocore/json-comment", @@ -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,20 +123,20 @@ "type": "github" } ], - "time": "2023-01-15T23:15:59+00:00" + "time": "2023-11-29T23:19:16+00:00" }, { "name": "pocketmine/bedrock-block-upgrade-schema", - "version": "3.6.0", + "version": "4.3.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockBlockUpgradeSchema.git", - "reference": "1496e275db5148cb96bdaa998115e5e31a5c1e4d" + "reference": "53d3a41c37ce90d58b33130cdadad08e442d7c47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/1496e275db5148cb96bdaa998115e5e31a5c1e4d", - "reference": "1496e275db5148cb96bdaa998115e5e31a5c1e4d", + "url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/53d3a41c37ce90d58b33130cdadad08e442d7c47", + "reference": "53d3a41c37ce90d58b33130cdadad08e442d7c47", "shasum": "" }, "type": "library", @@ -142,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/3.6.0" + "source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/4.3.0" }, - "time": "2024-02-28T19:25:25+00:00" + "time": "2024-08-13T18:04:27+00:00" }, { "name": "pocketmine/bedrock-data", - "version": "2.9.0+bedrock-1.20.70", + "version": "2.12.0+bedrock-1.21.20", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockData.git", - "reference": "10b6696b662fd80a282eff7dca6c99d321c5b9e3" + "reference": "d4ee3d08964fa16fbbdd04af1fb52bbde540b665" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/10b6696b662fd80a282eff7dca6c99d321c5b9e3", - "reference": "10b6696b662fd80a282eff7dca6c99d321c5b9e3", + "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/d4ee3d08964fa16fbbdd04af1fb52bbde540b665", + "reference": "d4ee3d08964fa16fbbdd04af1fb52bbde540b665", "shasum": "" }, "type": "library", @@ -168,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.70" + "source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.21.20" }, - "time": "2024-03-13T13:55:05+00:00" + "time": "2024-08-15T12:50:26+00:00" }, { "name": "pocketmine/bedrock-item-upgrade-schema", - "version": "1.8.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockItemUpgradeSchema.git", - "reference": "4c4dc3bbceb944c5de429b6e752ab7a15652078c" + "reference": "35c18d093fc2b12da8737b2edb2c3ad6a14a53dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/4c4dc3bbceb944c5de429b6e752ab7a15652078c", - "reference": "4c4dc3bbceb944c5de429b6e752ab7a15652078c", + "url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/35c18d093fc2b12da8737b2edb2c3ad6a14a53dd", + "reference": "35c18d093fc2b12da8737b2edb2c3ad6a14a53dd", "shasum": "" }, "type": "library", @@ -194,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.8.0" + "source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.11.0" }, - "time": "2024-02-28T19:25:53+00:00" + "time": "2024-08-13T18:06:25+00:00" }, { "name": "pocketmine/bedrock-protocol", - "version": "29.0.0+bedrock-1.20.70", + "version": "33.0.0+bedrock-1.21.20", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "8d63f39bb2cded3d3e578fd3cf7bc769b9674857" + "reference": "e2264137c5cd0522de2c6ee4921a3a803818ea32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/8d63f39bb2cded3d3e578fd3cf7bc769b9674857", - "reference": "8d63f39bb2cded3d3e578fd3cf7bc769b9674857", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/e2264137c5cd0522de2c6ee4921a3a803818ea32", + "reference": "e2264137c5cd0522de2c6ee4921a3a803818ea32", "shasum": "" }, "require": { @@ -222,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" @@ -240,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/29.0.0+bedrock-1.20.70" + "source": "https://github.com/pmmp/BedrockProtocol/tree/32.2.0+bedrock-1.21.2" }, - "time": "2024-03-13T14:35:54+00:00" + "time": "2024-08-10T19:23:18+00:00" }, { "name": "pocketmine/binaryutils", @@ -376,25 +381,25 @@ }, { "name": "pocketmine/errorhandler", - "version": "0.6.0", + "version": "0.7.0", "source": { "type": "git", "url": "https://github.com/pmmp/ErrorHandler.git", - "reference": "dae214a04348b911e8219ebf125ff1c5589cc878" + "reference": "cae94884368a74ece5294b9ff7fef18732dcd921" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ErrorHandler/zipball/dae214a04348b911e8219ebf125ff1c5589cc878", - "reference": "dae214a04348b911e8219ebf125ff1c5589cc878", + "url": "https://api.github.com/repos/pmmp/ErrorHandler/zipball/cae94884368a74ece5294b9ff7fef18732dcd921", + "reference": "cae94884368a74ece5294b9ff7fef18732dcd921", "shasum": "" }, "require": { "php": "^8.0" }, "require-dev": { - "phpstan/phpstan": "0.12.99", - "phpstan/phpstan-strict-rules": "^0.12.2", - "phpunit/phpunit": "^9.5" + "phpstan/phpstan": "~1.10.3", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5 || ^10.0 || ^11.0" }, "type": "library", "autoload": { @@ -409,9 +414,9 @@ "description": "Utilities to handle nasty PHP E_* errors in a usable way", "support": { "issues": "https://github.com/pmmp/ErrorHandler/issues", - "source": "https://github.com/pmmp/ErrorHandler/tree/0.6.0" + "source": "https://github.com/pmmp/ErrorHandler/tree/0.7.0" }, - "time": "2022-01-08T21:05:46+00:00" + "time": "2024-04-02T18:29:54+00:00" }, { "name": "pocketmine/locale-data", @@ -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,20 +922,20 @@ "type": "tidelift" } ], - "time": "2023-11-08T05:53:05+00:00" + "time": "2024-04-27T21:32:50+00:00" }, { "name": "symfony/filesystem", - "version": "v6.4.3", + "version": "v6.4.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb" + "reference": "b51ef8059159330b74a4d52f68e671033c0fe463" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b51ef8059159330b74a4d52f68e671033c0fe463", + "reference": "b51ef8059159330b74a4d52f68e671033c0fe463", "shasum": "" }, "require": { @@ -938,6 +943,9 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" + }, "type": "library", "autoload": { "psr-4": { @@ -964,7 +972,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.3" + "source": "https://github.com/symfony/filesystem/tree/v6.4.9" }, "funding": [ { @@ -980,20 +988,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+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": { @@ -1043,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": [ { @@ -1059,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": { @@ -1123,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": [ { @@ -1139,22 +1147,22 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-06-19T12:30:46+00:00" } ], "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": { @@ -1162,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", @@ -1192,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": [ { @@ -1200,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", @@ -1380,16 +1389,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.60", + "version": "1.11.10", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe" + "reference": "640410b32995914bde3eed26fa89552f9c2c082f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/95dcea7d6c628a3f2f56d091d8a0219485a86bbe", - "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/640410b32995914bde3eed26fa89552f9c2c082f", + "reference": "640410b32995914bde3eed26fa89552f9c2c082f", "shasum": "" }, "require": { @@ -1432,31 +1441,27 @@ { "url": "https://github.com/phpstan", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" } ], - "time": "2024-03-07T13:30:19+00:00" + "time": "2024-08-08T09:02:50+00:00" }, { "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" @@ -1488,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.2", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542" + "reference": "363f921dd8441777d4fc137deb99beb486c77df1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/7a50e9662ee9f3942e4aaaf3d603653f60282542", - "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542", + "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.34" + "phpstan/phpstan": "^1.11" }, "require-dev": { "nikic/php-parser": "^4.13.0", @@ -1537,22 +1542,22 @@ "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.2" + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.6.0" }, - "time": "2023-10-30T14:35:06+00:00" + "time": "2024-04-20T06:37:51+00:00" }, { "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": { @@ -1609,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": [ { @@ -1617,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", @@ -1864,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": { @@ -1913,7 +1918,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.3-dev" + "dev-main": "10.5-dev" } }, "autoload": { @@ -1945,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": [ { @@ -1961,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", @@ -2335,16 +2340,16 @@ }, { "name": "sebastian/environment", - "version": "6.0.1", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", "shasum": "" }, "require": { @@ -2359,7 +2364,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -2387,7 +2392,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" }, "funding": [ { @@ -2395,7 +2400,7 @@ "type": "github" } ], - "time": "2023-04-11T05:39:26+00:00" + "time": "2024-03-23T08:47:14+00:00" }, { "name": "sebastian/exporter", @@ -2953,7 +2958,7 @@ "ext-openssl": "*", "ext-pcre": "*", "ext-phar": "*", - "ext-pmmpthread": "^6.0.7", + "ext-pmmpthread": "^6.1.0", "ext-reflection": "*", "ext-simplexml": "*", "ext-sockets": "*", diff --git a/install-local-protocol.sh b/install-local-protocol.sh new file mode 100644 index 00000000000..0f25a039005 --- /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'." + diff --git a/src/PocketMine.php b/src/PocketMine.php index f0fba9dcbcd..b2e1cd04695 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -124,8 +124,8 @@ function check_platform_dependencies(){ } if(($pmmpthread_version = phpversion("pmmpthread")) !== false){ - if(version_compare($pmmpthread_version, "6.0.7") < 0 || version_compare($pmmpthread_version, "7.0.0") >= 0){ - $messages[] = "pmmpthread ^6.0.7 is required, while you have $pmmpthread_version."; + if(version_compare($pmmpthread_version, "6.1.0") < 0 || version_compare($pmmpthread_version, "7.0.0") >= 0){ + $messages[] = "pmmpthread ^6.1.0 is required, while you have $pmmpthread_version."; } } @@ -327,7 +327,7 @@ function server(){ } $logFile = isset($opts[BootstrapOptions::NO_LOG_FILE]) ? null : Path::join($dataPath, "server.log"); - $logger = new MainLogger($logFile, Path::join($dataPath, "log_archive"), Terminal::hasFormattingCodes(), "Server", new \DateTimeZone(Timezone::get())); + $logger = new MainLogger($logFile, Terminal::hasFormattingCodes(), "Server", new \DateTimeZone(Timezone::get()), false, Path::join($dataPath, "log_archive")); if($logFile === null){ $logger->notice("Logging to file disabled. Ensure logs are collected by other means (e.g. Docker logs)."); } diff --git a/src/Server.php b/src/Server.php index ed7f52d63ea..a34349bb5cd 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1666,9 +1666,11 @@ public function crashDump() : void{ $this->isRunning = false; //Force minimum uptime to be >= 120 seconds, to reduce the impact of spammy crash loops - $spacing = ((int) $this->startTime) - time() + 120; + $uptime = time() - ((int) $this->startTime); + $minUptime = 120; + $spacing = $minUptime - $uptime; if($spacing > 0){ - echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL; + echo "--- Uptime {$uptime}s - waiting {$spacing}s to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL; sleep($spacing); } @Process::kill(Process::pid()); diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 420b12e5802..b292b4c4580 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,7 +31,7 @@ final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "5.13.1"; + public const BASE_VERSION = "5.18.1"; public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "stable"; diff --git a/src/block/Anvil.php b/src/block/Anvil.php index 916c390ef6d..4b4afef6153 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -91,7 +91,7 @@ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ - $this->facing = Facing::rotateY($player->getHorizontalFacing(), true); + $this->facing = Facing::rotateY($player->getHorizontalFacing(), false); } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/block/Bell.php b/src/block/Bell.php index ec033cef87a..53a6fc7fbb4 100644 --- a/src/block/Bell.php +++ b/src/block/Bell.php @@ -150,6 +150,10 @@ public function ring(int $faceHit) : void{ } } + public function getDropsForIncompatibleTool(Item $item) : array{ + return [$this->asItem()]; + } + private function isValidFaceToRing(int $faceHit) : bool{ return match($this->attachmentType){ BellAttachmentType::CEILING => true, diff --git a/src/block/BlockTypeIds.php b/src/block/BlockTypeIds.php index dec31eff11f..29f4e650d4d 100644 --- a/src/block/BlockTypeIds.php +++ b/src/block/BlockTypeIds.php @@ -745,8 +745,23 @@ private function __construct(){ 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 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 = 10718; + public const FIRST_UNUSED_BLOCK_ID = 10733; 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 00000000000..ce759ee87f7 --- /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/Copper.php b/src/block/Copper.php index 1da253fa418..8e678bf426d 100644 --- a/src/block/Copper.php +++ b/src/block/Copper.php @@ -24,7 +24,8 @@ 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 088ace11e1b..4194cd8543e 100644 --- a/src/block/CopperSlab.php +++ b/src/block/CopperSlab.php @@ -24,7 +24,8 @@ 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 b16d49ec1ee..dd8f44f7ac7 100644 --- a/src/block/CopperStairs.php +++ b/src/block/CopperStairs.php @@ -24,7 +24,8 @@ 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/NetherRoots.php b/src/block/NetherRoots.php index 5c39b8bec3e..0b08d1b180a 100644 --- a/src/block/NetherRoots.php +++ b/src/block/NetherRoots.php @@ -34,6 +34,7 @@ private function canBeSupportedAt(Block $block) : bool{ $supportBlock = $block->getSide(Facing::DOWN); return $supportBlock->hasTypeTag(BlockTypeTags::DIRT) || - $supportBlock->hasTypeTag(BlockTypeTags::MUD); + $supportBlock->hasTypeTag(BlockTypeTags::MUD) || + $supportBlock->getTypeId() === BlockTypeIds::SOUL_SOIL; } } diff --git a/src/block/SoulCampfire.php b/src/block/SoulCampfire.php new file mode 100644 index 00000000000..a9c8fc918f1 --- /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 9c0e7d3b7c7..13c7e869ac1 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -36,6 +36,7 @@ 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 @@ * @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() @@ -186,6 +188,8 @@ * @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() @@ -607,6 +611,10 @@ * @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() @@ -685,6 +693,7 @@ * @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() @@ -735,6 +744,13 @@ * @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() @@ -826,6 +842,11 @@ public function getBreakTime(Item $item) : float{ 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)); @@ -1261,6 +1282,7 @@ public function getDropsForCompatibleTool(Item $item) : array{ self::registerBlocksR17(); self::registerBlocksR18(); self::registerMudBlocks(); + self::registerTuffBlocks(); self::registerCraftingTables(); self::registerChorusBlocks(); @@ -1568,7 +1590,6 @@ private static function registerBlocksR17() : void{ 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)))); @@ -1659,6 +1680,27 @@ private static function registerMudBlocks() : void{ 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/block/WoodenStairs.php b/src/block/WoodenStairs.php index 30fa7e60266..0d9ba62cebf 100644 --- a/src/block/WoodenStairs.php +++ b/src/block/WoodenStairs.php @@ -28,6 +28,10 @@ class WoodenStairs extends Stair{ use WoodTypeTrait; + public function getFuelTime() : int{ + return $this->woodType->isFlammable() ? 300 : 0; + } + public function getFlameEncouragement() : int{ return 5; } diff --git a/src/block/inventory/CampfireInventory.php b/src/block/inventory/CampfireInventory.php new file mode 100644 index 00000000000..ae762473e23 --- /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 00000000000..ad4a193d7b8 --- /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/ChiseledBookshelf.php b/src/block/tile/ChiseledBookshelf.php index f9d61e7eb6d..6455208fecd 100644 --- a/src/block/tile/ChiseledBookshelf.php +++ b/src/block/tile/ChiseledBookshelf.php @@ -59,7 +59,7 @@ public function readSaveData(CompoundTag $nbt) : void{ $this->loadItems($nbt); } - public function writeSaveData(CompoundTag $nbt) : void{ + protected function writeSaveData(CompoundTag $nbt) : void{ $this->saveItems($nbt); } diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 6e87b72acb9..515dd8c63c6 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -57,6 +57,7 @@ public function __construct(){ $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 @@ public function __construct(){ $this->register(MobHead::class, ["Skull", "minecraft:skull"]); $this->register(GlowingItemFrame::class, ["GlowItemFrame"]); - //TODO: Campfire //TODO: ChalkboardBlock //TODO: ChemistryTable //TODO: CommandBlock diff --git a/src/block/utils/BannerPatternType.php b/src/block/utils/BannerPatternType.php index cd63226a75b..9b196360331 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/block/utils/ICopper.php b/src/block/utils/ICopper.php new file mode 100644 index 00000000000..a749efe6395 --- /dev/null +++ b/src/block/utils/ICopper.php @@ -0,0 +1,38 @@ +registerShapelessRecipe(new ShapelessRecipe( $inputs, $outputs, @@ -262,6 +263,7 @@ public static function make(string $directoryPath) : CraftingManager{ } $outputs[] = $output; } + //TODO: check unlocking requirements - our current system doesn't support this $result->registerShapedRecipe(new ShapedRecipe( $recipe->shape, $inputs, @@ -273,7 +275,8 @@ public static function make(string $directoryPath) : CraftingManager{ "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 0ce5b72cea6..89834c82145 100644 --- a/src/crafting/FurnaceType.php +++ b/src/crafting/FurnaceType.php @@ -25,6 +25,7 @@ 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 @@ * 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 @@ private function getMetadata() : array{ 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/crafting/json/ShapedRecipeData.php b/src/crafting/json/ShapedRecipeData.php index dd040f516ed..965a437ea62 100644 --- a/src/crafting/json/ShapedRecipeData.php +++ b/src/crafting/json/ShapedRecipeData.php @@ -23,7 +23,9 @@ 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 d59bafbbf3f..23cfebde0b0 100644 --- a/src/crafting/json/ShapelessRecipeData.php +++ b/src/crafting/json/ShapelessRecipeData.php @@ -23,7 +23,9 @@ 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/crash/CrashDump.php b/src/crash/CrashDump.php index 1a558b499dd..49a587c34c5 100644 --- a/src/crash/CrashDump.php +++ b/src/crash/CrashDump.php @@ -63,6 +63,12 @@ use function substr; use function zend_version; use function zlib_encode; +use const E_COMPILE_ERROR; +use const E_CORE_ERROR; +use const E_ERROR; +use const E_PARSE; +use const E_RECOVERABLE_ERROR; +use const E_USER_ERROR; use const FILE_IGNORE_NEW_LINES; use const JSON_THROW_ON_ERROR; use const JSON_UNESCAPED_SLASHES; @@ -85,6 +91,9 @@ class CrashDump{ public const PLUGIN_INVOLVEMENT_DIRECT = "direct"; public const PLUGIN_INVOLVEMENT_INDIRECT = "indirect"; + public const FATAL_ERROR_MASK = + E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR; + private CrashDumpData $data; private string $encodedData; @@ -186,7 +195,7 @@ private function baseCrash() : void{ $error = $lastExceptionError; }else{ $error = error_get_last(); - if($error === null){ + if($error === null || ($error["type"] & self::FATAL_ERROR_MASK) === 0){ throw new \RuntimeException("Crash error information missing - did something use exit()?"); } $error["trace"] = Utils::printableTrace(Utils::currentTrace(3)); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump diff --git a/src/data/bedrock/BannerPatternTypeIdMap.php b/src/data/bedrock/BannerPatternTypeIdMap.php index d1884350fa8..7d4353d4f21 100644 --- a/src/data/bedrock/BannerPatternTypeIdMap.php +++ b/src/data/bedrock/BannerPatternTypeIdMap.php @@ -56,9 +56,11 @@ public function __construct(){ 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", diff --git a/src/data/bedrock/EnchantmentIdMap.php b/src/data/bedrock/EnchantmentIdMap.php index ae2460cfeb9..e3d652b19ce 100644 --- a/src/data/bedrock/EnchantmentIdMap.php +++ b/src/data/bedrock/EnchantmentIdMap.php @@ -43,6 +43,7 @@ private function __construct(){ $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/data/bedrock/block/BlockStateData.php b/src/data/bedrock/block/BlockStateData.php index ea8e9f5b8a4..1973b55af19 100644 --- a/src/data/bedrock/block/BlockStateData.php +++ b/src/data/bedrock/block/BlockStateData.php @@ -38,12 +38,15 @@ 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 - (20 << 16) | //minor - (70 << 8) | //patch - (4); //revision + (21 << 16) | //minor + (20 << 8) | //patch + (6); //revision public const TAG_NAME = "name"; public const TAG_STATES = "states"; diff --git a/src/data/bedrock/block/BlockStateNames.php b/src/data/bedrock/block/BlockStateNames.php index 72b237ddf96..e9c33bee24c 100644 --- a/src/data/bedrock/block/BlockStateNames.php +++ b/src/data/bedrock/block/BlockStateNames.php @@ -42,7 +42,6 @@ private function __construct(){ public const BIG_DRIPLEAF_HEAD = "big_dripleaf_head"; public const BIG_DRIPLEAF_TILT = "big_dripleaf_tilt"; public const BITE_COUNTER = "bite_counter"; - public const BLOCK_LIGHT_LEVEL = "block_light_level"; public const BLOOM = "bloom"; public const BOOKS_STORED = "books_stored"; public const BREWING_STAND_SLOT_A_BIT = "brewing_stand_slot_a_bit"; @@ -59,21 +58,16 @@ private function __construct(){ 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"; public const COVERED_BIT = "covered_bit"; public const CRACKED_STATE = "cracked_state"; public const CRAFTING = "crafting"; - public const DAMAGE = "damage"; public const DEAD_BIT = "dead_bit"; public const DEPRECATED = "deprecated"; public const DIRECTION = "direction"; - 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"; @@ -81,7 +75,6 @@ private function __construct(){ public const EXTINGUISHED = "extinguished"; public const FACING_DIRECTION = "facing_direction"; public const FILL_LEVEL = "fill_level"; - public const FLOWER_TYPE = "flower_type"; public const GROUND_SIGN_DIRECTION = "ground_sign_direction"; public const GROWING_PLANT_AGE = "growing_plant_age"; public const GROWTH = "growth"; @@ -103,9 +96,9 @@ private function __construct(){ public const MC_FACING_DIRECTION = "minecraft:facing_direction"; public const MC_VERTICAL_HALF = "minecraft:vertical_half"; public const MOISTURIZED_AMOUNT = "moisturized_amount"; - 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"; @@ -114,7 +107,6 @@ private function __construct(){ public const PILLAR_AXIS = "pillar_axis"; public const PORTAL_AXIS = "portal_axis"; public const POWERED_BIT = "powered_bit"; - public const PRISMARINE_BLOCK_TYPE = "prismarine_block_type"; public const PROPAGULE_STAGE = "propagule_stage"; public const RAIL_DATA_BIT = "rail_data_bit"; public const RAIL_DIRECTION = "rail_direction"; @@ -122,24 +114,15 @@ private function __construct(){ public const REPEATER_DELAY = "repeater_delay"; public const RESPAWN_ANCHOR_CHARGE = "respawn_anchor_charge"; public const ROTATION = "rotation"; - public const SAND_STONE_TYPE = "sand_stone_type"; - public const SAND_TYPE = "sand_type"; - public const SAPLING_TYPE = "sapling_type"; public const SCULK_SENSOR_PHASE = "sculk_sensor_phase"; public const SEA_GRASS_TYPE = "sea_grass_type"; public const SPONGE_TYPE = "sponge_type"; public const STABILITY = "stability"; public const STABILITY_CHECK = "stability_check"; - public const STONE_BRICK_TYPE = "stone_brick_type"; - public const STONE_SLAB_TYPE = "stone_slab_type"; - public const STONE_SLAB_TYPE_2 = "stone_slab_type_2"; - public const STONE_SLAB_TYPE_3 = "stone_slab_type_3"; - public const STONE_SLAB_TYPE_4 = "stone_slab_type_4"; public const STRIPPED_BIT = "stripped_bit"; public const STRUCTURE_BLOCK_TYPE = "structure_block_type"; public const STRUCTURE_VOID_TYPE = "structure_void_type"; public const SUSPENDED_BIT = "suspended_bit"; - public const 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 202bfa34de4..1794e240d13 100644 --- a/src/data/bedrock/block/BlockStateStringValues.php +++ b/src/data/bedrock/block/BlockStateStringValues.php @@ -62,49 +62,16 @@ private function __construct(){ 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"; - public const DAMAGE_BROKEN = "broken"; - public const DAMAGE_SLIGHTLY_DAMAGED = "slightly_damaged"; - public const DAMAGE_UNDAMAGED = "undamaged"; - public const DAMAGE_VERY_DAMAGED = "very_damaged"; - - 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"; public const DRIPSTONE_THICKNESS_MIDDLE = "middle"; public const DRIPSTONE_THICKNESS_TIP = "tip"; - public const FLOWER_TYPE_ALLIUM = "allium"; - public const FLOWER_TYPE_CORNFLOWER = "cornflower"; - public const FLOWER_TYPE_HOUSTONIA = "houstonia"; - public const FLOWER_TYPE_LILY_OF_THE_VALLEY = "lily_of_the_valley"; - public const FLOWER_TYPE_ORCHID = "orchid"; - public const FLOWER_TYPE_OXEYE = "oxeye"; - public const FLOWER_TYPE_POPPY = "poppy"; - public const FLOWER_TYPE_TULIP_ORANGE = "tulip_orange"; - public const FLOWER_TYPE_TULIP_PINK = "tulip_pink"; - public const FLOWER_TYPE_TULIP_RED = "tulip_red"; - public const FLOWER_TYPE_TULIP_WHITE = "tulip_white"; - public const LEVER_DIRECTION_DOWN_EAST_WEST = "down_east_west"; public const LEVER_DIRECTION_DOWN_NORTH_SOUTH = "down_north_south"; public const LEVER_DIRECTION_EAST = "east"; @@ -136,13 +103,6 @@ private function __construct(){ public const MC_VERTICAL_HALF_BOTTOM = "bottom"; public const MC_VERTICAL_HALF_TOP = "top"; - public const MONSTER_EGG_STONE_TYPE_CHISELED_STONE_BRICK = "chiseled_stone_brick"; - public const MONSTER_EGG_STONE_TYPE_COBBLESTONE = "cobblestone"; - public const MONSTER_EGG_STONE_TYPE_CRACKED_STONE_BRICK = "cracked_stone_brick"; - public const MONSTER_EGG_STONE_TYPE_MOSSY_STONE_BRICK = "mossy_stone_brick"; - public const MONSTER_EGG_STONE_TYPE_STONE = "stone"; - public const MONSTER_EGG_STONE_TYPE_STONE_BRICK = "stone_brick"; - public const ORIENTATION_DOWN_EAST = "down_east"; public const ORIENTATION_DOWN_NORTH = "down_north"; public const ORIENTATION_DOWN_SOUTH = "down_south"; @@ -164,25 +124,6 @@ private function __construct(){ public const PORTAL_AXIS_X = "x"; public const PORTAL_AXIS_Z = "z"; - public const PRISMARINE_BLOCK_TYPE_BRICKS = "bricks"; - public const PRISMARINE_BLOCK_TYPE_DARK = "dark"; - public const PRISMARINE_BLOCK_TYPE_DEFAULT = "default"; - - public const SAND_STONE_TYPE_CUT = "cut"; - public const SAND_STONE_TYPE_DEFAULT = "default"; - public const SAND_STONE_TYPE_HEIROGLYPHS = "heiroglyphs"; - public const SAND_STONE_TYPE_SMOOTH = "smooth"; - - public const SAND_TYPE_NORMAL = "normal"; - public const SAND_TYPE_RED = "red"; - - public const SAPLING_TYPE_ACACIA = "acacia"; - public const SAPLING_TYPE_BIRCH = "birch"; - public const SAPLING_TYPE_DARK_OAK = "dark_oak"; - public const SAPLING_TYPE_JUNGLE = "jungle"; - public const SAPLING_TYPE_OAK = "oak"; - public const SAPLING_TYPE_SPRUCE = "spruce"; - public const SEA_GRASS_TYPE_DEFAULT = "default"; public const SEA_GRASS_TYPE_DOUBLE_BOT = "double_bot"; public const SEA_GRASS_TYPE_DOUBLE_TOP = "double_top"; @@ -190,45 +131,6 @@ private function __construct(){ public const SPONGE_TYPE_DRY = "dry"; public const SPONGE_TYPE_WET = "wet"; - public const STONE_BRICK_TYPE_CHISELED = "chiseled"; - public const STONE_BRICK_TYPE_CRACKED = "cracked"; - public const STONE_BRICK_TYPE_DEFAULT = "default"; - public const STONE_BRICK_TYPE_MOSSY = "mossy"; - public const STONE_BRICK_TYPE_SMOOTH = "smooth"; - - public const STONE_SLAB_TYPE_BRICK = "brick"; - public const STONE_SLAB_TYPE_COBBLESTONE = "cobblestone"; - public const STONE_SLAB_TYPE_NETHER_BRICK = "nether_brick"; - public const STONE_SLAB_TYPE_QUARTZ = "quartz"; - public const STONE_SLAB_TYPE_SANDSTONE = "sandstone"; - public const STONE_SLAB_TYPE_SMOOTH_STONE = "smooth_stone"; - public const STONE_SLAB_TYPE_STONE_BRICK = "stone_brick"; - public const STONE_SLAB_TYPE_WOOD = "wood"; - - public const STONE_SLAB_TYPE_2_MOSSY_COBBLESTONE = "mossy_cobblestone"; - public const STONE_SLAB_TYPE_2_PRISMARINE_BRICK = "prismarine_brick"; - public const STONE_SLAB_TYPE_2_PRISMARINE_DARK = "prismarine_dark"; - public const STONE_SLAB_TYPE_2_PRISMARINE_ROUGH = "prismarine_rough"; - public const STONE_SLAB_TYPE_2_PURPUR = "purpur"; - public const STONE_SLAB_TYPE_2_RED_NETHER_BRICK = "red_nether_brick"; - public const STONE_SLAB_TYPE_2_RED_SANDSTONE = "red_sandstone"; - public const STONE_SLAB_TYPE_2_SMOOTH_SANDSTONE = "smooth_sandstone"; - - public const STONE_SLAB_TYPE_3_ANDESITE = "andesite"; - public const STONE_SLAB_TYPE_3_DIORITE = "diorite"; - public const STONE_SLAB_TYPE_3_END_STONE_BRICK = "end_stone_brick"; - public const STONE_SLAB_TYPE_3_GRANITE = "granite"; - public const STONE_SLAB_TYPE_3_POLISHED_ANDESITE = "polished_andesite"; - public const STONE_SLAB_TYPE_3_POLISHED_DIORITE = "polished_diorite"; - public const STONE_SLAB_TYPE_3_POLISHED_GRANITE = "polished_granite"; - public const STONE_SLAB_TYPE_3_SMOOTH_RED_SANDSTONE = "smooth_red_sandstone"; - - public const STONE_SLAB_TYPE_4_CUT_RED_SANDSTONE = "cut_red_sandstone"; - public const STONE_SLAB_TYPE_4_CUT_SANDSTONE = "cut_sandstone"; - public const STONE_SLAB_TYPE_4_MOSSY_STONE_BRICK = "mossy_stone_brick"; - public const STONE_SLAB_TYPE_4_SMOOTH_QUARTZ = "smooth_quartz"; - public const STONE_SLAB_TYPE_4_STONE = "stone"; - public const STRUCTURE_BLOCK_TYPE_CORNER = "corner"; public const STRUCTURE_BLOCK_TYPE_DATA = "data"; public const STRUCTURE_BLOCK_TYPE_EXPORT = "export"; @@ -239,11 +141,6 @@ private function __construct(){ 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 614394f04cd..f74f858cef5 100644 --- a/src/data/bedrock/block/BlockTypeNames.php +++ b/src/data/bedrock/block/BlockTypeNames.php @@ -41,6 +41,7 @@ private function __construct(){ public const ACACIA_LOG = "minecraft:acacia_log"; public const ACACIA_PLANKS = "minecraft:acacia_planks"; public const ACACIA_PRESSURE_PLATE = "minecraft:acacia_pressure_plate"; + public const ACACIA_SAPLING = "minecraft:acacia_sapling"; public const ACACIA_SLAB = "minecraft:acacia_slab"; public const ACACIA_STAIRS = "minecraft:acacia_stairs"; public const ACACIA_STANDING_SIGN = "minecraft:acacia_standing_sign"; @@ -49,16 +50,20 @@ private function __construct(){ public const ACACIA_WOOD = "minecraft:acacia_wood"; public const ACTIVATOR_RAIL = "minecraft:activator_rail"; public const AIR = "minecraft:air"; + public const ALLIUM = "minecraft:allium"; public const ALLOW = "minecraft:allow"; public const AMETHYST_BLOCK = "minecraft:amethyst_block"; public const AMETHYST_CLUSTER = "minecraft:amethyst_cluster"; public const ANCIENT_DEBRIS = "minecraft:ancient_debris"; public const ANDESITE = "minecraft:andesite"; + public const ANDESITE_DOUBLE_SLAB = "minecraft:andesite_double_slab"; + public const ANDESITE_SLAB = "minecraft:andesite_slab"; public const ANDESITE_STAIRS = "minecraft:andesite_stairs"; public const ANVIL = "minecraft:anvil"; public const AZALEA = "minecraft:azalea"; public const AZALEA_LEAVES = "minecraft:azalea_leaves"; public const AZALEA_LEAVES_FLOWERED = "minecraft:azalea_leaves_flowered"; + public const AZURE_BLUET = "minecraft:azure_bluet"; public const BAMBOO = "minecraft:bamboo"; public const BAMBOO_BLOCK = "minecraft:bamboo_block"; public const BAMBOO_BUTTON = "minecraft:bamboo_button"; @@ -100,6 +105,7 @@ private function __construct(){ public const BIRCH_LOG = "minecraft:birch_log"; public const BIRCH_PLANKS = "minecraft:birch_planks"; public const BIRCH_PRESSURE_PLATE = "minecraft:birch_pressure_plate"; + public const BIRCH_SAPLING = "minecraft:birch_sapling"; public const BIRCH_SLAB = "minecraft:birch_slab"; public const BIRCH_STAIRS = "minecraft:birch_stairs"; public const BIRCH_STANDING_SIGN = "minecraft:birch_standing_sign"; @@ -130,6 +136,7 @@ private function __construct(){ public const BLUE_CONCRETE_POWDER = "minecraft:blue_concrete_powder"; public const BLUE_GLAZED_TERRACOTTA = "minecraft:blue_glazed_terracotta"; public const BLUE_ICE = "minecraft:blue_ice"; + public const BLUE_ORCHID = "minecraft:blue_orchid"; public const BLUE_SHULKER_BOX = "minecraft:blue_shulker_box"; public const BLUE_STAINED_GLASS = "minecraft:blue_stained_glass"; public const BLUE_STAINED_GLASS_PANE = "minecraft:blue_stained_glass_pane"; @@ -139,8 +146,13 @@ private function __construct(){ 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 BRAIN_CORAL_WALL_FAN = "minecraft:brain_coral_wall_fan"; public const BREWING_STAND = "minecraft:brewing_stand"; public const BRICK_BLOCK = "minecraft:brick_block"; + public const BRICK_DOUBLE_SLAB = "minecraft:brick_double_slab"; + public const BRICK_SLAB = "minecraft:brick_slab"; public const BRICK_STAIRS = "minecraft:brick_stairs"; public const BROWN_CANDLE = "minecraft:brown_candle"; public const BROWN_CANDLE_CAKE = "minecraft:brown_candle_cake"; @@ -157,6 +169,9 @@ private function __construct(){ 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 BUBBLE_CORAL_WALL_FAN = "minecraft:bubble_coral_wall_fan"; public const BUDDING_AMETHYST = "minecraft:budding_amethyst"; public const CACTUS = "minecraft:cactus"; public const CAKE = "minecraft:cake"; @@ -195,11 +210,16 @@ private function __construct(){ public const CHERRY_WALL_SIGN = "minecraft:cherry_wall_sign"; public const CHERRY_WOOD = "minecraft:cherry_wood"; public const CHEST = "minecraft:chest"; + public const CHIPPED_ANVIL = "minecraft:chipped_anvil"; public const CHISELED_BOOKSHELF = "minecraft:chiseled_bookshelf"; public const CHISELED_COPPER = "minecraft:chiseled_copper"; public const CHISELED_DEEPSLATE = "minecraft:chiseled_deepslate"; public const CHISELED_NETHER_BRICKS = "minecraft:chiseled_nether_bricks"; public const CHISELED_POLISHED_BLACKSTONE = "minecraft:chiseled_polished_blackstone"; + public const CHISELED_QUARTZ_BLOCK = "minecraft:chiseled_quartz_block"; + public const CHISELED_RED_SANDSTONE = "minecraft:chiseled_red_sandstone"; + public const CHISELED_SANDSTONE = "minecraft:chiseled_sandstone"; + public const CHISELED_STONE_BRICKS = "minecraft:chiseled_stone_bricks"; public const CHISELED_TUFF = "minecraft:chiseled_tuff"; public const CHISELED_TUFF_BRICKS = "minecraft:chiseled_tuff_bricks"; public const CHORUS_FLOWER = "minecraft:chorus_flower"; @@ -208,12 +228,15 @@ private function __construct(){ public const CLIENT_REQUEST_PLACEHOLDER_BLOCK = "minecraft:client_request_placeholder_block"; public const COAL_BLOCK = "minecraft:coal_block"; public const COAL_ORE = "minecraft:coal_ore"; + public const COARSE_DIRT = "minecraft:coarse_dirt"; public const COBBLED_DEEPSLATE = "minecraft:cobbled_deepslate"; public const COBBLED_DEEPSLATE_DOUBLE_SLAB = "minecraft:cobbled_deepslate_double_slab"; public const COBBLED_DEEPSLATE_SLAB = "minecraft:cobbled_deepslate_slab"; 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_DOUBLE_SLAB = "minecraft:cobblestone_double_slab"; + 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"; @@ -227,16 +250,12 @@ private function __construct(){ 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 = "minecraft:coral_fan"; - public const CORAL_FAN_DEAD = "minecraft:coral_fan_dead"; - 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"; + public const CORNFLOWER = "minecraft:cornflower"; public const CRACKED_DEEPSLATE_BRICKS = "minecraft:cracked_deepslate_bricks"; public const CRACKED_DEEPSLATE_TILES = "minecraft:cracked_deepslate_tiles"; public const CRACKED_NETHER_BRICKS = "minecraft:cracked_nether_bricks"; public const CRACKED_POLISHED_BLACKSTONE_BRICKS = "minecraft:cracked_polished_blackstone_bricks"; + public const CRACKED_STONE_BRICKS = "minecraft:cracked_stone_bricks"; public const CRAFTER = "minecraft:crafter"; public const CRAFTING_TABLE = "minecraft:crafting_table"; public const CRIMSON_BUTTON = "minecraft:crimson_button"; @@ -261,6 +280,12 @@ private function __construct(){ public const CUT_COPPER = "minecraft:cut_copper"; public const CUT_COPPER_SLAB = "minecraft:cut_copper_slab"; public const CUT_COPPER_STAIRS = "minecraft:cut_copper_stairs"; + public const CUT_RED_SANDSTONE = "minecraft:cut_red_sandstone"; + public const CUT_RED_SANDSTONE_DOUBLE_SLAB = "minecraft:cut_red_sandstone_double_slab"; + public const CUT_RED_SANDSTONE_SLAB = "minecraft:cut_red_sandstone_slab"; + public const CUT_SANDSTONE = "minecraft:cut_sandstone"; + public const CUT_SANDSTONE_DOUBLE_SLAB = "minecraft:cut_sandstone_double_slab"; + public const CUT_SANDSTONE_SLAB = "minecraft:cut_sandstone_slab"; public const CYAN_CANDLE = "minecraft:cyan_candle"; public const CYAN_CANDLE_CAKE = "minecraft:cyan_candle_cake"; public const CYAN_CARPET = "minecraft:cyan_carpet"; @@ -272,6 +297,8 @@ private function __construct(){ public const CYAN_STAINED_GLASS_PANE = "minecraft:cyan_stained_glass_pane"; public const CYAN_TERRACOTTA = "minecraft:cyan_terracotta"; public const CYAN_WOOL = "minecraft:cyan_wool"; + public const DAMAGED_ANVIL = "minecraft:damaged_anvil"; + public const DANDELION = "minecraft:dandelion"; public const DARK_OAK_BUTTON = "minecraft:dark_oak_button"; public const DARK_OAK_DOOR = "minecraft:dark_oak_door"; public const DARK_OAK_DOUBLE_SLAB = "minecraft:dark_oak_double_slab"; @@ -282,20 +309,39 @@ private function __construct(){ public const DARK_OAK_LOG = "minecraft:dark_oak_log"; public const DARK_OAK_PLANKS = "minecraft:dark_oak_planks"; public const DARK_OAK_PRESSURE_PLATE = "minecraft:dark_oak_pressure_plate"; + public const DARK_OAK_SAPLING = "minecraft:dark_oak_sapling"; public const DARK_OAK_SLAB = "minecraft:dark_oak_slab"; public const DARK_OAK_STAIRS = "minecraft:dark_oak_stairs"; public const DARK_OAK_TRAPDOOR = "minecraft:dark_oak_trapdoor"; public const DARK_OAK_WOOD = "minecraft:dark_oak_wood"; + public const DARK_PRISMARINE = "minecraft:dark_prismarine"; + public const DARK_PRISMARINE_DOUBLE_SLAB = "minecraft:dark_prismarine_double_slab"; + public const DARK_PRISMARINE_SLAB = "minecraft:dark_prismarine_slab"; public const DARK_PRISMARINE_STAIRS = "minecraft:dark_prismarine_stairs"; public const DARKOAK_STANDING_SIGN = "minecraft:darkoak_standing_sign"; public const DARKOAK_WALL_SIGN = "minecraft:darkoak_wall_sign"; 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_BRAIN_CORAL_WALL_FAN = "minecraft:dead_brain_coral_wall_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_BUBBLE_CORAL_WALL_FAN = "minecraft:dead_bubble_coral_wall_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_FIRE_CORAL_WALL_FAN = "minecraft:dead_fire_coral_wall_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_HORN_CORAL_WALL_FAN = "minecraft:dead_horn_coral_wall_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 DEAD_TUBE_CORAL_WALL_FAN = "minecraft:dead_tube_coral_wall_fan"; public const DEADBUSH = "minecraft:deadbush"; public const DECORATED_POT = "minecraft:decorated_pot"; public const DEEPSLATE = "minecraft:deepslate"; @@ -318,20 +364,18 @@ private function __construct(){ public const DEEPSLATE_TILE_WALL = "minecraft:deepslate_tile_wall"; public const DEEPSLATE_TILES = "minecraft:deepslate_tiles"; public const DENY = "minecraft:deny"; + public const DEPRECATED_ANVIL = "minecraft:deprecated_anvil"; public const DETECTOR_RAIL = "minecraft:detector_rail"; public const DIAMOND_BLOCK = "minecraft:diamond_block"; public const DIAMOND_ORE = "minecraft:diamond_ore"; public const DIORITE = "minecraft:diorite"; + public const DIORITE_DOUBLE_SLAB = "minecraft:diorite_double_slab"; + public const DIORITE_SLAB = "minecraft:diorite_slab"; public const DIORITE_STAIRS = "minecraft:diorite_stairs"; public const DIRT = "minecraft:dirt"; 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"; - public const DOUBLE_STONE_BLOCK_SLAB4 = "minecraft:double_stone_block_slab4"; public const DRAGON_EGG = "minecraft:dragon_egg"; public const DRIED_KELP_BLOCK = "minecraft:dried_kelp_block"; public const DRIPSTONE_BLOCK = "minecraft:dripstone_block"; @@ -465,6 +509,8 @@ private function __construct(){ public const END_PORTAL_FRAME = "minecraft:end_portal_frame"; public const END_ROD = "minecraft:end_rod"; public const END_STONE = "minecraft:end_stone"; + public const END_STONE_BRICK_DOUBLE_SLAB = "minecraft:end_stone_brick_double_slab"; + public const END_STONE_BRICK_SLAB = "minecraft:end_stone_brick_slab"; public const ENDER_CHEST = "minecraft:ender_chest"; public const EXPOSED_CHISELED_COPPER = "minecraft:exposed_chiseled_copper"; public const EXPOSED_COPPER = "minecraft:exposed_copper"; @@ -478,8 +524,12 @@ private function __construct(){ 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 FIRE_CORAL_WALL_FAN = "minecraft:fire_coral_wall_fan"; public const FLETCHING_TABLE = "minecraft:fletching_table"; public const FLOWER_POT = "minecraft:flower_pot"; public const FLOWERING_AZALEA = "minecraft:flowering_azalea"; @@ -500,6 +550,8 @@ private function __construct(){ public const GOLD_ORE = "minecraft:gold_ore"; public const GOLDEN_RAIL = "minecraft:golden_rail"; public const GRANITE = "minecraft:granite"; + public const GRANITE_DOUBLE_SLAB = "minecraft:granite_double_slab"; + public const GRANITE_SLAB = "minecraft:granite_slab"; public const GRANITE_STAIRS = "minecraft:granite_stairs"; public const GRASS_BLOCK = "minecraft:grass_block"; public const GRASS_PATH = "minecraft:grass_path"; @@ -564,13 +616,23 @@ private function __construct(){ public const HARD_YELLOW_STAINED_GLASS_PANE = "minecraft:hard_yellow_stained_glass_pane"; public const HARDENED_CLAY = "minecraft:hardened_clay"; public const HAY_BLOCK = "minecraft:hay_block"; + public const HEAVY_CORE = "minecraft:heavy_core"; public const HEAVY_WEIGHTED_PRESSURE_PLATE = "minecraft:heavy_weighted_pressure_plate"; public const HONEY_BLOCK = "minecraft:honey_block"; 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 HORN_CORAL_WALL_FAN = "minecraft:horn_coral_wall_fan"; public const ICE = "minecraft:ice"; + public const INFESTED_CHISELED_STONE_BRICKS = "minecraft:infested_chiseled_stone_bricks"; + public const INFESTED_COBBLESTONE = "minecraft:infested_cobblestone"; + public const INFESTED_CRACKED_STONE_BRICKS = "minecraft:infested_cracked_stone_bricks"; public const INFESTED_DEEPSLATE = "minecraft:infested_deepslate"; + public const INFESTED_MOSSY_STONE_BRICKS = "minecraft:infested_mossy_stone_bricks"; + public const INFESTED_STONE = "minecraft:infested_stone"; + public const INFESTED_STONE_BRICKS = "minecraft:infested_stone_bricks"; public const INFO_UPDATE = "minecraft:info_update"; public const INFO_UPDATE2 = "minecraft:info_update2"; public const INVISIBLE_BEDROCK = "minecraft:invisible_bedrock"; @@ -591,6 +653,7 @@ private function __construct(){ public const JUNGLE_LOG = "minecraft:jungle_log"; public const JUNGLE_PLANKS = "minecraft:jungle_planks"; public const JUNGLE_PRESSURE_PLATE = "minecraft:jungle_pressure_plate"; + public const JUNGLE_SAPLING = "minecraft:jungle_sapling"; public const JUNGLE_SLAB = "minecraft:jungle_slab"; public const JUNGLE_STAIRS = "minecraft:jungle_stairs"; public const JUNGLE_STANDING_SIGN = "minecraft:jungle_standing_sign"; @@ -603,10 +666,26 @@ private function __construct(){ 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"; - public const LIGHT_BLOCK = "minecraft:light_block"; + public const LIGHT_BLOCK_0 = "minecraft:light_block_0"; + public const LIGHT_BLOCK_1 = "minecraft:light_block_1"; + public const LIGHT_BLOCK_10 = "minecraft:light_block_10"; + public const LIGHT_BLOCK_11 = "minecraft:light_block_11"; + public const LIGHT_BLOCK_12 = "minecraft:light_block_12"; + public const LIGHT_BLOCK_13 = "minecraft:light_block_13"; + public const LIGHT_BLOCK_14 = "minecraft:light_block_14"; + public const LIGHT_BLOCK_15 = "minecraft:light_block_15"; + public const LIGHT_BLOCK_2 = "minecraft:light_block_2"; + public const LIGHT_BLOCK_3 = "minecraft:light_block_3"; + public const LIGHT_BLOCK_4 = "minecraft:light_block_4"; + public const LIGHT_BLOCK_5 = "minecraft:light_block_5"; + public const LIGHT_BLOCK_6 = "minecraft:light_block_6"; + public const LIGHT_BLOCK_7 = "minecraft:light_block_7"; + public const LIGHT_BLOCK_8 = "minecraft:light_block_8"; + public const LIGHT_BLOCK_9 = "minecraft:light_block_9"; public const LIGHT_BLUE_CANDLE = "minecraft:light_blue_candle"; public const LIGHT_BLUE_CANDLE_CAKE = "minecraft:light_blue_candle_cake"; public const LIGHT_BLUE_CARPET = "minecraft:light_blue_carpet"; @@ -630,6 +709,8 @@ private function __construct(){ 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"; public const LIME_CARPET = "minecraft:lime_carpet"; @@ -684,12 +765,16 @@ private function __construct(){ public const MELON_BLOCK = "minecraft:melon_block"; public const MELON_STEM = "minecraft:melon_stem"; public const MOB_SPAWNER = "minecraft:mob_spawner"; - public const MONSTER_EGG = "minecraft:monster_egg"; public const MOSS_BLOCK = "minecraft:moss_block"; public const MOSS_CARPET = "minecraft:moss_carpet"; public const MOSSY_COBBLESTONE = "minecraft:mossy_cobblestone"; + public const MOSSY_COBBLESTONE_DOUBLE_SLAB = "minecraft:mossy_cobblestone_double_slab"; + public const MOSSY_COBBLESTONE_SLAB = "minecraft:mossy_cobblestone_slab"; public const MOSSY_COBBLESTONE_STAIRS = "minecraft:mossy_cobblestone_stairs"; + public const MOSSY_STONE_BRICK_DOUBLE_SLAB = "minecraft:mossy_stone_brick_double_slab"; + public const MOSSY_STONE_BRICK_SLAB = "minecraft:mossy_stone_brick_slab"; public const MOSSY_STONE_BRICK_STAIRS = "minecraft:mossy_stone_brick_stairs"; + public const MOSSY_STONE_BRICKS = "minecraft:mossy_stone_bricks"; public const MOVING_BLOCK = "minecraft:moving_block"; public const MUD = "minecraft:mud"; public const MUD_BRICK_DOUBLE_SLAB = "minecraft:mud_brick_double_slab"; @@ -700,7 +785,9 @@ private function __construct(){ public const MUDDY_MANGROVE_ROOTS = "minecraft:muddy_mangrove_roots"; public const MYCELIUM = "minecraft:mycelium"; public const NETHER_BRICK = "minecraft:nether_brick"; + public const NETHER_BRICK_DOUBLE_SLAB = "minecraft:nether_brick_double_slab"; 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"; @@ -709,6 +796,8 @@ private function __construct(){ public const NETHERITE_BLOCK = "minecraft:netherite_block"; public const NETHERRACK = "minecraft:netherrack"; public const NETHERREACTOR = "minecraft:netherreactor"; + public const NORMAL_STONE_DOUBLE_SLAB = "minecraft:normal_stone_double_slab"; + public const NORMAL_STONE_SLAB = "minecraft:normal_stone_slab"; public const NORMAL_STONE_STAIRS = "minecraft:normal_stone_stairs"; public const NOTEBLOCK = "minecraft:noteblock"; public const OAK_DOUBLE_SLAB = "minecraft:oak_double_slab"; @@ -717,6 +806,7 @@ private function __construct(){ public const OAK_LEAVES = "minecraft:oak_leaves"; public const OAK_LOG = "minecraft:oak_log"; public const OAK_PLANKS = "minecraft:oak_planks"; + public const OAK_SAPLING = "minecraft:oak_sapling"; public const OAK_SLAB = "minecraft:oak_slab"; public const OAK_STAIRS = "minecraft:oak_stairs"; public const OAK_WOOD = "minecraft:oak_wood"; @@ -733,7 +823,9 @@ private function __construct(){ public const ORANGE_STAINED_GLASS = "minecraft:orange_stained_glass"; public const ORANGE_STAINED_GLASS_PANE = "minecraft:orange_stained_glass_pane"; public const ORANGE_TERRACOTTA = "minecraft:orange_terracotta"; + public const ORANGE_TULIP = "minecraft:orange_tulip"; public const ORANGE_WOOL = "minecraft:orange_wool"; + public const OXEYE_DAISY = "minecraft:oxeye_daisy"; public const OXIDIZED_CHISELED_COPPER = "minecraft:oxidized_chiseled_copper"; public const OXIDIZED_COPPER = "minecraft:oxidized_copper"; public const OXIDIZED_COPPER_BULB = "minecraft:oxidized_copper_bulb"; @@ -747,6 +839,9 @@ private function __construct(){ 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_DOUBLE_SLAB = "minecraft:petrified_oak_double_slab"; + 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"; @@ -758,6 +853,7 @@ private function __construct(){ public const PINK_STAINED_GLASS = "minecraft:pink_stained_glass"; public const PINK_STAINED_GLASS_PANE = "minecraft:pink_stained_glass_pane"; public const PINK_TERRACOTTA = "minecraft:pink_terracotta"; + public const PINK_TULIP = "minecraft:pink_tulip"; public const PINK_WOOL = "minecraft:pink_wool"; public const PISTON = "minecraft:piston"; public const PISTON_ARM_COLLISION = "minecraft:piston_arm_collision"; @@ -766,6 +862,8 @@ private function __construct(){ public const PODZOL = "minecraft:podzol"; public const POINTED_DRIPSTONE = "minecraft:pointed_dripstone"; public const POLISHED_ANDESITE = "minecraft:polished_andesite"; + public const POLISHED_ANDESITE_DOUBLE_SLAB = "minecraft:polished_andesite_double_slab"; + public const POLISHED_ANDESITE_SLAB = "minecraft:polished_andesite_slab"; public const POLISHED_ANDESITE_STAIRS = "minecraft:polished_andesite_stairs"; public const POLISHED_BASALT = "minecraft:polished_basalt"; public const POLISHED_BLACKSTONE = "minecraft:polished_blackstone"; @@ -786,21 +884,31 @@ private function __construct(){ public const POLISHED_DEEPSLATE_STAIRS = "minecraft:polished_deepslate_stairs"; public const POLISHED_DEEPSLATE_WALL = "minecraft:polished_deepslate_wall"; public const POLISHED_DIORITE = "minecraft:polished_diorite"; + public const POLISHED_DIORITE_DOUBLE_SLAB = "minecraft:polished_diorite_double_slab"; + public const POLISHED_DIORITE_SLAB = "minecraft:polished_diorite_slab"; public const POLISHED_DIORITE_STAIRS = "minecraft:polished_diorite_stairs"; public const POLISHED_GRANITE = "minecraft:polished_granite"; + public const POLISHED_GRANITE_DOUBLE_SLAB = "minecraft:polished_granite_double_slab"; + public const POLISHED_GRANITE_SLAB = "minecraft:polished_granite_slab"; public const POLISHED_GRANITE_STAIRS = "minecraft:polished_granite_stairs"; public const POLISHED_TUFF = "minecraft:polished_tuff"; public const POLISHED_TUFF_DOUBLE_SLAB = "minecraft:polished_tuff_double_slab"; public const POLISHED_TUFF_SLAB = "minecraft:polished_tuff_slab"; public const POLISHED_TUFF_STAIRS = "minecraft:polished_tuff_stairs"; public const POLISHED_TUFF_WALL = "minecraft:polished_tuff_wall"; + public const POPPY = "minecraft:poppy"; public const PORTAL = "minecraft:portal"; public const POTATOES = "minecraft:potatoes"; public const POWDER_SNOW = "minecraft:powder_snow"; public const POWERED_COMPARATOR = "minecraft:powered_comparator"; public const POWERED_REPEATER = "minecraft:powered_repeater"; public const PRISMARINE = "minecraft:prismarine"; + public const PRISMARINE_BRICK_DOUBLE_SLAB = "minecraft:prismarine_brick_double_slab"; + public const PRISMARINE_BRICK_SLAB = "minecraft:prismarine_brick_slab"; + public const PRISMARINE_BRICKS = "minecraft:prismarine_bricks"; public const PRISMARINE_BRICKS_STAIRS = "minecraft:prismarine_bricks_stairs"; + public const PRISMARINE_DOUBLE_SLAB = "minecraft:prismarine_double_slab"; + public const PRISMARINE_SLAB = "minecraft:prismarine_slab"; public const PRISMARINE_STAIRS = "minecraft:prismarine_stairs"; public const PUMPKIN = "minecraft:pumpkin"; public const PUMPKIN_STEM = "minecraft:pumpkin_stem"; @@ -816,10 +924,15 @@ private function __construct(){ public const PURPLE_TERRACOTTA = "minecraft:purple_terracotta"; public const PURPLE_WOOL = "minecraft:purple_wool"; public const PURPUR_BLOCK = "minecraft:purpur_block"; + public const PURPUR_DOUBLE_SLAB = "minecraft:purpur_double_slab"; + public const PURPUR_SLAB = "minecraft:purpur_slab"; public const PURPUR_STAIRS = "minecraft:purpur_stairs"; public const QUARTZ_BLOCK = "minecraft:quartz_block"; public const QUARTZ_BRICKS = "minecraft:quartz_bricks"; + public const QUARTZ_DOUBLE_SLAB = "minecraft:quartz_double_slab"; public const QUARTZ_ORE = "minecraft:quartz_ore"; + public const QUARTZ_PILLAR = "minecraft:quartz_pillar"; + 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"; @@ -830,18 +943,23 @@ private function __construct(){ public const RED_CARPET = "minecraft:red_carpet"; public const RED_CONCRETE = "minecraft:red_concrete"; public const RED_CONCRETE_POWDER = "minecraft:red_concrete_powder"; - public const RED_FLOWER = "minecraft:red_flower"; public const RED_GLAZED_TERRACOTTA = "minecraft:red_glazed_terracotta"; public const RED_MUSHROOM = "minecraft:red_mushroom"; public const RED_MUSHROOM_BLOCK = "minecraft:red_mushroom_block"; public const RED_NETHER_BRICK = "minecraft:red_nether_brick"; + public const RED_NETHER_BRICK_DOUBLE_SLAB = "minecraft:red_nether_brick_double_slab"; + public const RED_NETHER_BRICK_SLAB = "minecraft:red_nether_brick_slab"; public const RED_NETHER_BRICK_STAIRS = "minecraft:red_nether_brick_stairs"; + public const RED_SAND = "minecraft:red_sand"; public const RED_SANDSTONE = "minecraft:red_sandstone"; + public const RED_SANDSTONE_DOUBLE_SLAB = "minecraft:red_sandstone_double_slab"; + public const RED_SANDSTONE_SLAB = "minecraft:red_sandstone_slab"; public const RED_SANDSTONE_STAIRS = "minecraft:red_sandstone_stairs"; public const RED_SHULKER_BOX = "minecraft:red_shulker_box"; public const RED_STAINED_GLASS = "minecraft:red_stained_glass"; public const RED_STAINED_GLASS_PANE = "minecraft:red_stained_glass_pane"; public const RED_TERRACOTTA = "minecraft:red_terracotta"; + public const RED_TULIP = "minecraft:red_tulip"; public const RED_WOOL = "minecraft:red_wool"; public const REDSTONE_BLOCK = "minecraft:redstone_block"; public const REDSTONE_LAMP = "minecraft:redstone_lamp"; @@ -853,10 +971,12 @@ private function __construct(){ 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_DOUBLE_SLAB = "minecraft:sandstone_double_slab"; + public const SANDSTONE_SLAB = "minecraft:sandstone_slab"; public const SANDSTONE_STAIRS = "minecraft:sandstone_stairs"; - public const SAPLING = "minecraft:sapling"; public const SCAFFOLDING = "minecraft:scaffolding"; public const SCULK = "minecraft:sculk"; public const SCULK_CATALYST = "minecraft:sculk_catalyst"; @@ -866,6 +986,7 @@ private function __construct(){ 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"; @@ -875,10 +996,21 @@ private function __construct(){ public const SMITHING_TABLE = "minecraft:smithing_table"; public const SMOKER = "minecraft:smoker"; public const SMOOTH_BASALT = "minecraft:smooth_basalt"; + public const SMOOTH_QUARTZ = "minecraft:smooth_quartz"; + public const SMOOTH_QUARTZ_DOUBLE_SLAB = "minecraft:smooth_quartz_double_slab"; + public const SMOOTH_QUARTZ_SLAB = "minecraft:smooth_quartz_slab"; public const SMOOTH_QUARTZ_STAIRS = "minecraft:smooth_quartz_stairs"; + public const SMOOTH_RED_SANDSTONE = "minecraft:smooth_red_sandstone"; + public const SMOOTH_RED_SANDSTONE_DOUBLE_SLAB = "minecraft:smooth_red_sandstone_double_slab"; + public const SMOOTH_RED_SANDSTONE_SLAB = "minecraft:smooth_red_sandstone_slab"; public const SMOOTH_RED_SANDSTONE_STAIRS = "minecraft:smooth_red_sandstone_stairs"; + public const SMOOTH_SANDSTONE = "minecraft:smooth_sandstone"; + public const SMOOTH_SANDSTONE_DOUBLE_SLAB = "minecraft:smooth_sandstone_double_slab"; + public const SMOOTH_SANDSTONE_SLAB = "minecraft:smooth_sandstone_slab"; public const SMOOTH_SANDSTONE_STAIRS = "minecraft:smooth_sandstone_stairs"; public const SMOOTH_STONE = "minecraft:smooth_stone"; + public const SMOOTH_STONE_DOUBLE_SLAB = "minecraft:smooth_stone_double_slab"; + 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"; @@ -900,6 +1032,7 @@ private function __construct(){ public const SPRUCE_LOG = "minecraft:spruce_log"; public const SPRUCE_PLANKS = "minecraft:spruce_planks"; public const SPRUCE_PRESSURE_PLATE = "minecraft:spruce_pressure_plate"; + public const SPRUCE_SAPLING = "minecraft:spruce_sapling"; public const SPRUCE_SLAB = "minecraft:spruce_slab"; public const SPRUCE_STAIRS = "minecraft:spruce_stairs"; public const SPRUCE_STANDING_SIGN = "minecraft:spruce_standing_sign"; @@ -911,15 +1044,13 @@ private function __construct(){ 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_DOUBLE_SLAB = "minecraft:stone_brick_double_slab"; + public const STONE_BRICK_SLAB = "minecraft:stone_brick_slab"; public const STONE_BRICK_STAIRS = "minecraft:stone_brick_stairs"; + public const STONE_BRICKS = "minecraft:stone_bricks"; public const STONE_BUTTON = "minecraft:stone_button"; public const STONE_PRESSURE_PLATE = "minecraft:stone_pressure_plate"; public const STONE_STAIRS = "minecraft:stone_stairs"; - public const STONEBRICK = "minecraft:stonebrick"; public const STONECUTTER = "minecraft:stonecutter"; public const STONECUTTER_BLOCK = "minecraft:stonecutter_block"; public const STRIPPED_ACACIA_LOG = "minecraft:stripped_acacia_log"; @@ -945,10 +1076,11 @@ private function __construct(){ 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"; @@ -961,6 +1093,9 @@ private function __construct(){ 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 TUBE_CORAL_WALL_FAN = "minecraft:tube_coral_wall_fan"; public const TUFF = "minecraft:tuff"; public const TUFF_BRICK_DOUBLE_SLAB = "minecraft:tuff_brick_double_slab"; public const TUFF_BRICK_SLAB = "minecraft:tuff_brick_slab"; @@ -1068,6 +1203,7 @@ private function __construct(){ public const WHITE_STAINED_GLASS = "minecraft:white_stained_glass"; public const WHITE_STAINED_GLASS_PANE = "minecraft:white_stained_glass_pane"; public const WHITE_TERRACOTTA = "minecraft:white_terracotta"; + public const WHITE_TULIP = "minecraft:white_tulip"; public const WHITE_WOOL = "minecraft:white_wool"; public const WITHER_ROSE = "minecraft:wither_rose"; public const WOODEN_BUTTON = "minecraft:wooden_button"; @@ -1078,7 +1214,6 @@ private function __construct(){ public const YELLOW_CARPET = "minecraft:yellow_carpet"; public const YELLOW_CONCRETE = "minecraft:yellow_concrete"; public const YELLOW_CONCRETE_POWDER = "minecraft:yellow_concrete_powder"; - public const YELLOW_FLOWER = "minecraft:yellow_flower"; public const YELLOW_GLAZED_TERRACOTTA = "minecraft:yellow_glazed_terracotta"; public const YELLOW_SHULKER_BOX = "minecraft:yellow_shulker_box"; public const YELLOW_STAINED_GLASS = "minecraft:yellow_stained_glass"; diff --git a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php index 453fd75fd42..2b16a32ddef 100644 --- a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php +++ b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php @@ -43,6 +43,7 @@ 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\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; @@ -204,6 +206,7 @@ public function __construct(){ $this->registerCauldronSerializers(); $this->registerFlatWoodBlockSerializers(); $this->registerLeavesSerializers(); + $this->registerSaplingSerializers(); $this->registerSimpleSerializers(); $this->registerSerializers(); } @@ -537,6 +540,41 @@ private function registerFlatCoralSerializers() : void{ CoralType::TUBE => $block->isDead() ? Ids::DEAD_TUBE_CORAL : Ids::TUBE_CORAL, } )); + + $this->map(Blocks::CORAL_FAN(), fn(FloorCoralFan $block) => Writer::create( + match($block->getCoralType()){ + CoralType::BRAIN => $block->isDead() ? Ids::DEAD_BRAIN_CORAL_FAN : Ids::BRAIN_CORAL_FAN, + CoralType::BUBBLE => $block->isDead() ? Ids::DEAD_BUBBLE_CORAL_FAN : Ids::BUBBLE_CORAL_FAN, + CoralType::FIRE => $block->isDead() ? Ids::DEAD_FIRE_CORAL_FAN : Ids::FIRE_CORAL_FAN, + CoralType::HORN => $block->isDead() ? Ids::DEAD_HORN_CORAL_FAN : Ids::HORN_CORAL_FAN, + CoralType::TUBE => $block->isDead() ? Ids::DEAD_TUBE_CORAL_FAN : Ids::TUBE_CORAL_FAN, + }) + ->writeInt(StateNames::CORAL_FAN_DIRECTION, match($axis = $block->getAxis()){ + Axis::X => 0, + 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, + } + )); + + $this->map(Blocks::WALL_CORAL_FAN(), fn(WallCoralFan $block) => Writer::create( + match($block->getCoralType()){ + CoralType::TUBE => $block->isDead() ? Ids::DEAD_TUBE_CORAL_WALL_FAN : Ids::TUBE_CORAL_WALL_FAN, + CoralType::BRAIN => $block->isDead() ? Ids::DEAD_BRAIN_CORAL_WALL_FAN : Ids::BRAIN_CORAL_WALL_FAN, + CoralType::BUBBLE => $block->isDead() ? Ids::DEAD_BUBBLE_CORAL_WALL_FAN : Ids::BUBBLE_CORAL_WALL_FAN, + CoralType::FIRE => $block->isDead() ? Ids::DEAD_FIRE_CORAL_WALL_FAN : Ids::FIRE_CORAL_WALL_FAN, + CoralType::HORN => $block->isDead() ? Ids::DEAD_HORN_CORAL_WALL_FAN : Ids::HORN_CORAL_WALL_FAN, + }) + ->writeCoralFacing($block->getFacing()) + ); } private function registerCauldronSerializers() : void{ @@ -726,6 +764,19 @@ private function registerLeavesSerializers() : void{ $this->map(Blocks::SPRUCE_LEAVES(), fn(Leaves $block) => Helper::encodeLeaves($block, new Writer(Ids::SPRUCE_LEAVES))); } + private function registerSaplingSerializers() : void{ + foreach([ + Ids::ACACIA_SAPLING => Blocks::ACACIA_SAPLING(), + Ids::BIRCH_SAPLING => Blocks::BIRCH_SAPLING(), + Ids::DARK_OAK_SAPLING => Blocks::DARK_OAK_SAPLING(), + Ids::JUNGLE_SAPLING => Blocks::JUNGLE_SAPLING(), + Ids::OAK_SAPLING => Blocks::OAK_SAPLING(), + Ids::SPRUCE_SAPLING => Blocks::SPRUCE_SAPLING(), + ] as $id => $block){ + $this->map($block, fn(Sapling $block) => Helper::encodeSapling($block, new Writer($id))); + } + } + private function registerSimpleSerializers() : void{ $this->mapSimple(Blocks::AIR(), Ids::AIR); $this->mapSimple(Blocks::AMETHYST(), Ids::AMETHYST_BLOCK); @@ -745,6 +796,11 @@ private function registerSimpleSerializers() : void{ $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_RED_SANDSTONE(), Ids::CHISELED_RED_SANDSTONE); + $this->mapSimple(Blocks::CHISELED_SANDSTONE(), Ids::CHISELED_SANDSTONE); + $this->mapSimple(Blocks::CHISELED_STONE_BRICKS(), Ids::CHISELED_STONE_BRICKS); + $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); @@ -757,10 +813,14 @@ private function registerSimpleSerializers() : void{ $this->mapSimple(Blocks::CRACKED_DEEPSLATE_TILES(), Ids::CRACKED_DEEPSLATE_TILES); $this->mapSimple(Blocks::CRACKED_NETHER_BRICKS(), Ids::CRACKED_NETHER_BRICKS); $this->mapSimple(Blocks::CRACKED_POLISHED_BLACKSTONE_BRICKS(), Ids::CRACKED_POLISHED_BLACKSTONE_BRICKS); + $this->mapSimple(Blocks::CRACKED_STONE_BRICKS(), Ids::CRACKED_STONE_BRICKS); $this->mapSimple(Blocks::CRAFTING_TABLE(), Ids::CRAFTING_TABLE); $this->mapSimple(Blocks::CRIMSON_ROOTS(), Ids::CRIMSON_ROOTS); $this->mapSimple(Blocks::CRYING_OBSIDIAN(), Ids::CRYING_OBSIDIAN); - $this->mapSimple(Blocks::DANDELION(), Ids::YELLOW_FLOWER); + $this->mapSimple(Blocks::DANDELION(), Ids::DANDELION); + $this->mapSimple(Blocks::CUT_RED_SANDSTONE(), Ids::CUT_RED_SANDSTONE); + $this->mapSimple(Blocks::CUT_SANDSTONE(), Ids::CUT_SANDSTONE); + $this->mapSimple(Blocks::DARK_PRISMARINE(), Ids::DARK_PRISMARINE); $this->mapSimple(Blocks::DEAD_BUSH(), Ids::DEADBUSH); $this->mapSimple(Blocks::DEEPSLATE_BRICKS(), Ids::DEEPSLATE_BRICKS); $this->mapSimple(Blocks::DEEPSLATE_COAL_ORE(), Ids::DEEPSLATE_COAL_ORE); @@ -900,6 +960,7 @@ private function registerSimpleSerializers() : void{ $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); @@ -918,6 +979,12 @@ private function registerSimpleSerializers() : void{ $this->mapSimple(Blocks::HARDENED_GLASS_PANE(), Ids::HARD_GLASS_PANE); $this->mapSimple(Blocks::HONEYCOMB(), Ids::HONEYCOMB_BLOCK); $this->mapSimple(Blocks::ICE(), Ids::ICE); + $this->mapSimple(Blocks::INFESTED_CHISELED_STONE_BRICK(), Ids::INFESTED_CHISELED_STONE_BRICKS); + $this->mapSimple(Blocks::INFESTED_COBBLESTONE(), Ids::INFESTED_COBBLESTONE); + $this->mapSimple(Blocks::INFESTED_CRACKED_STONE_BRICK(), Ids::INFESTED_CRACKED_STONE_BRICKS); + $this->mapSimple(Blocks::INFESTED_MOSSY_STONE_BRICK(), Ids::INFESTED_MOSSY_STONE_BRICKS); + $this->mapSimple(Blocks::INFESTED_STONE(), Ids::INFESTED_STONE); + $this->mapSimple(Blocks::INFESTED_STONE_BRICK(), Ids::INFESTED_STONE_BRICKS); $this->mapSimple(Blocks::INFO_UPDATE(), Ids::INFO_UPDATE); $this->mapSimple(Blocks::INFO_UPDATE2(), Ids::INFO_UPDATE2); $this->mapSimple(Blocks::INVISIBLE_BEDROCK(), Ids::INVISIBLE_BEDROCK); @@ -934,6 +1001,7 @@ private function registerSimpleSerializers() : void{ $this->mapSimple(Blocks::MELON(), Ids::MELON_BLOCK); $this->mapSimple(Blocks::MONSTER_SPAWNER(), Ids::MOB_SPAWNER); $this->mapSimple(Blocks::MOSSY_COBBLESTONE(), Ids::MOSSY_COBBLESTONE); + $this->mapSimple(Blocks::MOSSY_STONE_BRICKS(), Ids::MOSSY_STONE_BRICKS); $this->mapSimple(Blocks::MUD(), Ids::MUD); $this->mapSimple(Blocks::MUD_BRICKS(), Ids::MUD_BRICKS); $this->mapSimple(Blocks::MYCELIUM(), Ids::MYCELIUM); @@ -956,6 +1024,9 @@ private function registerSimpleSerializers() : void{ $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::PRISMARINE(), Ids::PRISMARINE); + $this->mapSimple(Blocks::PRISMARINE_BRICKS(), Ids::PRISMARINE_BRICKS); $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); @@ -963,8 +1034,12 @@ private function registerSimpleSerializers() : void{ $this->mapSimple(Blocks::REDSTONE(), Ids::REDSTONE_BLOCK); $this->mapSimple(Blocks::RED_MUSHROOM(), Ids::RED_MUSHROOM); $this->mapSimple(Blocks::RED_NETHER_BRICKS(), Ids::RED_NETHER_BRICK); + $this->mapSimple(Blocks::RED_SAND(), Ids::RED_SAND); + $this->mapSimple(Blocks::RED_SANDSTONE(), Ids::RED_SANDSTONE); $this->mapSimple(Blocks::REINFORCED_DEEPSLATE(), Ids::REINFORCED_DEEPSLATE); $this->mapSimple(Blocks::RESERVED6(), Ids::RESERVED6); + $this->mapSimple(Blocks::SAND(), Ids::SAND); + $this->mapSimple(Blocks::SANDSTONE(), Ids::SANDSTONE); $this->mapSimple(Blocks::SCULK(), Ids::SCULK); $this->mapSimple(Blocks::SEA_LANTERN(), Ids::SEA_LANTERN); $this->mapSimple(Blocks::SHROOMLIGHT(), Ids::SHROOMLIGHT); @@ -972,28 +1047,43 @@ private function registerSimpleSerializers() : void{ $this->mapSimple(Blocks::SLIME(), Ids::SLIME); $this->mapSimple(Blocks::SMITHING_TABLE(), Ids::SMITHING_TABLE); $this->mapSimple(Blocks::SMOOTH_BASALT(), Ids::SMOOTH_BASALT); + $this->mapSimple(Blocks::SMOOTH_RED_SANDSTONE(), Ids::SMOOTH_RED_SANDSTONE); + $this->mapSimple(Blocks::SMOOTH_SANDSTONE(), Ids::SMOOTH_SANDSTONE); $this->mapSimple(Blocks::SMOOTH_STONE(), Ids::SMOOTH_STONE); $this->mapSimple(Blocks::SNOW(), Ids::SNOW); $this->mapSimple(Blocks::SOUL_SAND(), Ids::SOUL_SAND); $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::STONE_BRICKS(), Ids::STONE_BRICKS); + $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); + $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); + + $this->mapSimple(Blocks::ALLIUM(), Ids::ALLIUM); + $this->mapSimple(Blocks::CORNFLOWER(), Ids::CORNFLOWER); + $this->mapSimple(Blocks::AZURE_BLUET(), Ids::AZURE_BLUET); + $this->mapSimple(Blocks::LILY_OF_THE_VALLEY(), Ids::LILY_OF_THE_VALLEY); + $this->mapSimple(Blocks::BLUE_ORCHID(), Ids::BLUE_ORCHID); + $this->mapSimple(Blocks::OXEYE_DAISY(), Ids::OXEYE_DAISY); + $this->mapSimple(Blocks::POPPY(), Ids::POPPY); + $this->mapSimple(Blocks::ORANGE_TULIP(), Ids::ORANGE_TULIP); + $this->mapSimple(Blocks::PINK_TULIP(), Ids::PINK_TULIP); + $this->mapSimple(Blocks::RED_TULIP(), Ids::RED_TULIP); + $this->mapSimple(Blocks::WHITE_TULIP(), Ids::WHITE_TULIP); } private function registerSerializers() : void{ - $this->map(Blocks::ACACIA_SAPLING(), fn(Sapling $block) => Helper::encodeSapling($block, StringValues::SAPLING_TYPE_ACACIA)); $this->map(Blocks::ACTIVATOR_RAIL(), function(ActivatorRail $block) : Writer{ return Writer::create(Ids::ACTIVATOR_RAIL) ->writeBool(StateNames::RAIL_DATA_BIT, $block->isPowered()) ->writeInt(StateNames::RAIL_DIRECTION, $block->getShape()); }); - $this->map(Blocks::ALLIUM(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_ALLIUM)); $this->map(Blocks::ALL_SIDED_MUSHROOM_STEM(), fn() => Writer::create(Ids::BROWN_MUSHROOM_BLOCK) ->writeInt(StateNames::HUGE_MUSHROOM_BITS, BlockLegacyMetadata::MUSHROOM_BLOCK_ALL_STEM)); $this->map(Blocks::AMETHYST_CLUSTER(), fn(AmethystCluster $block) => Writer::create( @@ -1006,20 +1096,18 @@ private function registerSerializers() : void{ }) ->writeBlockFace($block->getFacing()) ); - $this->map(Blocks::ANDESITE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab3($block, StringValues::STONE_SLAB_TYPE_3_ANDESITE)); + $this->mapSlab(Blocks::ANDESITE_SLAB(), Ids::ANDESITE_SLAB, Ids::ANDESITE_DOUBLE_SLAB); $this->map(Blocks::ANDESITE_STAIRS(), fn(Stair $block) => Helper::encodeStairs($block, new Writer(Ids::ANDESITE_STAIRS))); $this->map(Blocks::ANDESITE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_ANDESITE)); - $this->map(Blocks::ANVIL(), function(Anvil $block) : Writer{ - return Writer::create(Ids::ANVIL) - ->writeCardinalHorizontalFacing($block->getFacing()) - ->writeString(StateNames::DAMAGE, match($damage = $block->getDamage()){ - 0 => StringValues::DAMAGE_UNDAMAGED, - 1 => StringValues::DAMAGE_SLIGHTLY_DAMAGED, - 2 => StringValues::DAMAGE_VERY_DAMAGED, - default => throw new BlockStateSerializeException("Invalid Anvil damage {$damage}"), - }); - }); - $this->map(Blocks::AZURE_BLUET(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_HOUSTONIA)); + $this->map(Blocks::ANVIL(), fn(Anvil $block) : Writer => Writer::create( + match($damage = $block->getDamage()){ + 0 => Ids::ANVIL, + 1 => Ids::CHIPPED_ANVIL, + 2 => Ids::DAMAGED_ANVIL, + default => throw new BlockStateSerializeException("Invalid Anvil damage {$damage}"), + }) + ->writeCardinalHorizontalFacing($block->getFacing()) + ); $this->map(Blocks::BAMBOO(), function(Bamboo $block) : Writer{ return Writer::create(Ids::BAMBOO) ->writeBool(StateNames::AGE_BIT, $block->isReady()) @@ -1033,10 +1121,7 @@ private function registerSerializers() : void{ }); $this->map(Blocks::BAMBOO_SAPLING(), function(BambooSapling $block) : Writer{ return Writer::create(Ids::BAMBOO_SAPLING) - ->writeBool(StateNames::AGE_BIT, $block->isReady()) - - //TODO: bug in MCPE - ->writeString(StateNames::SAPLING_TYPE, StringValues::SAPLING_TYPE_OAK); + ->writeBool(StateNames::AGE_BIT, $block->isReady()); }); $this->map(Blocks::BANNER(), function(FloorBanner $block) : Writer{ return Writer::create(Ids::STANDING_BANNER) @@ -1086,12 +1171,10 @@ private function registerSerializers() : void{ ->writeString(StateNames::BIG_DRIPLEAF_TILT, StringValues::BIG_DRIPLEAF_TILT_NONE) ->writeBool(StateNames::BIG_DRIPLEAF_HEAD, false); }); - $this->map(Blocks::BIRCH_SAPLING(), fn(Sapling $block) => Helper::encodeSapling($block, StringValues::SAPLING_TYPE_BIRCH)); $this->mapSlab(Blocks::BLACKSTONE_SLAB(), Ids::BLACKSTONE_SLAB, Ids::BLACKSTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::BLACKSTONE_STAIRS(), Ids::BLACKSTONE_STAIRS); $this->map(Blocks::BLACKSTONE_WALL(), fn(Wall $block) => Helper::encodeWall($block, new Writer(Ids::BLACKSTONE_WALL))); $this->map(Blocks::BLAST_FURNACE(), fn(Furnace $block) => Helper::encodeFurnace($block, Ids::BLAST_FURNACE, Ids::LIT_BLAST_FURNACE)); - $this->map(Blocks::BLUE_ORCHID(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_ORCHID)); $this->map(Blocks::BLUE_TORCH(), fn(Torch $block) => Helper::encodeColoredTorch($block, false, Writer::create(Ids::COLORED_TORCH_BP))); $this->map(Blocks::BONE_BLOCK(), function(BoneBlock $block) : Writer{ return Writer::create(Ids::BONE_BLOCK) @@ -1104,7 +1187,7 @@ private function registerSerializers() : void{ ->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->mapSlab(Blocks::BRICK_SLAB(), Ids::BRICK_SLAB, Ids::BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::BRICK_STAIRS(), Ids::BRICK_STAIRS); $this->map(Blocks::BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_BRICK)); $this->map(Blocks::BROWN_MUSHROOM_BLOCK(), fn(BrownMushroomBlock $block) => Helper::encodeMushroomBlock($block, new Writer(Ids::BROWN_MUSHROOM_BLOCK))); @@ -1116,6 +1199,11 @@ private function registerSerializers() : void{ 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) @@ -1149,10 +1237,7 @@ private function registerSerializers() : void{ ->writeLegacyHorizontalFacing($block->getFacing()) ->writeInt(StateNames::BOOKS_STORED, $flags); }); - $this->map(Blocks::CHISELED_QUARTZ(), fn(SimplePillar $block) => Helper::encodeQuartz(StringValues::CHISEL_TYPE_CHISELED, $block->getAxis())); - $this->map(Blocks::CHISELED_RED_SANDSTONE(), fn() => Helper::encodeSandstone(Ids::RED_SANDSTONE, StringValues::SAND_STONE_TYPE_HEIROGLYPHS)); - $this->map(Blocks::CHISELED_SANDSTONE(), fn() => Helper::encodeSandstone(Ids::SANDSTONE, StringValues::SAND_STONE_TYPE_HEIROGLYPHS)); - $this->map(Blocks::CHISELED_STONE_BRICKS(), fn() => Helper::encodeStoneBricks(StringValues::STONE_BRICK_TYPE_CHISELED)); + $this->map(Blocks::CHISELED_QUARTZ(), fn(SimplePillar $block) => Helper::encodeQuartz($block->getAxis(), Writer::create(Ids::CHISELED_QUARTZ_BLOCK))); $this->map(Blocks::CHORUS_FLOWER(), function(ChorusFlower $block) : Writer{ return Writer::create(Ids::CHORUS_FLOWER) ->writeInt(StateNames::AGE, $block->getAge()); @@ -1160,7 +1245,7 @@ private function registerSerializers() : void{ $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->mapSlab(Blocks::COBBLESTONE_SLAB(), Ids::COBBLESTONE_SLAB, Ids::COBBLESTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::COBBLESTONE_STAIRS(), Ids::STONE_STAIRS); $this->map(Blocks::COBBLESTONE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_COBBLESTONE)); $this->map(Blocks::COPPER(), function(Copper $block) : Writer{ @@ -1243,30 +1328,9 @@ private function registerSerializers() : void{ ->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::CORAL_FAN(), function(FloorCoralFan $block) : Writer{ - return Writer::create($block->isDead() ? Ids::CORAL_FAN_DEAD : Ids::CORAL_FAN) - ->writeCoralType($block->getCoralType()) - ->writeInt(StateNames::CORAL_FAN_DIRECTION, match($axis = $block->getAxis()){ - Axis::X => 0, - Axis::Z => 1, - default => throw new BlockStateSerializeException("Invalid axis {$axis}"), - }); - }); - $this->map(Blocks::CORNFLOWER(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_CORNFLOWER)); - $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)); - $this->map(Blocks::CUT_SANDSTONE(), fn() => Helper::encodeSandstone(Ids::SANDSTONE, StringValues::SAND_STONE_TYPE_CUT)); - $this->map(Blocks::CUT_SANDSTONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab4($block, StringValues::STONE_SLAB_TYPE_4_CUT_SANDSTONE)); - $this->map(Blocks::DARK_OAK_SAPLING(), fn(Sapling $block) => Helper::encodeSapling($block, StringValues::SAPLING_TYPE_DARK_OAK)); - $this->map(Blocks::DARK_PRISMARINE(), fn() => Writer::create(Ids::PRISMARINE) - ->writeString(StateNames::PRISMARINE_BLOCK_TYPE, StringValues::PRISMARINE_BLOCK_TYPE_DARK)); - $this->map(Blocks::DARK_PRISMARINE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab2($block, StringValues::STONE_SLAB_TYPE_2_PRISMARINE_DARK)); + $this->mapSlab(Blocks::CUT_RED_SANDSTONE_SLAB(), Ids::CUT_RED_SANDSTONE_SLAB, Ids::CUT_RED_SANDSTONE_DOUBLE_SLAB); + $this->mapSlab(Blocks::CUT_SANDSTONE_SLAB(), Ids::CUT_SANDSTONE_SLAB, Ids::CUT_SANDSTONE_DOUBLE_SLAB); + $this->mapSlab(Blocks::DARK_PRISMARINE_SLAB(), Ids::DARK_PRISMARINE_SLAB, Ids::DARK_PRISMARINE_DOUBLE_SLAB); $this->mapStairs(Blocks::DARK_PRISMARINE_STAIRS(), Ids::DARK_PRISMARINE_STAIRS); $this->map(Blocks::DAYLIGHT_SENSOR(), function(DaylightSensor $block) : Writer{ return Writer::create($block->isInverted() ? Ids::DAYLIGHT_DETECTOR_INVERTED : Ids::DAYLIGHT_DETECTOR) @@ -1288,22 +1352,17 @@ private function registerSerializers() : void{ ->writeBool(StateNames::RAIL_DATA_BIT, $block->isActivated()) ->writeInt(StateNames::RAIL_DIRECTION, $block->getShape()); }); - $this->map(Blocks::DIORITE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab3($block, StringValues::STONE_SLAB_TYPE_3_DIORITE)); + $this->mapSlab(Blocks::DIORITE_SLAB(), Ids::DIORITE_SLAB, Ids::DIORITE_DOUBLE_SLAB); $this->mapStairs(Blocks::DIORITE_STAIRS(), Ids::DIORITE_STAIRS); $this->map(Blocks::DIORITE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_DIORITE)); $this->map(Blocks::DIRT(), function(Dirt $block) : Writer{ - $dirtType = $block->getDirtType(); - if($dirtType === DirtType::ROOTED){ - return new Writer(Ids::DIRT_WITH_ROOTS); - } - return Writer::create(Ids::DIRT) - ->writeString(StateNames::DIRT_TYPE, match($dirtType){ - DirtType::COARSE => StringValues::DIRT_TYPE_COARSE, - DirtType::NORMAL => StringValues::DIRT_TYPE_NORMAL, - //ROOTED was already checked above - }); + return Writer::create(match($block->getDirtType()){ + DirtType::NORMAL => Ids::DIRT, + DirtType::COARSE => Ids::COARSE_DIRT, + DirtType::ROOTED => Ids::DIRT_WITH_ROOTS, + }); }); - $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) @@ -1318,16 +1377,14 @@ private function registerSerializers() : void{ return Writer::create(Ids::END_ROD) ->writeEndRodFacingDirection($block->getFacing()); }); - $this->map(Blocks::END_STONE_BRICK_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab3($block, StringValues::STONE_SLAB_TYPE_3_END_STONE_BRICK)); + $this->mapSlab(Blocks::END_STONE_BRICK_SLAB(), Ids::END_STONE_BRICK_SLAB, Ids::END_STONE_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::END_STONE_BRICK_STAIRS(), Ids::END_BRICK_STAIRS); $this->map(Blocks::END_STONE_BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_END_BRICK)); - $this->map(Blocks::FAKE_WOODEN_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab1($block, StringValues::STONE_SLAB_TYPE_WOOD)); + $this->mapSlab(Blocks::FAKE_WOODEN_SLAB(), Ids::PETRIFIED_OAK_SLAB, Ids::PETRIFIED_OAK_DOUBLE_SLAB); $this->map(Blocks::FARMLAND(), function(Farmland $block) : Writer{ return Writer::create(Ids::FARMLAND) ->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()); @@ -1354,7 +1411,7 @@ private function registerSerializers() : void{ ->writeFacingFlags($block->getFaces()); }); $this->map(Blocks::GLOWING_ITEM_FRAME(), fn(ItemFrame $block) => Helper::encodeItemFrame($block, Ids::GLOW_FRAME)); - $this->map(Blocks::GRANITE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab3($block, StringValues::STONE_SLAB_TYPE_3_GRANITE)); + $this->mapSlab(Blocks::GRANITE_SLAB(), Ids::GRANITE_SLAB, Ids::GRANITE_DOUBLE_SLAB); $this->mapStairs(Blocks::GRANITE_STAIRS(), Ids::GRANITE_STAIRS); $this->map(Blocks::GRANITE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_GRANITE)); $this->map(Blocks::GREEN_TORCH(), fn(Torch $block) => Helper::encodeColoredTorch($block, true, Writer::create(Ids::COLORED_TORCH_RG))); @@ -1368,22 +1425,9 @@ private function registerSerializers() : void{ ->writeBool(StateNames::TOGGLE_BIT, $block->isPowered()) ->writeFacingWithoutUp($block->getFacing()); }); - $this->map(Blocks::INFESTED_CHISELED_STONE_BRICK(), fn() => Writer::create(Ids::MONSTER_EGG) - ->writeString(StateNames::MONSTER_EGG_STONE_TYPE, StringValues::MONSTER_EGG_STONE_TYPE_CHISELED_STONE_BRICK)); - $this->map(Blocks::INFESTED_COBBLESTONE(), fn() => Writer::create(Ids::MONSTER_EGG) - ->writeString(StateNames::MONSTER_EGG_STONE_TYPE, StringValues::MONSTER_EGG_STONE_TYPE_COBBLESTONE)); - $this->map(Blocks::INFESTED_CRACKED_STONE_BRICK(), fn() => Writer::create(Ids::MONSTER_EGG) - ->writeString(StateNames::MONSTER_EGG_STONE_TYPE, StringValues::MONSTER_EGG_STONE_TYPE_CRACKED_STONE_BRICK)); - $this->map(Blocks::INFESTED_MOSSY_STONE_BRICK(), fn() => Writer::create(Ids::MONSTER_EGG) - ->writeString(StateNames::MONSTER_EGG_STONE_TYPE, StringValues::MONSTER_EGG_STONE_TYPE_MOSSY_STONE_BRICK)); - $this->map(Blocks::INFESTED_STONE(), fn() => Writer::create(Ids::MONSTER_EGG) - ->writeString(StateNames::MONSTER_EGG_STONE_TYPE, StringValues::MONSTER_EGG_STONE_TYPE_STONE)); - $this->map(Blocks::INFESTED_STONE_BRICK(), fn() => Writer::create(Ids::MONSTER_EGG) - ->writeString(StateNames::MONSTER_EGG_STONE_TYPE, StringValues::MONSTER_EGG_STONE_TYPE_STONE_BRICK)); $this->map(Blocks::IRON_DOOR(), fn(Door $block) => Helper::encodeDoor($block, new Writer(Ids::IRON_DOOR))); $this->map(Blocks::IRON_TRAPDOOR(), fn(Trapdoor $block) => Helper::encodeTrapdoor($block, new Writer(Ids::IRON_TRAPDOOR))); $this->map(Blocks::ITEM_FRAME(), fn(ItemFrame $block) => Helper::encodeItemFrame($block, Ids::FRAME)); - $this->map(Blocks::JUNGLE_SAPLING(), fn(Sapling $block) => Helper::encodeSapling($block, StringValues::SAPLING_TYPE_JUNGLE)); $this->map(Blocks::LAB_TABLE(), fn(ChemistryTable $block) => Helper::encodeChemistryTable($block, StringValues::CHEMISTRY_TABLE_TYPE_LAB_TABLE, new Writer(Ids::CHEMISTRY_TABLE))); $this->map(Blocks::LADDER(), function(Ladder $block) : Writer{ return Writer::create(Ids::LADDER) @@ -1393,7 +1437,7 @@ private function registerSerializers() : void{ 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) @@ -1415,15 +1459,31 @@ private function registerSerializers() : void{ }); }); $this->map(Blocks::LIGHT(), function(Light $block) : Writer{ - return Writer::create(Ids::LIGHT_BLOCK) - ->writeInt(StateNames::BLOCK_LIGHT_LEVEL, $block->getLightLevel()); + return Writer::create(match($block->getLightLevel()){ + 0 => Ids::LIGHT_BLOCK_0, + 1 => Ids::LIGHT_BLOCK_1, + 2 => Ids::LIGHT_BLOCK_2, + 3 => Ids::LIGHT_BLOCK_3, + 4 => Ids::LIGHT_BLOCK_4, + 5 => Ids::LIGHT_BLOCK_5, + 6 => Ids::LIGHT_BLOCK_6, + 7 => Ids::LIGHT_BLOCK_7, + 8 => Ids::LIGHT_BLOCK_8, + 9 => Ids::LIGHT_BLOCK_9, + 10 => Ids::LIGHT_BLOCK_10, + 11 => Ids::LIGHT_BLOCK_11, + 12 => Ids::LIGHT_BLOCK_12, + 13 => Ids::LIGHT_BLOCK_13, + 14 => Ids::LIGHT_BLOCK_14, + 15 => Ids::LIGHT_BLOCK_15, + default => throw new BlockStateSerializeException("Invalid light level " . $block->getLightLevel()), + }); }); $this->map(Blocks::LIGHTNING_ROD(), function(LightningRod $block) : Writer{ 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::LILY_OF_THE_VALLEY(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_LILY_OF_THE_VALLEY)); + $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()); @@ -1438,11 +1498,10 @@ private function registerSerializers() : void{ return Writer::create(Ids::SKULL) ->writeFacingWithoutDown($block->getFacing()); }); - $this->map(Blocks::MOSSY_COBBLESTONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab2($block, StringValues::STONE_SLAB_TYPE_2_MOSSY_COBBLESTONE)); + $this->mapSlab(Blocks::MOSSY_COBBLESTONE_SLAB(), Ids::MOSSY_COBBLESTONE_SLAB, Ids::MOSSY_COBBLESTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::MOSSY_COBBLESTONE_STAIRS(), Ids::MOSSY_COBBLESTONE_STAIRS); $this->map(Blocks::MOSSY_COBBLESTONE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_MOSSY_COBBLESTONE)); - $this->map(Blocks::MOSSY_STONE_BRICKS(), fn() => Helper::encodeStoneBricks(StringValues::STONE_BRICK_TYPE_MOSSY)); - $this->map(Blocks::MOSSY_STONE_BRICK_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab4($block, StringValues::STONE_SLAB_TYPE_4_MOSSY_STONE_BRICK)); + $this->mapSlab(Blocks::MOSSY_STONE_BRICK_SLAB(), Ids::MOSSY_STONE_BRICK_SLAB, Ids::MOSSY_STONE_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::MOSSY_STONE_BRICK_STAIRS(), Ids::MOSSY_STONE_BRICK_STAIRS); $this->map(Blocks::MOSSY_STONE_BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_MOSSY_STONE_BRICK)); $this->mapSlab(Blocks::MUD_BRICK_SLAB(), Ids::MUD_BRICK_SLAB, Ids::MUD_BRICK_DOUBLE_SLAB); @@ -1452,7 +1511,7 @@ private function registerSerializers() : void{ ->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->mapSlab(Blocks::NETHER_BRICK_SLAB(), Ids::NETHER_BRICK_SLAB, Ids::NETHER_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::NETHER_BRICK_STAIRS(), Ids::NETHER_BRICK_STAIRS); $this->map(Blocks::NETHER_BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_NETHER_BRICK)); $this->map(Blocks::NETHER_PORTAL(), function(NetherPortal $block) : Writer{ @@ -1467,16 +1526,12 @@ private function registerSerializers() : void{ return Writer::create(Ids::NETHER_WART) ->writeInt(StateNames::AGE, $block->getAge()); }); - $this->map(Blocks::OAK_SAPLING(), fn(Sapling $block) => Helper::encodeSapling($block, StringValues::SAPLING_TYPE_OAK)); - $this->map(Blocks::ORANGE_TULIP(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_TULIP_ORANGE)); - $this->map(Blocks::OXEYE_DAISY(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_OXEYE)); - $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()) ->writeInt(StateNames::GROWTH, $block->getCount() - 1); }); - $this->map(Blocks::PINK_TULIP(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_TULIP_PINK)); $this->map(Blocks::PITCHER_PLANT(), function(DoublePlant $block) : Writer{ return Writer::create(Ids::PITCHER_PLANT) ->writeBool(StateNames::UPPER_BLOCK_BIT, $block->isTop()); @@ -1491,7 +1546,7 @@ private function registerSerializers() : void{ ->writeInt(StateNames::GROWTH, $block->getAge() + 1 + PitcherCrop::MAX_AGE) ->writeBool(StateNames::UPPER_BLOCK_BIT, $block->isTop()); }); - $this->map(Blocks::POLISHED_ANDESITE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab3($block, StringValues::STONE_SLAB_TYPE_3_POLISHED_ANDESITE)); + $this->mapSlab(Blocks::POLISHED_ANDESITE_SLAB(), Ids::POLISHED_ANDESITE_SLAB, Ids::POLISHED_ANDESITE_DOUBLE_SLAB); $this->mapStairs(Blocks::POLISHED_ANDESITE_STAIRS(), Ids::POLISHED_ANDESITE_STAIRS); $this->map(Blocks::POLISHED_BASALT(), function(SimplePillar $block) : Writer{ return Writer::create(Ids::POLISHED_BASALT) @@ -1508,24 +1563,22 @@ private function registerSerializers() : void{ $this->mapSlab(Blocks::POLISHED_DEEPSLATE_SLAB(), Ids::POLISHED_DEEPSLATE_SLAB, Ids::POLISHED_DEEPSLATE_DOUBLE_SLAB); $this->mapStairs(Blocks::POLISHED_DEEPSLATE_STAIRS(), Ids::POLISHED_DEEPSLATE_STAIRS); $this->map(Blocks::POLISHED_DEEPSLATE_WALL(), fn(Wall $block) => Helper::encodeWall($block, new Writer(Ids::POLISHED_DEEPSLATE_WALL))); - $this->map(Blocks::POLISHED_DIORITE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab3($block, StringValues::STONE_SLAB_TYPE_3_POLISHED_DIORITE)); + $this->mapSlab(Blocks::POLISHED_DIORITE_SLAB(), Ids::POLISHED_DIORITE_SLAB, Ids::POLISHED_DIORITE_DOUBLE_SLAB); $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->mapSlab(Blocks::POLISHED_GRANITE_SLAB(), Ids::POLISHED_GRANITE_SLAB, Ids::POLISHED_GRANITE_DOUBLE_SLAB); $this->mapStairs(Blocks::POLISHED_GRANITE_STAIRS(), Ids::POLISHED_GRANITE_STAIRS); - $this->map(Blocks::POPPY(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_POPPY)); + $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) ->writeBool(StateNames::RAIL_DATA_BIT, $block->isPowered()) ->writeInt(StateNames::RAIL_DIRECTION, $block->getShape()); }); - $this->map(Blocks::PRISMARINE(), fn() => Writer::create(Ids::PRISMARINE) - ->writeString(StateNames::PRISMARINE_BLOCK_TYPE, StringValues::PRISMARINE_BLOCK_TYPE_DEFAULT)); - $this->map(Blocks::PRISMARINE_BRICKS(), fn() => Writer::create(Ids::PRISMARINE) - ->writeString(StateNames::PRISMARINE_BLOCK_TYPE, StringValues::PRISMARINE_BLOCK_TYPE_BRICKS)); - $this->map(Blocks::PRISMARINE_BRICKS_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab2($block, StringValues::STONE_SLAB_TYPE_2_PRISMARINE_BRICK)); + $this->mapSlab(Blocks::PRISMARINE_BRICKS_SLAB(), Ids::PRISMARINE_BRICK_SLAB, Ids::PRISMARINE_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::PRISMARINE_BRICKS_STAIRS(), Ids::PRISMARINE_BRICKS_STAIRS); - $this->map(Blocks::PRISMARINE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab2($block, StringValues::STONE_SLAB_TYPE_2_PRISMARINE_ROUGH)); + $this->mapSlab(Blocks::PRISMARINE_SLAB(), Ids::PRISMARINE_SLAB, Ids::PRISMARINE_DOUBLE_SLAB); $this->mapStairs(Blocks::PRISMARINE_STAIRS(), Ids::PRISMARINE_STAIRS); $this->map(Blocks::PRISMARINE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_PRISMARINE)); $this->map(Blocks::PUMPKIN(), function() : Writer{ @@ -1544,11 +1597,11 @@ private function registerSerializers() : void{ ->writeString(StateNames::CHISEL_TYPE, StringValues::CHISEL_TYPE_LINES) ->writePillarAxis($block->getAxis()); }); - $this->map(Blocks::PURPUR_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab2($block, StringValues::STONE_SLAB_TYPE_2_PURPUR)); + $this->mapSlab(Blocks::PURPUR_SLAB(), Ids::PURPUR_SLAB, Ids::PURPUR_DOUBLE_SLAB); $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(), fn() => Helper::encodeQuartz(Axis::Y, Writer::create(Ids::QUARTZ_BLOCK))); + $this->map(Blocks::QUARTZ_PILLAR(), fn(SimplePillar $block) => Helper::encodeQuartz($block->getAxis(), Writer::create(Ids::QUARTZ_PILLAR))); + $this->mapSlab(Blocks::QUARTZ_SLAB(), Ids::QUARTZ_SLAB, Ids::QUARTZ_DOUBLE_SLAB); $this->mapStairs(Blocks::QUARTZ_STAIRS(), Ids::QUARTZ_STAIRS); $this->map(Blocks::RAIL(), function(Rail $block) : Writer{ return Writer::create(Ids::RAIL) @@ -1576,22 +1629,15 @@ private function registerSerializers() : void{ ->writeInt(StateNames::REDSTONE_SIGNAL, $block->getOutputSignalStrength()); }); $this->map(Blocks::RED_MUSHROOM_BLOCK(), fn(RedMushroomBlock $block) => Helper::encodeMushroomBlock($block, new Writer(Ids::RED_MUSHROOM_BLOCK))); - $this->map(Blocks::RED_NETHER_BRICK_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab2($block, StringValues::STONE_SLAB_TYPE_2_RED_NETHER_BRICK)); + $this->mapSlab(Blocks::RED_NETHER_BRICK_SLAB(), Ids::RED_NETHER_BRICK_SLAB, Ids::RED_NETHER_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::RED_NETHER_BRICK_STAIRS(), Ids::RED_NETHER_BRICK_STAIRS); $this->map(Blocks::RED_NETHER_BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_RED_NETHER_BRICK)); - $this->map(Blocks::RED_SAND(), fn() => Writer::create(Ids::SAND) - ->writeString(StateNames::SAND_TYPE, StringValues::SAND_TYPE_RED)); - $this->map(Blocks::RED_SANDSTONE(), fn() => Helper::encodeSandstone(Ids::RED_SANDSTONE, StringValues::SAND_STONE_TYPE_DEFAULT)); - $this->map(Blocks::RED_SANDSTONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab2($block, StringValues::STONE_SLAB_TYPE_2_RED_SANDSTONE)); + $this->mapSlab(Blocks::RED_SANDSTONE_SLAB(), Ids::RED_SANDSTONE_SLAB, Ids::RED_SANDSTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::RED_SANDSTONE_STAIRS(), Ids::RED_SANDSTONE_STAIRS); $this->map(Blocks::RED_SANDSTONE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_RED_SANDSTONE)); $this->map(Blocks::RED_TORCH(), fn(Torch $block) => Helper::encodeColoredTorch($block, false, Writer::create(Ids::COLORED_TORCH_RG))); - $this->map(Blocks::RED_TULIP(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_TULIP_RED)); - $this->map(Blocks::ROSE_BUSH(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, StringValues::DOUBLE_PLANT_TYPE_ROSE, Writer::create(Ids::DOUBLE_PLANT))); - $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::ROSE_BUSH(), fn(DoublePlant $block) => Helper::encodeDoublePlant($block, Writer::create(Ids::ROSE_BUSH))); + $this->mapSlab(Blocks::SANDSTONE_SLAB(), Ids::SANDSTONE_SLAB, Ids::SANDSTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::SANDSTONE_STAIRS(), Ids::SANDSTONE_STAIRS); $this->map(Blocks::SANDSTONE_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_SANDSTONE)); $this->map(Blocks::SEA_PICKLE(), function(SeaPickle $block) : Writer{ @@ -1605,21 +1651,24 @@ private function registerSerializers() : void{ ->writeBool(StateNames::UPPER_BLOCK_BIT, $block->isTop()); }); $this->map(Blocks::SMOKER(), fn(Furnace $block) => Helper::encodeFurnace($block, Ids::SMOKER, Ids::LIT_SMOKER)); - $this->map(Blocks::SMOOTH_QUARTZ(), fn() => Helper::encodeQuartz(StringValues::CHISEL_TYPE_SMOOTH, Axis::Y)); - $this->map(Blocks::SMOOTH_QUARTZ_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab4($block, StringValues::STONE_SLAB_TYPE_4_SMOOTH_QUARTZ)); + $this->map(Blocks::SMOOTH_QUARTZ(), fn() => Helper::encodeQuartz(Axis::Y, Writer::create(Ids::SMOOTH_QUARTZ))); + $this->mapSlab(Blocks::SMOOTH_QUARTZ_SLAB(), Ids::SMOOTH_QUARTZ_SLAB, Ids::SMOOTH_QUARTZ_DOUBLE_SLAB); $this->mapStairs(Blocks::SMOOTH_QUARTZ_STAIRS(), Ids::SMOOTH_QUARTZ_STAIRS); - $this->map(Blocks::SMOOTH_RED_SANDSTONE(), fn() => Helper::encodeSandstone(Ids::RED_SANDSTONE, StringValues::SAND_STONE_TYPE_SMOOTH)); - $this->map(Blocks::SMOOTH_RED_SANDSTONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab3($block, StringValues::STONE_SLAB_TYPE_3_SMOOTH_RED_SANDSTONE)); + $this->mapSlab(Blocks::SMOOTH_RED_SANDSTONE_SLAB(), Ids::SMOOTH_RED_SANDSTONE_SLAB, Ids::SMOOTH_RED_SANDSTONE_DOUBLE_SLAB); $this->mapStairs(Blocks::SMOOTH_RED_SANDSTONE_STAIRS(), Ids::SMOOTH_RED_SANDSTONE_STAIRS); - $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->mapSlab(Blocks::SMOOTH_SANDSTONE_SLAB(), Ids::SMOOTH_SANDSTONE_SLAB, Ids::SMOOTH_SANDSTONE_DOUBLE_SLAB); $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->mapSlab(Blocks::SMOOTH_STONE_SLAB(), Ids::SMOOTH_STONE_SLAB, Ids::SMOOTH_STONE_DOUBLE_SLAB); $this->map(Blocks::SNOW_LAYER(), function(SnowLayer $block) : Writer{ return Writer::create(Ids::SNOW_LAYER) ->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 @@ -1636,28 +1685,24 @@ private function registerSerializers() : void{ return Writer::create(Ids::SPONGE) ->writeString(StateNames::SPONGE_TYPE, $block->isWet() ? StringValues::SPONGE_TYPE_WET : StringValues::SPONGE_TYPE_DRY); }); - $this->map(Blocks::SPRUCE_SAPLING(), fn(Sapling $block) => Helper::encodeSapling($block, StringValues::SAPLING_TYPE_SPRUCE)); $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->mapSlab(Blocks::STONE_BRICK_SLAB(), Ids::STONE_BRICK_SLAB, Ids::STONE_BRICK_DOUBLE_SLAB); $this->mapStairs(Blocks::STONE_BRICK_STAIRS(), Ids::STONE_BRICK_STAIRS); $this->map(Blocks::STONE_BRICK_WALL(), fn(Wall $block) => Helper::encodeLegacyWall($block, StringValues::WALL_BLOCK_TYPE_STONE_BRICK)); $this->map(Blocks::STONE_BUTTON(), fn(StoneButton $block) => Helper::encodeButton($block, new Writer(Ids::STONE_BUTTON))); $this->map(Blocks::STONE_PRESSURE_PLATE(), fn(StonePressurePlate $block) => Helper::encodeSimplePressurePlate($block, new Writer(Ids::STONE_PRESSURE_PLATE))); - $this->map(Blocks::STONE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab4($block, StringValues::STONE_SLAB_TYPE_4_STONE)); + $this->mapSlab(Blocks::STONE_SLAB(), Ids::NORMAL_STONE_SLAB, Ids::NORMAL_STONE_DOUBLE_SLAB); $this->mapStairs(Blocks::STONE_STAIRS(), Ids::NORMAL_STONE_STAIRS); $this->map(Blocks::SUGARCANE(), function(Sugarcane $block) : Writer{ 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()) @@ -1688,6 +1733,12 @@ private function registerSerializers() : void{ ->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()); @@ -1704,17 +1755,6 @@ private function registerSerializers() : void{ return Writer::create(Ids::WALL_BANNER) ->writeHorizontalFacing($block->getFacing()); }); - $this->map(Blocks::WALL_CORAL_FAN(), function(WallCoralFan $block) : Writer{ - $coralType = $block->getCoralType(); - return Writer::create(match($coralType){ - CoralType::TUBE, CoralType::BRAIN => Ids::CORAL_FAN_HANG, - CoralType::BUBBLE, CoralType::FIRE => Ids::CORAL_FAN_HANG2, - CoralType::HORN => Ids::CORAL_FAN_HANG3, - }) - ->writeBool(StateNames::CORAL_HANG_TYPE_BIT, $coralType === CoralType::BRAIN || $coralType === CoralType::FIRE) - ->writeBool(StateNames::DEAD_BIT, $block->isDead()) - ->writeCoralFacing($block->getFacing()); - }); $this->map(Blocks::WATER(), fn(Water $block) => Helper::encodeLiquid($block, Ids::WATER, Ids::FLOWING_WATER)); $this->map(Blocks::WEEPING_VINES(), function(NetherVines $block) : Writer{ return Writer::create(Ids::WEEPING_VINES) @@ -1729,6 +1769,5 @@ private function registerSerializers() : void{ ->writeInt(StateNames::REDSTONE_SIGNAL, $block->getOutputSignalStrength()); }); $this->map(Blocks::WHEAT(), fn(Wheat $block) => Helper::encodeCrops($block, new Writer(Ids::WHEAT))); - $this->map(Blocks::WHITE_TULIP(), fn() => Helper::encodeRedFlower(StringValues::FLOWER_TYPE_TULIP_WHITE)); } } diff --git a/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php b/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php index 68bf14a7e34..c7447bd531d 100644 --- a/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php +++ b/src/data/bedrock/block/convert/BlockStateDeserializerHelper.php @@ -26,12 +26,10 @@ use pocketmine\block\Block; use pocketmine\block\Button; use pocketmine\block\Candle; -use pocketmine\block\Copper; -use pocketmine\block\CopperSlab; -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; @@ -41,12 +39,15 @@ use pocketmine\block\RedMushroomBlock; use pocketmine\block\RedstoneComparator; use pocketmine\block\RedstoneRepeater; +use pocketmine\block\Sapling; use pocketmine\block\SimplePressurePlate; use pocketmine\block\Slab; use pocketmine\block\Stair; use pocketmine\block\Stem; use pocketmine\block\Trapdoor; use pocketmine\block\utils\CopperOxidation; +use pocketmine\block\utils\ICopper; +use pocketmine\block\utils\SlabType; use pocketmine\block\VanillaBlocks; use pocketmine\block\Wall; use pocketmine\block\WallCoralFan; @@ -99,24 +100,24 @@ public static function decodeComparator(RedstoneComparator $block, BlockStateRea } /** - * @phpstan-template TBlock of Copper|CopperSlab|CopperStairs + * @phpstan-template TBlock of ICopper * * @phpstan-param TBlock $block * @phpstan-return TBlock */ - public static function decodeCopper(Copper|CopperSlab|CopperStairs $block, CopperOxidation $oxidation) : Copper|CopperSlab|CopperStairs{ + public static function decodeCopper(ICopper $block, CopperOxidation $oxidation) : ICopper{ $block->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; @@ -138,6 +139,12 @@ public static function decodeDoor(Door $block, BlockStateReader $in) : Door{ ->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 @@ -149,7 +156,6 @@ public static function decodeFenceGate(FenceGate $block, BlockStateReader $in) : /** @throws BlockStateDeserializeException */ public static function decodeFloorCoralFan(FloorCoralFan $block, BlockStateReader $in) : FloorCoralFan{ return $block - ->setCoralType($in->readCoralType()) ->setAxis(match($in->readBoundedInt(BlockStateNames::CORAL_FAN_DIRECTION, 0, 1)){ 0 => Axis::X, 1 => Axis::Z, @@ -220,6 +226,12 @@ public static function decodeRepeater(RedstoneRepeater $block, BlockStateReader ->setDelay($in->readBoundedInt(BlockStateNames::REPEATER_DELAY, 0, 3) + 1); } + /** @throws BlockStateDeserializeException */ + public static function decodeSapling(Sapling $block, BlockStateReader $in) : Sapling{ + return $block + ->setReady($in->readBool(BlockStateNames::AGE_BIT)); + } + /** @throws BlockStateDeserializeException */ public static function decodeSimplePressurePlate(SimplePressurePlate $block, BlockStateReader $in) : SimplePressurePlate{ //TODO: not sure what the deal is here ... seems like a mojang bug / artifact of bad implementation? @@ -227,6 +239,17 @@ public static function decodeSimplePressurePlate(SimplePressurePlate $block, Blo 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 @@ -301,65 +324,4 @@ public static function mapLegacyWallType(BlockStateReader $in) : Wall{ default => throw $in->badValueException(BlockStateNames::WALL_BLOCK_TYPE, $type), }, $in); } - - /** @throws BlockStateDeserializeException */ - public static function mapStoneSlab1Type(BlockStateReader $in) : Slab{ - //* stone_slab_type (StringTag) = brick, cobblestone, nether_brick, quartz, sandstone, smooth_stone, stone_brick, wood - return match($type = $in->readString(BlockStateNames::STONE_SLAB_TYPE)){ - StringValues::STONE_SLAB_TYPE_BRICK => VanillaBlocks::BRICK_SLAB(), - StringValues::STONE_SLAB_TYPE_COBBLESTONE => VanillaBlocks::COBBLESTONE_SLAB(), - StringValues::STONE_SLAB_TYPE_NETHER_BRICK => VanillaBlocks::NETHER_BRICK_SLAB(), - StringValues::STONE_SLAB_TYPE_QUARTZ => VanillaBlocks::QUARTZ_SLAB(), - StringValues::STONE_SLAB_TYPE_SANDSTONE => VanillaBlocks::SANDSTONE_SLAB(), - StringValues::STONE_SLAB_TYPE_SMOOTH_STONE => VanillaBlocks::SMOOTH_STONE_SLAB(), - StringValues::STONE_SLAB_TYPE_STONE_BRICK => VanillaBlocks::STONE_BRICK_SLAB(), - StringValues::STONE_SLAB_TYPE_WOOD => VanillaBlocks::FAKE_WOODEN_SLAB(), - default => throw $in->badValueException(BlockStateNames::STONE_SLAB_TYPE, $type), - }; - } - - /** @throws BlockStateDeserializeException */ - public static function mapStoneSlab2Type(BlockStateReader $in) : Slab{ - // * stone_slab_type_2 (StringTag) = mossy_cobblestone, prismarine_brick, prismarine_dark, prismarine_rough, purpur, red_nether_brick, red_sandstone, smooth_sandstone - return match($type = $in->readString(BlockStateNames::STONE_SLAB_TYPE_2)){ - StringValues::STONE_SLAB_TYPE_2_MOSSY_COBBLESTONE => VanillaBlocks::MOSSY_COBBLESTONE_SLAB(), - StringValues::STONE_SLAB_TYPE_2_PRISMARINE_BRICK => VanillaBlocks::PRISMARINE_BRICKS_SLAB(), - StringValues::STONE_SLAB_TYPE_2_PRISMARINE_DARK => VanillaBlocks::DARK_PRISMARINE_SLAB(), - StringValues::STONE_SLAB_TYPE_2_PRISMARINE_ROUGH => VanillaBlocks::PRISMARINE_SLAB(), - StringValues::STONE_SLAB_TYPE_2_PURPUR => VanillaBlocks::PURPUR_SLAB(), - StringValues::STONE_SLAB_TYPE_2_RED_NETHER_BRICK => VanillaBlocks::RED_NETHER_BRICK_SLAB(), - StringValues::STONE_SLAB_TYPE_2_RED_SANDSTONE => VanillaBlocks::RED_SANDSTONE_SLAB(), - StringValues::STONE_SLAB_TYPE_2_SMOOTH_SANDSTONE => VanillaBlocks::SMOOTH_SANDSTONE_SLAB(), - default => throw $in->badValueException(BlockStateNames::STONE_SLAB_TYPE_2, $type), - }; - } - - /** @throws BlockStateDeserializeException */ - public static function mapStoneSlab3Type(BlockStateReader $in) : Slab{ - // * stone_slab_type_3 (StringTag) = andesite, diorite, end_stone_brick, granite, polished_andesite, polished_diorite, polished_granite, smooth_red_sandstone - return match($type = $in->readString(BlockStateNames::STONE_SLAB_TYPE_3)){ - StringValues::STONE_SLAB_TYPE_3_ANDESITE => VanillaBlocks::ANDESITE_SLAB(), - StringValues::STONE_SLAB_TYPE_3_DIORITE => VanillaBlocks::DIORITE_SLAB(), - StringValues::STONE_SLAB_TYPE_3_END_STONE_BRICK => VanillaBlocks::END_STONE_BRICK_SLAB(), - StringValues::STONE_SLAB_TYPE_3_GRANITE => VanillaBlocks::GRANITE_SLAB(), - StringValues::STONE_SLAB_TYPE_3_POLISHED_ANDESITE => VanillaBlocks::POLISHED_ANDESITE_SLAB(), - StringValues::STONE_SLAB_TYPE_3_POLISHED_DIORITE => VanillaBlocks::POLISHED_DIORITE_SLAB(), - StringValues::STONE_SLAB_TYPE_3_POLISHED_GRANITE => VanillaBlocks::POLISHED_GRANITE_SLAB(), - StringValues::STONE_SLAB_TYPE_3_SMOOTH_RED_SANDSTONE => VanillaBlocks::SMOOTH_RED_SANDSTONE_SLAB(), - default => throw $in->badValueException(BlockStateNames::STONE_SLAB_TYPE_3, $type), - }; - } - - /** @throws BlockStateDeserializeException */ - public static function mapStoneSlab4Type(BlockStateReader $in) : Slab{ - // * stone_slab_type_4 (StringTag) = cut_red_sandstone, cut_sandstone, mossy_stone_brick, smooth_quartz, stone - return match($type = $in->readString(BlockStateNames::STONE_SLAB_TYPE_4)){ - StringValues::STONE_SLAB_TYPE_4_CUT_RED_SANDSTONE => VanillaBlocks::CUT_RED_SANDSTONE_SLAB(), - StringValues::STONE_SLAB_TYPE_4_CUT_SANDSTONE => VanillaBlocks::CUT_SANDSTONE_SLAB(), - StringValues::STONE_SLAB_TYPE_4_MOSSY_STONE_BRICK => VanillaBlocks::MOSSY_STONE_BRICK_SLAB(), - StringValues::STONE_SLAB_TYPE_4_SMOOTH_QUARTZ => VanillaBlocks::SMOOTH_QUARTZ_SLAB(), - StringValues::STONE_SLAB_TYPE_4_STONE => VanillaBlocks::STONE_SLAB(), - default => throw $in->badValueException(BlockStateNames::STONE_SLAB_TYPE_4, $type), - }; - } } diff --git a/src/data/bedrock/block/convert/BlockStateReader.php b/src/data/bedrock/block/convert/BlockStateReader.php index 07effd4f994..e3a02885f08 100644 --- a/src/data/bedrock/block/convert/BlockStateReader.php +++ b/src/data/bedrock/block/convert/BlockStateReader.php @@ -24,7 +24,6 @@ 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 @@ public function readTorchFacing() : int{ }; } - /** @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 68bb227cce3..9dfb17ca0c1 100644 --- a/src/data/bedrock/block/convert/BlockStateSerializerHelper.php +++ b/src/data/bedrock/block/convert/BlockStateSerializerHelper.php @@ -107,10 +107,9 @@ public static function encodeDoor(Door $block, Writer $out) : Writer{ ->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{ @@ -161,24 +160,14 @@ public static function encodeMushroomBlock(RedMushroomBlock $block, Writer $out) ->writeInt(BlockStateNames::HUGE_MUSHROOM_BITS, MushroomBlockTypeIdMap::getInstance()->toId($block->getMushroomBlockType())); } - public static function encodeQuartz(string $type, int $axis) : Writer{ - return Writer::create(Ids::QUARTZ_BLOCK) - ->writeString(BlockStateNames::CHISEL_TYPE, $type) + public static function encodeQuartz(int $axis, Writer $out) : Writer{ + return $out ->writePillarAxis($axis); //this isn't needed for all types, but we have to write it anyway } - public static function encodeRedFlower(string $type) : Writer{ - return Writer::create(Ids::RED_FLOWER)->writeString(BlockStateNames::FLOWER_TYPE, $type); - } - - public static function encodeSandstone(string $id, string $type) : Writer{ - return Writer::create($id)->writeString(BlockStateNames::SAND_STONE_TYPE, $type); - } - - public static function encodeSapling(Sapling $block, string $type) : Writer{ - return Writer::create(Ids::SAPLING) - ->writeBool(BlockStateNames::AGE_BIT, $block->isReady()) - ->writeString(BlockStateNames::SAPLING_TYPE, $type); + public static function encodeSapling(Sapling $block, Writer $out) : Writer{ + return $out + ->writeBool(BlockStateNames::AGE_BIT, $block->isReady()); } public static function encodeSimplePressurePlate(SimplePressurePlate $block, Writer $out) : Writer{ @@ -188,11 +177,21 @@ public static function encodeSimplePressurePlate(SimplePressurePlate $block, Wri ->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{ @@ -210,32 +209,6 @@ public static function encodeStem(Stem $block, Writer $out) : Writer{ ->writeFacingWithoutUp($facing === Facing::UP ? Facing::DOWN : $facing); } - public static function encodeStoneBricks(string $type) : Writer{ - return Writer::create(Ids::STONEBRICK) - ->writeString(BlockStateNames::STONE_BRICK_TYPE, $type); - } - - private static function encodeStoneSlab(Slab $block, string $singleId, string $doubleId, string $typeKey, string $typeValue) : Writer{ - return self::encodeSlab($block, $singleId, $doubleId) - ->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 encodeStoneSlab2(Slab $block, string $typeValue) : Writer{ - return self::encodeStoneSlab($block, Ids::STONE_BLOCK_SLAB2, Ids::DOUBLE_STONE_BLOCK_SLAB2, BlockStateNames::STONE_SLAB_TYPE_2, $typeValue); - } - - public static function encodeStoneSlab3(Slab $block, string $typeValue) : Writer{ - return self::encodeStoneSlab($block, Ids::STONE_BLOCK_SLAB3, Ids::DOUBLE_STONE_BLOCK_SLAB3, BlockStateNames::STONE_SLAB_TYPE_3, $typeValue); - } - - public static function encodeStoneSlab4(Slab $block, string $typeValue) : Writer{ - return self::encodeStoneSlab($block, Ids::STONE_BLOCK_SLAB4, Ids::DOUBLE_STONE_BLOCK_SLAB4, BlockStateNames::STONE_SLAB_TYPE_4, $typeValue); - } - public static function encodeTrapdoor(Trapdoor $block, Writer $out) : Writer{ return $out ->write5MinusHorizontalFacing($block->getFacing()) diff --git a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php index b82eeb14c67..2c2e75e9999 100644 --- a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php +++ b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php @@ -24,12 +24,13 @@ namespace pocketmine\data\bedrock\block\convert; use pocketmine\block\AmethystCluster; +use pocketmine\block\Anvil; use pocketmine\block\Bamboo; use pocketmine\block\Block; use pocketmine\block\CaveVines; use pocketmine\block\ChorusFlower; use pocketmine\block\DoublePitcherCrop; -use pocketmine\block\Light; +use pocketmine\block\Opaque; use pocketmine\block\PinkPetals; use pocketmine\block\PitcherCrop; use pocketmine\block\Slab; @@ -44,7 +45,6 @@ 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; @@ -83,6 +83,8 @@ public function __construct(){ $this->registerCauldronDeserializers(); $this->registerFlatWoodBlockDeserializers(); $this->registerLeavesDeserializers(); + $this->registerSaplingDeserializers(); + $this->registerLightDeserializers(); $this->registerSimpleDeserializers(); $this->registerDeserializers(); } @@ -114,11 +116,8 @@ public function mapSimple(string $id, \Closure $getBlock) : void{ * @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)); } /** @@ -438,6 +437,39 @@ private function registerFlatCoralDeserializers() : void{ ] as $id => $coralType){ $this->mapSimple($id, fn() => Blocks::CORAL()->setCoralType($coralType)->setDead(true)); } + + foreach([ + [CoralType::BRAIN, Ids::BRAIN_CORAL_FAN, Ids::DEAD_BRAIN_CORAL_FAN], + [CoralType::BUBBLE, Ids::BUBBLE_CORAL_FAN, Ids::DEAD_BUBBLE_CORAL_FAN], + [CoralType::FIRE, Ids::FIRE_CORAL_FAN, Ids::DEAD_FIRE_CORAL_FAN], + [CoralType::HORN, Ids::HORN_CORAL_FAN, Ids::DEAD_HORN_CORAL_FAN], + [CoralType::TUBE, Ids::TUBE_CORAL_FAN, Ids::DEAD_TUBE_CORAL_FAN], + ] as [$coralType, $aliveId, $deadId]){ + $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)); + } + + foreach([ + [CoralType::BRAIN, Ids::BRAIN_CORAL_WALL_FAN, Ids::DEAD_BRAIN_CORAL_WALL_FAN], + [CoralType::BUBBLE, Ids::BUBBLE_CORAL_WALL_FAN, Ids::DEAD_BUBBLE_CORAL_WALL_FAN], + [CoralType::FIRE, Ids::FIRE_CORAL_WALL_FAN, Ids::DEAD_FIRE_CORAL_WALL_FAN], + [CoralType::HORN, Ids::HORN_CORAL_WALL_FAN, Ids::DEAD_HORN_CORAL_WALL_FAN], + [CoralType::TUBE, Ids::TUBE_CORAL_WALL_FAN, Ids::DEAD_TUBE_CORAL_WALL_FAN], + ] as [$coralType, $aliveId, $deadId]){ + $this->map($aliveId, fn(Reader $in) => Blocks::WALL_CORAL_FAN()->setFacing($in->readCoralFacing())->setCoralType($coralType)->setDead(false)); + $this->map($deadId, fn(Reader $in) => Blocks::WALL_CORAL_FAN()->setFacing($in->readCoralFacing())->setCoralType($coralType)->setDead(true)); + } } private function registerCauldronDeserializers() : void{ @@ -622,6 +654,42 @@ private function registerLeavesDeserializers() : void{ $this->map(Ids::SPRUCE_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::SPRUCE_LEAVES(), $in)); } + private function registerSaplingDeserializers() : void{ + foreach([ + Ids::ACACIA_SAPLING => fn() => Blocks::ACACIA_SAPLING(), + Ids::BIRCH_SAPLING => fn() => Blocks::BIRCH_SAPLING(), + Ids::DARK_OAK_SAPLING => fn() => Blocks::DARK_OAK_SAPLING(), + Ids::JUNGLE_SAPLING => fn() => Blocks::JUNGLE_SAPLING(), + Ids::OAK_SAPLING => fn() => Blocks::OAK_SAPLING(), + Ids::SPRUCE_SAPLING => fn() => Blocks::SPRUCE_SAPLING(), + ] as $id => $getBlock){ + $this->map($id, fn(Reader $in) => Helper::decodeSapling($getBlock(), $in)); + } + } + + private function registerLightDeserializers() : void{ + foreach([ + Ids::LIGHT_BLOCK_0 => 0, + Ids::LIGHT_BLOCK_1 => 1, + Ids::LIGHT_BLOCK_2 => 2, + Ids::LIGHT_BLOCK_3 => 3, + Ids::LIGHT_BLOCK_4 => 4, + Ids::LIGHT_BLOCK_5 => 5, + Ids::LIGHT_BLOCK_6 => 6, + Ids::LIGHT_BLOCK_7 => 7, + Ids::LIGHT_BLOCK_8 => 8, + Ids::LIGHT_BLOCK_9 => 9, + Ids::LIGHT_BLOCK_10 => 10, + Ids::LIGHT_BLOCK_11 => 11, + Ids::LIGHT_BLOCK_12 => 12, + Ids::LIGHT_BLOCK_13 => 13, + Ids::LIGHT_BLOCK_14 => 14, + Ids::LIGHT_BLOCK_15 => 15, + ] as $id => $level){ + $this->mapSimple($id, fn() => Blocks::LIGHT()->setLightLevel($level)); + } + } + private function registerSimpleDeserializers() : void{ $this->mapSimple(Ids::AIR, fn() => Blocks::AIR()); $this->mapSimple(Ids::AMETHYST_BLOCK, fn() => Blocks::AMETHYST()); @@ -641,6 +709,11 @@ private function registerSimpleDeserializers() : void{ $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_RED_SANDSTONE, fn() => Blocks::CHISELED_RED_SANDSTONE()); + $this->mapSimple(Ids::CHISELED_SANDSTONE, fn() => Blocks::CHISELED_SANDSTONE()); + $this->mapSimple(Ids::CHISELED_STONE_BRICKS, fn() => Blocks::CHISELED_STONE_BRICKS()); + $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()); @@ -652,9 +725,13 @@ private function registerSimpleDeserializers() : void{ $this->mapSimple(Ids::CRACKED_DEEPSLATE_TILES, fn() => Blocks::CRACKED_DEEPSLATE_TILES()); $this->mapSimple(Ids::CRACKED_NETHER_BRICKS, fn() => Blocks::CRACKED_NETHER_BRICKS()); $this->mapSimple(Ids::CRACKED_POLISHED_BLACKSTONE_BRICKS, fn() => Blocks::CRACKED_POLISHED_BLACKSTONE_BRICKS()); + $this->mapSimple(Ids::CRACKED_STONE_BRICKS, fn() => Blocks::CRACKED_STONE_BRICKS()); $this->mapSimple(Ids::CRAFTING_TABLE, fn() => Blocks::CRAFTING_TABLE()); $this->mapSimple(Ids::CRIMSON_ROOTS, fn() => Blocks::CRIMSON_ROOTS()); $this->mapSimple(Ids::CRYING_OBSIDIAN, fn() => Blocks::CRYING_OBSIDIAN()); + $this->mapSimple(Ids::CUT_RED_SANDSTONE, fn() => Blocks::CUT_RED_SANDSTONE()); + $this->mapSimple(Ids::CUT_SANDSTONE, fn() => Blocks::CUT_SANDSTONE()); + $this->mapSimple(Ids::DARK_PRISMARINE, fn() => Blocks::DARK_PRISMARINE()); $this->mapSimple(Ids::DEADBUSH, fn() => Blocks::DEAD_BUSH()); $this->mapSimple(Ids::DEEPSLATE_BRICKS, fn() => Blocks::DEEPSLATE_BRICKS()); $this->mapSimple(Ids::DEEPSLATE_COAL_ORE, fn() => Blocks::DEEPSLATE_COAL_ORE()); @@ -794,6 +871,7 @@ private function registerSimpleDeserializers() : void{ $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()); @@ -812,6 +890,12 @@ private function registerSimpleDeserializers() : void{ $this->mapSimple(Ids::HARDENED_CLAY, fn() => Blocks::HARDENED_CLAY()); $this->mapSimple(Ids::HONEYCOMB_BLOCK, fn() => Blocks::HONEYCOMB()); $this->mapSimple(Ids::ICE, fn() => Blocks::ICE()); + $this->mapSimple(Ids::INFESTED_CHISELED_STONE_BRICKS, fn() => Blocks::INFESTED_CHISELED_STONE_BRICK()); + $this->mapSimple(Ids::INFESTED_COBBLESTONE, fn() => Blocks::INFESTED_COBBLESTONE()); + $this->mapSimple(Ids::INFESTED_CRACKED_STONE_BRICKS, fn() => Blocks::INFESTED_CRACKED_STONE_BRICK()); + $this->mapSimple(Ids::INFESTED_MOSSY_STONE_BRICKS, fn() => Blocks::INFESTED_MOSSY_STONE_BRICK()); + $this->mapSimple(Ids::INFESTED_STONE, fn() => Blocks::INFESTED_STONE()); + $this->mapSimple(Ids::INFESTED_STONE_BRICKS, fn() => Blocks::INFESTED_STONE_BRICK()); $this->mapSimple(Ids::INFO_UPDATE, fn() => Blocks::INFO_UPDATE()); $this->mapSimple(Ids::INFO_UPDATE2, fn() => Blocks::INFO_UPDATE2()); $this->mapSimple(Ids::INVISIBLE_BEDROCK, fn() => Blocks::INVISIBLE_BEDROCK()); @@ -826,6 +910,7 @@ private function registerSimpleDeserializers() : void{ $this->mapSimple(Ids::MELON_BLOCK, fn() => Blocks::MELON()); $this->mapSimple(Ids::MOB_SPAWNER, fn() => Blocks::MONSTER_SPAWNER()); $this->mapSimple(Ids::MOSSY_COBBLESTONE, fn() => Blocks::MOSSY_COBBLESTONE()); + $this->mapSimple(Ids::MOSSY_STONE_BRICKS, fn() => Blocks::MOSSY_STONE_BRICKS()); $this->mapSimple(Ids::MUD, fn() => Blocks::MUD()); $this->mapSimple(Ids::MUD_BRICKS, fn() => Blocks::MUD_BRICKS()); $this->mapSimple(Ids::MYCELIUM, fn() => Blocks::MYCELIUM()); @@ -847,6 +932,9 @@ private function registerSimpleDeserializers() : void{ $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::PRISMARINE, fn() => Blocks::PRISMARINE()); + $this->mapSimple(Ids::PRISMARINE_BRICKS, fn() => Blocks::PRISMARINE_BRICKS()); $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()); @@ -854,15 +942,22 @@ private function registerSimpleDeserializers() : void{ $this->mapSimple(Ids::RAW_IRON_BLOCK, fn() => Blocks::RAW_IRON()); $this->mapSimple(Ids::RED_MUSHROOM, fn() => Blocks::RED_MUSHROOM()); $this->mapSimple(Ids::RED_NETHER_BRICK, fn() => Blocks::RED_NETHER_BRICKS()); + $this->mapSimple(Ids::RED_SAND, fn() => Blocks::RED_SAND()); + $this->mapSimple(Ids::RED_SANDSTONE, fn() => Blocks::RED_SANDSTONE()); $this->mapSimple(Ids::REDSTONE_BLOCK, fn() => Blocks::REDSTONE()); $this->mapSimple(Ids::REINFORCED_DEEPSLATE, fn() => Blocks::REINFORCED_DEEPSLATE()); $this->mapSimple(Ids::RESERVED6, fn() => Blocks::RESERVED6()); + $this->mapSimple(Ids::SAND, fn() => Blocks::SAND()); + $this->mapSimple(Ids::SANDSTONE, fn() => Blocks::SANDSTONE()); $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()); $this->mapSimple(Ids::SMOOTH_BASALT, fn() => Blocks::SMOOTH_BASALT()); + $this->mapSimple(Ids::SMOOTH_RED_SANDSTONE, fn() => Blocks::SMOOTH_RED_SANDSTONE()); + $this->mapSimple(Ids::SMOOTH_SANDSTONE, fn() => Blocks::SMOOTH_SANDSTONE()); $this->mapSimple(Ids::SMOOTH_STONE, fn() => Blocks::SMOOTH_STONE()); $this->mapSimple(Ids::SNOW, fn() => Blocks::SNOW()); $this->mapSimple(Ids::SOUL_SAND, fn() => Blocks::SOUL_SAND()); @@ -870,16 +965,30 @@ private function registerSimpleDeserializers() : void{ $this->mapSimple(Ids::SPORE_BLOSSOM, fn() => Blocks::SPORE_BLOSSOM()); $this->mapSimple(Ids::STONE, fn() => Blocks::STONE()); $this->mapSimple(Ids::STONECUTTER, fn() => Blocks::LEGACY_STONECUTTER()); + $this->mapSimple(Ids::STONE_BRICKS, fn() => Blocks::STONE_BRICKS()); $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()); $this->mapSimple(Ids::WATERLILY, fn() => Blocks::LILY_PAD()); $this->mapSimple(Ids::WEB, fn() => Blocks::COBWEB()); $this->mapSimple(Ids::WITHER_ROSE, fn() => Blocks::WITHER_ROSE()); - $this->mapSimple(Ids::YELLOW_FLOWER, fn() => Blocks::DANDELION()); + $this->mapSimple(Ids::DANDELION, fn() => Blocks::DANDELION()); + + $this->mapSimple(Ids::ALLIUM, fn() => Blocks::ALLIUM()); + $this->mapSimple(Ids::CORNFLOWER, fn() => Blocks::CORNFLOWER()); + $this->mapSimple(Ids::AZURE_BLUET, fn() => Blocks::AZURE_BLUET()); + $this->mapSimple(Ids::LILY_OF_THE_VALLEY, fn() => Blocks::LILY_OF_THE_VALLEY()); + $this->mapSimple(Ids::BLUE_ORCHID, fn() => Blocks::BLUE_ORCHID()); + $this->mapSimple(Ids::OXEYE_DAISY, fn() => Blocks::OXEYE_DAISY()); + $this->mapSimple(Ids::POPPY, fn() => Blocks::POPPY()); + $this->mapSimple(Ids::ORANGE_TULIP, fn() => Blocks::ORANGE_TULIP()); + $this->mapSimple(Ids::PINK_TULIP, fn() => Blocks::PINK_TULIP()); + $this->mapSimple(Ids::RED_TULIP, fn() => Blocks::RED_TULIP()); + $this->mapSimple(Ids::WHITE_TULIP, fn() => Blocks::WHITE_TULIP()); } private function registerDeserializers() : void{ @@ -893,16 +1002,21 @@ private function registerDeserializers() : void{ ->setStage(AmethystCluster::STAGE_CLUSTER) ->setFacing($in->readBlockFace()); }); + $this->mapSlab(Ids::ANDESITE_SLAB, Ids::ANDESITE_DOUBLE_SLAB, fn() => Blocks::ANDESITE_SLAB()); $this->mapStairs(Ids::ANDESITE_STAIRS, fn() => Blocks::ANDESITE_STAIRS()); $this->map(Ids::ANVIL, function(Reader $in) : Block{ return Blocks::ANVIL() - ->setDamage(match($value = $in->readString(StateNames::DAMAGE)){ - StringValues::DAMAGE_UNDAMAGED => 0, - StringValues::DAMAGE_SLIGHTLY_DAMAGED => 1, - StringValues::DAMAGE_VERY_DAMAGED => 2, - StringValues::DAMAGE_BROKEN => 0, - default => throw $in->badValueException(StateNames::DAMAGE, $value), - }) + ->setDamage(Anvil::UNDAMAGED) + ->setFacing($in->readCardinalHorizontalFacing()); + }); + $this->map(Ids::CHIPPED_ANVIL, function(Reader $in) : Block{ + return Blocks::ANVIL() + ->setDamage(Anvil::SLIGHTLY_DAMAGED) + ->setFacing($in->readCardinalHorizontalFacing()); + }); + $this->map(Ids::DAMAGED_ANVIL, function(Reader $in) : Block{ + return Blocks::ANVIL() + ->setDamage(Anvil::VERY_DAMAGED) ->setFacing($in->readCardinalHorizontalFacing()); }); $this->map(Ids::BAMBOO, function(Reader $in) : Block{ @@ -921,7 +1035,6 @@ private function registerDeserializers() : void{ }); }); $this->map(Ids::BAMBOO_SAPLING, function(Reader $in) : Block{ - $in->ignored(StateNames::SAPLING_TYPE); //bug in MCPE return Blocks::BAMBOO_SAPLING()->setReady($in->readBool(StateNames::AGE_BIT)); }); $this->map(Ids::BARREL, function(Reader $in) : Block{ @@ -984,6 +1097,7 @@ private function registerDeserializers() : void{ ->setSlot(BrewingStandSlot::SOUTHWEST, $in->readBool(StateNames::BREWING_STAND_SLOT_B_BIT)) ->setSlot(BrewingStandSlot::NORTHWEST, $in->readBool(StateNames::BREWING_STAND_SLOT_C_BIT)); }); + $this->mapSlab(Ids::BRICK_SLAB, Ids::BRICK_DOUBLE_SLAB, fn() => Blocks::BRICK_SLAB()); $this->mapStairs(Ids::BRICK_STAIRS, fn() => Blocks::BRICK_STAIRS()); $this->map(Ids::BROWN_MUSHROOM_BLOCK, fn(Reader $in) => Helper::decodeMushroomBlock(Blocks::BROWN_MUSHROOM_BLOCK(), $in)); $this->map(Ids::CACTUS, function(Reader $in) : Block{ @@ -994,6 +1108,11 @@ private function registerDeserializers() : void{ 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() @@ -1033,6 +1152,10 @@ private function registerDeserializers() : void{ return $block; }); + $this->map(Ids::CHISELED_QUARTZ_BLOCK, function(Reader $in) : Block{ + return Blocks::CHISELED_QUARTZ() + ->setAxis($in->readPillarAxis()); + }); $this->map(Ids::CHEMISTRY_TABLE, function(Reader $in) : Block{ return (match($type = $in->readString(StateNames::CHEMISTRY_TABLE_TYPE)){ StringValues::CHEMISTRY_TABLE_TYPE_COMPOUND_CREATOR => Blocks::COMPOUND_CREATOR(), @@ -1050,9 +1173,11 @@ private function registerDeserializers() : void{ return Blocks::CHORUS_FLOWER() ->setAge($in->readBoundedInt(StateNames::AGE, ChorusFlower::MIN_AGE, ChorusFlower::MAX_AGE)); }); + $this->map(Ids::COARSE_DIRT, fn() => Blocks::DIRT()->setDirtType(DirtType::COARSE)); $this->mapSlab(Ids::COBBLED_DEEPSLATE_SLAB, Ids::COBBLED_DEEPSLATE_DOUBLE_SLAB, fn() => Blocks::COBBLED_DEEPSLATE_SLAB()); $this->mapStairs(Ids::COBBLED_DEEPSLATE_STAIRS, fn() => Blocks::COBBLED_DEEPSLATE_STAIRS()); $this->map(Ids::COBBLED_DEEPSLATE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::COBBLED_DEEPSLATE_WALL(), $in)); + $this->mapSlab(Ids::COBBLESTONE_SLAB, Ids::COBBLESTONE_DOUBLE_SLAB, fn() => Blocks::COBBLESTONE_SLAB()); $this->map(Ids::COBBLESTONE_WALL, fn(Reader $in) => Helper::mapLegacyWallType($in)); $this->map(Ids::COCOA, function(Reader $in) : Block{ return Blocks::COCOA_POD() @@ -1073,24 +1198,9 @@ private function registerDeserializers() : void{ $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, fn(Reader $in) => Helper::decodeFloorCoralFan(Blocks::CORAL_FAN(), $in) - ->setDead(false)); - $this->map(Ids::CORAL_FAN_DEAD, fn(Reader $in) => Helper::decodeFloorCoralFan(Blocks::CORAL_FAN(), $in) - ->setDead(true)); - $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) - ->setCoralType($in->readBool(StateNames::CORAL_HANG_TYPE_BIT) ? CoralType::FIRE : CoralType::BUBBLE)); - $this->map(Ids::CORAL_FAN_HANG3, function(Reader $in) : Block{ - $in->ignored(StateNames::CORAL_HANG_TYPE_BIT); //the game always writes this, even though it's not used - return Helper::decodeWallCoralFan(Blocks::WALL_CORAL_FAN(), $in) - ->setCoralType(CoralType::HORN); - }); + $this->mapSlab(Ids::CUT_RED_SANDSTONE_SLAB, Ids::CUT_RED_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::CUT_RED_SANDSTONE_SLAB()); + $this->mapSlab(Ids::CUT_SANDSTONE_SLAB, Ids::CUT_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::CUT_SANDSTONE_SLAB()); + $this->mapSlab(Ids::DARK_PRISMARINE_SLAB, Ids::DARK_PRISMARINE_DOUBLE_SLAB, fn() => Blocks::DARK_PRISMARINE_SLAB()); $this->mapStairs(Ids::DARK_PRISMARINE_STAIRS, fn() => Blocks::DARK_PRISMARINE_STAIRS()); $this->map(Ids::DAYLIGHT_DETECTOR, fn(Reader $in) => Helper::decodeDaylightSensor(Blocks::DAYLIGHT_SENSOR(), $in) ->setInverted(false)); @@ -1112,27 +1222,16 @@ private function registerDeserializers() : void{ ->setActivated($in->readBool(StateNames::RAIL_DATA_BIT)) ->setShape($in->readBoundedInt(StateNames::RAIL_DIRECTION, 0, 5)); }); + $this->mapSlab(Ids::DIORITE_SLAB, Ids::DIORITE_DOUBLE_SLAB, fn() => Blocks::DIORITE_SLAB()); $this->mapStairs(Ids::DIORITE_STAIRS, fn() => Blocks::DIORITE_STAIRS()); - $this->map(Ids::DIRT, function(Reader $in) : Block{ - return Blocks::DIRT() - ->setDirtType(match($value = $in->readString(StateNames::DIRT_TYPE)){ - StringValues::DIRT_TYPE_NORMAL => DirtType::NORMAL, - StringValues::DIRT_TYPE_COARSE => DirtType::COARSE, - default => throw $in->badValueException(StateNames::DIRT_TYPE, $value), - }); - }); + $this->map(Ids::DIRT, fn() => Blocks::DIRT()->setDirtType(DirtType::NORMAL)); $this->map(Ids::DIRT_WITH_ROOTS, fn() => Blocks::DIRT()->setDirtType(DirtType::ROOTED)); - $this->map(Ids::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() @@ -1143,6 +1242,7 @@ private function registerDeserializers() : void{ return Blocks::END_ROD() ->setFacing($in->readEndRodFacingDirection()); }); + $this->mapSlab(Ids::END_STONE_BRICK_SLAB, Ids::END_STONE_BRICK_DOUBLE_SLAB, fn() => Blocks::END_STONE_BRICK_SLAB()); $this->map(Ids::ENDER_CHEST, function(Reader $in) : Block{ return Blocks::ENDER_CHEST() ->setFacing($in->readCardinalHorizontalFacing()); @@ -1182,6 +1282,7 @@ private function registerDeserializers() : void{ ->setPowered($in->readBool(StateNames::RAIL_DATA_BIT)) ->setShape($in->readBoundedInt(StateNames::RAIL_DIRECTION, 0, 5)); }); + $this->mapSlab(Ids::GRANITE_SLAB, Ids::GRANITE_DOUBLE_SLAB, fn() => Blocks::GRANITE_SLAB()); $this->mapStairs(Ids::GRANITE_STAIRS, fn() => Blocks::GRANITE_STAIRS()); $this->map(Ids::HAY_BLOCK, function(Reader $in) : Block{ $in->ignored(StateNames::DEPRECATED); @@ -1229,10 +1330,6 @@ private function registerDeserializers() : void{ default => throw $in->badValueException(StateNames::LEVER_DIRECTION, $value), }); }); - $this->map(Ids::LIGHT_BLOCK, function(Reader $in) : Block{ - return Blocks::LIGHT() - ->setLightLevel($in->readBoundedInt(StateNames::BLOCK_LIGHT_LEVEL, Light::MIN_LIGHT_LEVEL, Light::MAX_LIGHT_LEVEL)); - }); $this->map(Ids::LIGHTNING_ROD, function(Reader $in) : Block{ return Blocks::LIGHTNING_ROD() ->setFacing($in->readFacingDirection()); @@ -1276,18 +1373,9 @@ private function registerDeserializers() : void{ ->setFacing($in->readBlockFace()); }); $this->map(Ids::MELON_STEM, fn(Reader $in) => Helper::decodeStem(Blocks::MELON_STEM(), $in)); - $this->map(Ids::MONSTER_EGG, function(Reader $in) : Block{ - return match($type = $in->readString(StateNames::MONSTER_EGG_STONE_TYPE)){ - StringValues::MONSTER_EGG_STONE_TYPE_CHISELED_STONE_BRICK => Blocks::INFESTED_CHISELED_STONE_BRICK(), - StringValues::MONSTER_EGG_STONE_TYPE_COBBLESTONE => Blocks::INFESTED_COBBLESTONE(), - StringValues::MONSTER_EGG_STONE_TYPE_CRACKED_STONE_BRICK => Blocks::INFESTED_CRACKED_STONE_BRICK(), - StringValues::MONSTER_EGG_STONE_TYPE_MOSSY_STONE_BRICK => Blocks::INFESTED_MOSSY_STONE_BRICK(), - StringValues::MONSTER_EGG_STONE_TYPE_STONE => Blocks::INFESTED_STONE(), - StringValues::MONSTER_EGG_STONE_TYPE_STONE_BRICK => Blocks::INFESTED_STONE_BRICK(), - default => throw $in->badValueException(StateNames::MONSTER_EGG_STONE_TYPE, $type), - }; - }); + $this->mapSlab(Ids::MOSSY_COBBLESTONE_SLAB, Ids::MOSSY_COBBLESTONE_DOUBLE_SLAB, fn() => Blocks::MOSSY_COBBLESTONE_SLAB()); $this->mapStairs(Ids::MOSSY_COBBLESTONE_STAIRS, fn() => Blocks::MOSSY_COBBLESTONE_STAIRS()); + $this->mapSlab(Ids::MOSSY_STONE_BRICK_SLAB, Ids::MOSSY_STONE_BRICK_DOUBLE_SLAB, fn() => Blocks::MOSSY_STONE_BRICK_SLAB()); $this->mapStairs(Ids::MOSSY_STONE_BRICK_STAIRS, fn() => Blocks::MOSSY_STONE_BRICK_STAIRS()); $this->mapSlab(Ids::MUD_BRICK_SLAB, Ids::MUD_BRICK_DOUBLE_SLAB, fn() => Blocks::MUD_BRICK_SLAB()); $this->mapStairs(Ids::MUD_BRICK_STAIRS, fn() => Blocks::MUD_BRICK_STAIRS()); @@ -1296,11 +1384,13 @@ private function registerDeserializers() : void{ return Blocks::MUDDY_MANGROVE_ROOTS() ->setAxis($in->readPillarAxis()); }); + $this->mapSlab(Ids::NETHER_BRICK_SLAB, Ids::NETHER_BRICK_DOUBLE_SLAB, fn() => Blocks::NETHER_BRICK_SLAB()); $this->mapStairs(Ids::NETHER_BRICK_STAIRS, fn() => Blocks::NETHER_BRICK_STAIRS()); $this->map(Ids::NETHER_WART, function(Reader $in) : Block{ return Blocks::NETHER_WART() ->setAge($in->readBoundedInt(StateNames::AGE, 0, 3)); }); + $this->mapSlab(Ids::NORMAL_STONE_SLAB, Ids::NORMAL_STONE_DOUBLE_SLAB, fn() => Blocks::STONE_SLAB()); $this->mapStairs(Ids::NORMAL_STONE_STAIRS, fn() => Blocks::STONE_STAIRS()); $this->map(Ids::OCHRE_FROGLIGHT, fn(Reader $in) => Blocks::FROGLIGHT()->setFroglightType(FroglightType::OCHRE)->setAxis($in->readPillarAxis())); $this->map(Ids::OXIDIZED_COPPER, fn() => Helper::decodeCopper(Blocks::COPPER(), CopperOxidation::OXIDIZED)); @@ -1308,6 +1398,7 @@ private function registerDeserializers() : void{ $this->mapSlab(Ids::OXIDIZED_CUT_COPPER_SLAB, Ids::OXIDIZED_DOUBLE_CUT_COPPER_SLAB, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_SLAB(), CopperOxidation::OXIDIZED)); $this->mapStairs(Ids::OXIDIZED_CUT_COPPER_STAIRS, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_STAIRS(), CopperOxidation::OXIDIZED)); $this->map(Ids::PEARLESCENT_FROGLIGHT, fn(Reader $in) => Blocks::FROGLIGHT()->setFroglightType(FroglightType::PEARLESCENT)->setAxis($in->readPillarAxis())); + $this->mapSlab(Ids::PETRIFIED_OAK_SLAB, Ids::PETRIFIED_OAK_DOUBLE_SLAB, fn() => Blocks::FAKE_WOODEN_SLAB()); $this->map(Ids::PINK_PETALS, function(Reader $in) : Block{ //Pink petals only uses 0-3, but GROWTH state can go up to 7 $growth = $in->readBoundedInt(StateNames::GROWTH, 0, 7); @@ -1331,6 +1422,7 @@ private function registerDeserializers() : void{ return Blocks::PITCHER_PLANT() ->setTop($in->readBool(StateNames::UPPER_BLOCK_BIT)); }); + $this->mapSlab(Ids::POLISHED_ANDESITE_SLAB, Ids::POLISHED_ANDESITE_DOUBLE_SLAB, fn() => Blocks::POLISHED_ANDESITE_SLAB()); $this->mapStairs(Ids::POLISHED_ANDESITE_STAIRS, fn() => Blocks::POLISHED_ANDESITE_STAIRS()); $this->map(Ids::POLISHED_BASALT, function(Reader $in) : Block{ return Blocks::POLISHED_BASALT() @@ -1347,8 +1439,13 @@ private function registerDeserializers() : void{ $this->mapSlab(Ids::POLISHED_DEEPSLATE_SLAB, Ids::POLISHED_DEEPSLATE_DOUBLE_SLAB, fn() => Blocks::POLISHED_DEEPSLATE_SLAB()); $this->mapStairs(Ids::POLISHED_DEEPSLATE_STAIRS, fn() => Blocks::POLISHED_DEEPSLATE_STAIRS()); $this->map(Ids::POLISHED_DEEPSLATE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::POLISHED_DEEPSLATE_WALL(), $in)); + $this->mapSlab(Ids::POLISHED_DIORITE_SLAB, Ids::POLISHED_DIORITE_DOUBLE_SLAB, fn() => Blocks::POLISHED_DIORITE_SLAB()); $this->mapStairs(Ids::POLISHED_DIORITE_STAIRS, fn() => Blocks::POLISHED_DIORITE_STAIRS()); + $this->mapSlab(Ids::POLISHED_GRANITE_SLAB, Ids::POLISHED_GRANITE_DOUBLE_SLAB, fn() => Blocks::POLISHED_GRANITE_SLAB()); $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)){ @@ -1362,15 +1459,9 @@ private function registerDeserializers() : void{ $this->map(Ids::POWERED_COMPARATOR, fn(Reader $in) => Helper::decodeComparator(Blocks::REDSTONE_COMPARATOR(), $in)); $this->map(Ids::POWERED_REPEATER, fn(Reader $in) => Helper::decodeRepeater(Blocks::REDSTONE_REPEATER(), $in) ->setPowered(true)); - $this->map(Ids::PRISMARINE, function(Reader $in) : Block{ - return match($type = $in->readString(StateNames::PRISMARINE_BLOCK_TYPE)){ - StringValues::PRISMARINE_BLOCK_TYPE_BRICKS => Blocks::PRISMARINE_BRICKS(), - StringValues::PRISMARINE_BLOCK_TYPE_DARK => Blocks::DARK_PRISMARINE(), - StringValues::PRISMARINE_BLOCK_TYPE_DEFAULT => Blocks::PRISMARINE(), - default => throw $in->badValueException(StateNames::PRISMARINE_BLOCK_TYPE, $type), - }; - }); + $this->mapSlab(Ids::PRISMARINE_BRICK_SLAB, Ids::PRISMARINE_BRICK_DOUBLE_SLAB, fn() => Blocks::PRISMARINE_BRICKS_SLAB()); $this->mapStairs(Ids::PRISMARINE_BRICKS_STAIRS, fn() => Blocks::PRISMARINE_BRICKS_STAIRS()); + $this->mapSlab(Ids::PRISMARINE_SLAB, Ids::PRISMARINE_DOUBLE_SLAB, fn() => Blocks::PRISMARINE_SLAB()); $this->mapStairs(Ids::PRISMARINE_STAIRS, fn() => Blocks::PRISMARINE_STAIRS()); $this->map(Ids::PUMPKIN, function(Reader $in) : Block{ $in->ignored(StateNames::MC_CARDINAL_DIRECTION); //obsolete @@ -1391,55 +1482,26 @@ private function registerDeserializers() : void{ }; } }); + $this->mapSlab(Ids::PURPUR_SLAB, Ids::PURPUR_DOUBLE_SLAB, fn() => Blocks::PURPUR_SLAB()); $this->mapStairs(Ids::PURPUR_STAIRS, fn() => Blocks::PURPUR_STAIRS()); - $this->map(Ids::QUARTZ_BLOCK, function(Reader $in) : Block{ - switch($type = $in->readString(StateNames::CHISEL_TYPE)){ - case StringValues::CHISEL_TYPE_CHISELED: - return Blocks::CHISELED_QUARTZ()->setAxis($in->readPillarAxis()); - case StringValues::CHISEL_TYPE_DEFAULT: - $in->ignored(StateNames::PILLAR_AXIS); - return Blocks::QUARTZ(); - case StringValues::CHISEL_TYPE_LINES: - return Blocks::QUARTZ_PILLAR()->setAxis($in->readPillarAxis()); - case StringValues::CHISEL_TYPE_SMOOTH: - $in->ignored(StateNames::PILLAR_AXIS); - return Blocks::SMOOTH_QUARTZ(); - default: - return throw $in->badValueException(StateNames::CHISEL_TYPE, $type); - } + $this->map(Ids::QUARTZ_BLOCK, function(Reader $in) : Opaque{ + $in->ignored(StateNames::PILLAR_AXIS); + return Blocks::QUARTZ(); }); + $this->map(Ids::QUARTZ_PILLAR, function(Reader $in) : Block{ + return Blocks::QUARTZ_PILLAR() + ->setAxis($in->readPillarAxis()); + }); + $this->mapSlab(Ids::QUARTZ_SLAB, Ids::QUARTZ_DOUBLE_SLAB, fn() => Blocks::QUARTZ_SLAB()); $this->mapStairs(Ids::QUARTZ_STAIRS, fn() => Blocks::QUARTZ_STAIRS()); $this->map(Ids::RAIL, function(Reader $in) : Block{ return Blocks::RAIL() ->setShape($in->readBoundedInt(StateNames::RAIL_DIRECTION, 0, 9)); }); - $this->map(Ids::RED_FLOWER, function(Reader $in) : Block{ - return match($type = $in->readString(StateNames::FLOWER_TYPE)){ - StringValues::FLOWER_TYPE_ALLIUM => Blocks::ALLIUM(), - StringValues::FLOWER_TYPE_CORNFLOWER => Blocks::CORNFLOWER(), - StringValues::FLOWER_TYPE_HOUSTONIA => Blocks::AZURE_BLUET(), //wtf ??? - StringValues::FLOWER_TYPE_LILY_OF_THE_VALLEY => Blocks::LILY_OF_THE_VALLEY(), - StringValues::FLOWER_TYPE_ORCHID => Blocks::BLUE_ORCHID(), - StringValues::FLOWER_TYPE_OXEYE => Blocks::OXEYE_DAISY(), - StringValues::FLOWER_TYPE_POPPY => Blocks::POPPY(), - StringValues::FLOWER_TYPE_TULIP_ORANGE => Blocks::ORANGE_TULIP(), - StringValues::FLOWER_TYPE_TULIP_PINK => Blocks::PINK_TULIP(), - StringValues::FLOWER_TYPE_TULIP_RED => Blocks::RED_TULIP(), - StringValues::FLOWER_TYPE_TULIP_WHITE => Blocks::WHITE_TULIP(), - default => throw $in->badValueException(StateNames::FLOWER_TYPE, $type), - }; - }); $this->map(Ids::RED_MUSHROOM_BLOCK, fn(Reader $in) => Helper::decodeMushroomBlock(Blocks::RED_MUSHROOM_BLOCK(), $in)); + $this->mapSlab(Ids::RED_NETHER_BRICK_SLAB, Ids::RED_NETHER_BRICK_DOUBLE_SLAB, fn() => Blocks::RED_NETHER_BRICK_SLAB()); $this->mapStairs(Ids::RED_NETHER_BRICK_STAIRS, fn() => Blocks::RED_NETHER_BRICK_STAIRS()); - $this->map(Ids::RED_SANDSTONE, function(Reader $in) : Block{ - return match($type = $in->readString(StateNames::SAND_STONE_TYPE)){ - StringValues::SAND_STONE_TYPE_CUT => Blocks::CUT_RED_SANDSTONE(), - StringValues::SAND_STONE_TYPE_DEFAULT => Blocks::RED_SANDSTONE(), - StringValues::SAND_STONE_TYPE_HEIROGLYPHS => Blocks::CHISELED_RED_SANDSTONE(), - StringValues::SAND_STONE_TYPE_SMOOTH => Blocks::SMOOTH_RED_SANDSTONE(), - default => throw $in->badValueException(StateNames::SAND_STONE_TYPE, $type), - }; - }); + $this->mapSlab(Ids::RED_SANDSTONE_SLAB, Ids::RED_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::RED_SANDSTONE_SLAB()); $this->mapStairs(Ids::RED_SANDSTONE_STAIRS, fn() => Blocks::RED_SANDSTONE_STAIRS()); $this->map(Ids::REDSTONE_LAMP, function() : Block{ return Blocks::REDSTONE_LAMP() @@ -1462,35 +1524,8 @@ private function registerDeserializers() : void{ return Blocks::SUGARCANE() ->setAge($in->readBoundedInt(StateNames::AGE, 0, 15)); }); - $this->map(Ids::SAND, function(Reader $in) : Block{ - return match($value = $in->readString(StateNames::SAND_TYPE)){ - StringValues::SAND_TYPE_NORMAL => Blocks::SAND(), - StringValues::SAND_TYPE_RED => Blocks::RED_SAND(), - default => throw $in->badValueException(StateNames::SAND_TYPE, $value), - }; - }); - $this->map(Ids::SANDSTONE, function(Reader $in) : Block{ - return match($type = $in->readString(StateNames::SAND_STONE_TYPE)){ - StringValues::SAND_STONE_TYPE_CUT => Blocks::CUT_SANDSTONE(), - StringValues::SAND_STONE_TYPE_DEFAULT => Blocks::SANDSTONE(), - StringValues::SAND_STONE_TYPE_HEIROGLYPHS => Blocks::CHISELED_SANDSTONE(), - StringValues::SAND_STONE_TYPE_SMOOTH => Blocks::SMOOTH_SANDSTONE(), - default => throw $in->badValueException(StateNames::SAND_STONE_TYPE, $type), - }; - }); + $this->mapSlab(Ids::SANDSTONE_SLAB, Ids::SANDSTONE_DOUBLE_SLAB, fn() => Blocks::SANDSTONE_SLAB()); $this->mapStairs(Ids::SANDSTONE_STAIRS, fn() => Blocks::SANDSTONE_STAIRS()); - $this->map(Ids::SAPLING, function(Reader $in) : Block{ - return (match($type = $in->readString(StateNames::SAPLING_TYPE)){ - StringValues::SAPLING_TYPE_ACACIA => Blocks::ACACIA_SAPLING(), - StringValues::SAPLING_TYPE_BIRCH => Blocks::BIRCH_SAPLING(), - StringValues::SAPLING_TYPE_DARK_OAK => Blocks::DARK_OAK_SAPLING(), - StringValues::SAPLING_TYPE_JUNGLE => Blocks::JUNGLE_SAPLING(), - StringValues::SAPLING_TYPE_OAK => Blocks::OAK_SAPLING(), - StringValues::SAPLING_TYPE_SPRUCE => Blocks::SPRUCE_SAPLING(), - default => throw $in->badValueException(StateNames::SAPLING_TYPE, $type), - }) - ->setReady($in->readBool(StateNames::AGE_BIT)); - }); $this->map(Ids::SEA_PICKLE, function(Reader $in) : Block{ return Blocks::SEA_PICKLE() ->setCount($in->readBoundedInt(StateNames::CLUSTER_COUNT, 0, 3) + 1) @@ -1515,13 +1550,26 @@ private function registerDeserializers() : void{ ->setFacing($in->readCardinalHorizontalFacing()) ->setTop($in->readBool(StateNames::UPPER_BLOCK_BIT)); }); + $this->map(Ids::SMOOTH_QUARTZ, function(Reader $in) : Block{ + $in->ignored(StateNames::PILLAR_AXIS); + return Blocks::SMOOTH_QUARTZ(); + }); + $this->mapSlab(Ids::SMOOTH_QUARTZ_SLAB, Ids::SMOOTH_QUARTZ_DOUBLE_SLAB, fn() => Blocks::SMOOTH_QUARTZ_SLAB()); $this->mapStairs(Ids::SMOOTH_QUARTZ_STAIRS, fn() => Blocks::SMOOTH_QUARTZ_STAIRS()); + $this->mapSlab(Ids::SMOOTH_RED_SANDSTONE_SLAB, Ids::SMOOTH_RED_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::SMOOTH_RED_SANDSTONE_SLAB()); $this->mapStairs(Ids::SMOOTH_RED_SANDSTONE_STAIRS, fn() => Blocks::SMOOTH_RED_SANDSTONE_STAIRS()); + $this->mapSlab(Ids::SMOOTH_SANDSTONE_SLAB, Ids::SMOOTH_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::SMOOTH_SANDSTONE_SLAB()); $this->mapStairs(Ids::SMOOTH_SANDSTONE_STAIRS, fn() => Blocks::SMOOTH_SANDSTONE_STAIRS()); + $this->mapSlab(Ids::SMOOTH_STONE_SLAB, Ids::SMOOTH_STONE_DOUBLE_SLAB, fn() => Blocks::SMOOTH_STONE_SLAB()); $this->map(Ids::SNOW_LAYER, function(Reader $in) : Block{ $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(); @@ -1545,24 +1593,11 @@ private function registerDeserializers() : void{ return Blocks::BANNER() ->setRotation($in->readBoundedInt(StateNames::GROUND_SIGN_DIRECTION, 0, 15)); }); + $this->mapSlab(Ids::STONE_BRICK_SLAB, Ids::STONE_BRICK_DOUBLE_SLAB, fn() => Blocks::STONE_BRICK_SLAB()); $this->mapStairs(Ids::STONE_BRICK_STAIRS, fn() => Blocks::STONE_BRICK_STAIRS()); $this->map(Ids::STONE_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)); - $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)); $this->mapStairs(Ids::STONE_STAIRS, fn() => Blocks::COBBLESTONE_STAIRS()); - $this->map(Ids::STONEBRICK, function(Reader $in) : Block{ - return match($type = $in->readString(StateNames::STONE_BRICK_TYPE)){ - StringValues::STONE_BRICK_TYPE_SMOOTH, //TODO: bug in vanilla - StringValues::STONE_BRICK_TYPE_DEFAULT => Blocks::STONE_BRICKS(), - StringValues::STONE_BRICK_TYPE_CHISELED => Blocks::CHISELED_STONE_BRICKS(), - StringValues::STONE_BRICK_TYPE_CRACKED => Blocks::CRACKED_STONE_BRICKS(), - StringValues::STONE_BRICK_TYPE_MOSSY => Blocks::MOSSY_STONE_BRICKS(), - default => throw $in->badValueException(StateNames::STONE_BRICK_TYPE, $type), - }; - }); $this->map(Ids::STONECUTTER_BLOCK, function(Reader $in) : Block{ return Blocks::STONECUTTER() ->setFacing($in->readCardinalHorizontalFacing()); @@ -1573,13 +1608,6 @@ private function registerDeserializers() : void{ 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)) @@ -1611,6 +1639,12 @@ private function registerDeserializers() : void{ ->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/data/bedrock/block/convert/BlockStateWriter.php b/src/data/bedrock/block/convert/BlockStateWriter.php index 33e82a5c02d..63af92d1009 100644 --- a/src/data/bedrock/block/convert/BlockStateWriter.php +++ b/src/data/bedrock/block/convert/BlockStateWriter.php @@ -24,7 +24,6 @@ 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 @@ public function writeTorchFacing(int $facing) : self{ 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/block/upgrade/BlockStateUpgradeSchemaFlattenedName.php b/src/data/bedrock/block/upgrade/BlockStateUpgradeSchemaFlattenedName.php index d9cbc780e9a..1c95dd9c7f3 100644 --- a/src/data/bedrock/block/upgrade/BlockStateUpgradeSchemaFlattenedName.php +++ b/src/data/bedrock/block/upgrade/BlockStateUpgradeSchemaFlattenedName.php @@ -23,17 +23,28 @@ namespace pocketmine\data\bedrock\block\upgrade; +use function ksort; +use const SORT_STRING; + final class BlockStateUpgradeSchemaFlattenedName{ + /** + * @param string[] $flattenedValueRemaps + * @phpstan-param array $flattenedValueRemaps + */ public function __construct( public string $prefix, public string $flattenedProperty, - public string $suffix - ){} + public string $suffix, + public array $flattenedValueRemaps + ){ + ksort($this->flattenedValueRemaps, SORT_STRING); + } public function equals(self $that) : bool{ return $this->prefix === $that->prefix && $this->flattenedProperty === $that->flattenedProperty && - $this->suffix === $that->suffix; + $this->suffix === $that->suffix && + $this->flattenedValueRemaps === $that->flattenedValueRemaps; } } diff --git a/src/data/bedrock/block/upgrade/BlockStateUpgradeSchemaUtils.php b/src/data/bedrock/block/upgrade/BlockStateUpgradeSchemaUtils.php index 9c63d51f033..832631490a3 100644 --- a/src/data/bedrock/block/upgrade/BlockStateUpgradeSchemaUtils.php +++ b/src/data/bedrock/block/upgrade/BlockStateUpgradeSchemaUtils.php @@ -166,7 +166,8 @@ public static function fromJsonModel(BlockStateUpgradeSchemaModel $model, int $s $remap->newName ?? new BlockStateUpgradeSchemaFlattenedName( $remap->newFlattenedName->prefix, $remap->newFlattenedName->flattenedProperty, - $remap->newFlattenedName->suffix + $remap->newFlattenedName->suffix, + $remap->newFlattenedName->flattenedValueRemaps ?? [], ), array_map(fn(BlockStateUpgradeSchemaModelTag $tag) => self::jsonModelToTag($tag), $remap->newState ?? []), $remap->copiedState ?? [] @@ -301,7 +302,8 @@ public static function toJsonModel(BlockStateUpgradeSchema $schema) : BlockState new BlockStateUpgradeSchemaModelFlattenedName( $remap->newName->prefix, $remap->newName->flattenedProperty, - $remap->newName->suffix + $remap->newName->suffix, + $remap->newName->flattenedValueRemaps ), array_map(fn(Tag $tag) => self::tagToJsonModel($tag), $remap->newState), $remap->copiedState diff --git a/src/data/bedrock/block/upgrade/BlockStateUpgrader.php b/src/data/bedrock/block/upgrade/BlockStateUpgrader.php index f4a5b6e93e5..4a305d8bc35 100644 --- a/src/data/bedrock/block/upgrade/BlockStateUpgrader.php +++ b/src/data/bedrock/block/upgrade/BlockStateUpgrader.php @@ -142,7 +142,8 @@ private function applyStateRemapped(BlockStateUpgradeSchema $schema, BlockStateD }else{ $flattenedValue = $oldState[$remap->newName->flattenedProperty] ?? null; if($flattenedValue instanceof StringTag){ - $newName = sprintf("%s%s%s", $remap->newName->prefix, $flattenedValue->getValue(), $remap->newName->suffix); + $embedValue = $remap->newName->flattenedValueRemaps[$flattenedValue->getValue()] ?? $flattenedValue->getValue(); + $newName = sprintf("%s%s%s", $remap->newName->prefix, $embedValue, $remap->newName->suffix); unset($oldState[$remap->newName->flattenedProperty]); }else{ //flattened property is not a TAG_String, so this transformation is not applicable diff --git a/src/data/bedrock/block/upgrade/model/BlockStateUpgradeSchemaModelFlattenedName.php b/src/data/bedrock/block/upgrade/model/BlockStateUpgradeSchemaModelFlattenedName.php index 4508d9a3bea..001192f4789 100644 --- a/src/data/bedrock/block/upgrade/model/BlockStateUpgradeSchemaModelFlattenedName.php +++ b/src/data/bedrock/block/upgrade/model/BlockStateUpgradeSchemaModelFlattenedName.php @@ -23,7 +23,9 @@ namespace pocketmine\data\bedrock\block\upgrade\model; -final class BlockStateUpgradeSchemaModelFlattenedName{ +use function count; + +final class BlockStateUpgradeSchemaModelFlattenedName implements \JsonSerializable{ /** @required */ public string $prefix; @@ -31,10 +33,31 @@ final class BlockStateUpgradeSchemaModelFlattenedName{ public string $flattenedProperty; /** @required */ public string $suffix; + /** + * @var string[] + * @phpstan-var array + */ + public array $flattenedValueRemaps; - public function __construct(string $prefix, string $flattenedProperty, string $suffix){ + /** + * @param string[] $flattenedValueRemaps + * @phpstan-param array $flattenedValueRemaps + */ + public function __construct(string $prefix, string $flattenedProperty, string $suffix, array $flattenedValueRemaps){ $this->prefix = $prefix; $this->flattenedProperty = $flattenedProperty; $this->suffix = $suffix; + $this->flattenedValueRemaps = $flattenedValueRemaps; + } + + /** + * @return mixed[] + */ + public function jsonSerialize() : array{ + $result = (array) $this; + if(count($this->flattenedValueRemaps) === 0){ + unset($result["flattenedValueRemaps"]); + } + return $result; } } diff --git a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php index 7a720559eaa..de9b5ae5e60 100644 --- a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php +++ b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php @@ -133,6 +133,7 @@ private function register1to1BlockMappings() : void{ $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 @@ private function register1to1BlockMappings() : void{ $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/data/bedrock/item/ItemTypeNames.php b/src/data/bedrock/item/ItemTypeNames.php index 0a205f3e9b6..db6594c43dc 100644 --- a/src/data/bedrock/item/ItemTypeNames.php +++ b/src/data/bedrock/item/ItemTypeNames.php @@ -75,6 +75,7 @@ final class ItemTypeNames{ public const BLUE_DYE = "minecraft:blue_dye"; public const BOAT = "minecraft:boat"; public const BOGGED_SPAWN_EGG = "minecraft:bogged_spawn_egg"; + public const BOLT_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:bolt_armor_trim_smithing_template"; public const BONE = "minecraft:bone"; public const BONE_MEAL = "minecraft:bone_meal"; public const BOOK = "minecraft:book"; @@ -82,6 +83,7 @@ final class ItemTypeNames{ public const BOW = "minecraft:bow"; public const BOWL = "minecraft:bowl"; public const BREAD = "minecraft:bread"; + public const BREEZE_ROD = "minecraft:breeze_rod"; public const BREEZE_SPAWN_EGG = "minecraft:breeze_spawn_egg"; public const BREWER_POTTERY_SHERD = "minecraft:brewer_pottery_sherd"; public const BREWING_STAND = "minecraft:brewing_stand"; @@ -89,6 +91,7 @@ final class ItemTypeNames{ public const BROWN_DYE = "minecraft:brown_dye"; public const BRUSH = "minecraft:brush"; public const BUCKET = "minecraft:bucket"; + public const BUNDLE = "minecraft:bundle"; public const BURN_POTTERY_SHERD = "minecraft:burn_pottery_sherd"; public const CAKE = "minecraft:cake"; public const CAMEL_SPAWN_EGG = "minecraft:camel_spawn_egg"; @@ -141,6 +144,9 @@ 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"; public const CREEPER_BANNER_PATTERN = "minecraft:creeper_banner_pattern"; public const CREEPER_SPAWN_EGG = "minecraft:creeper_spawn_egg"; @@ -170,6 +176,11 @@ 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 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"; + public const DOUBLE_STONE_BLOCK_SLAB4 = "minecraft:double_stone_block_slab4"; public const DRAGON_BREATH = "minecraft:dragon_breath"; public const DRIED_KELP = "minecraft:dried_kelp"; public const DROWNED_SPAWN_EGG = "minecraft:drowned_spawn_egg"; @@ -205,6 +216,9 @@ final class ItemTypeNames{ public const FISHING_ROD = "minecraft:fishing_rod"; public const FLINT = "minecraft:flint"; public const FLINT_AND_STEEL = "minecraft:flint_and_steel"; + public const FLOW_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:flow_armor_trim_smithing_template"; + public const FLOW_BANNER_PATTERN = "minecraft:flow_banner_pattern"; + public const FLOW_POTTERY_SHERD = "minecraft:flow_pottery_sherd"; public const FLOWER_BANNER_PATTERN = "minecraft:flower_banner_pattern"; public const FLOWER_POT = "minecraft:flower_pot"; public const FOX_SPAWN_EGG = "minecraft:fox_spawn_egg"; @@ -242,6 +256,8 @@ final class ItemTypeNames{ public const GREEN_DYE = "minecraft:green_dye"; public const GUARDIAN_SPAWN_EGG = "minecraft:guardian_spawn_egg"; public const GUNPOWDER = "minecraft:gunpowder"; + public const GUSTER_BANNER_PATTERN = "minecraft:guster_banner_pattern"; + public const GUSTER_POTTERY_SHERD = "minecraft:guster_pottery_sherd"; public const HARD_STAINED_GLASS = "minecraft:hard_stained_glass"; public const HARD_STAINED_GLASS_PANE = "minecraft:hard_stained_glass_pane"; public const HEART_OF_THE_SEA = "minecraft:heart_of_the_sea"; @@ -289,6 +305,7 @@ final class ItemTypeNames{ public const LEATHER_LEGGINGS = "minecraft:leather_leggings"; public const LEAVES = "minecraft:leaves"; public const LEAVES2 = "minecraft:leaves2"; + public const LIGHT_BLOCK = "minecraft:light_block"; public const LIGHT_BLUE_DYE = "minecraft:light_blue_dye"; public const LIGHT_GRAY_DYE = "minecraft:light_gray_dye"; public const LIME_DYE = "minecraft:lime_dye"; @@ -297,6 +314,7 @@ final class ItemTypeNames{ public const LODESTONE_COMPASS = "minecraft:lodestone_compass"; public const LOG = "minecraft:log"; public const LOG2 = "minecraft:log2"; + public const MACE = "minecraft:mace"; public const MAGENTA_DYE = "minecraft:magenta_dye"; public const MAGMA_CREAM = "minecraft:magma_cream"; public const MAGMA_CUBE_SPAWN_EGG = "minecraft:magma_cube_spawn_egg"; @@ -312,6 +330,7 @@ final class ItemTypeNames{ public const MINECART = "minecraft:minecart"; public const MINER_POTTERY_SHERD = "minecraft:miner_pottery_sherd"; public const MOJANG_BANNER_PATTERN = "minecraft:mojang_banner_pattern"; + public const MONSTER_EGG = "minecraft:monster_egg"; public const MOOSHROOM_SPAWN_EGG = "minecraft:mooshroom_spawn_egg"; public const MOURNER_POTTERY_SHERD = "minecraft:mourner_pottery_sherd"; public const MULE_SPAWN_EGG = "minecraft:mule_spawn_egg"; @@ -322,11 +341,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"; @@ -357,6 +379,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"; @@ -404,6 +428,7 @@ final class ItemTypeNames{ public const RAW_IRON = "minecraft:raw_iron"; public const RECOVERY_COMPASS = "minecraft:recovery_compass"; public const RED_DYE = "minecraft:red_dye"; + public const RED_FLOWER = "minecraft:red_flower"; public const REDSTONE = "minecraft:redstone"; public const REPEATER = "minecraft:repeater"; public const RIB_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:rib_armor_trim_smithing_template"; @@ -412,6 +437,8 @@ final class ItemTypeNames{ public const SALMON = "minecraft:salmon"; public const SALMON_BUCKET = "minecraft:salmon_bucket"; public const SALMON_SPAWN_EGG = "minecraft:salmon_spawn_egg"; + public const SAPLING = "minecraft:sapling"; + public const SCRAPE_POTTERY_SHERD = "minecraft:scrape_pottery_sherd"; public const SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:sentry_armor_trim_smithing_template"; public const SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:shaper_armor_trim_smithing_template"; public const SHEAF_POTTERY_SHERD = "minecraft:sheaf_pottery_sherd"; @@ -455,10 +482,15 @@ 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_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_HOE = "minecraft:stone_hoe"; public const STONE_PICKAXE = "minecraft:stone_pickaxe"; public const STONE_SHOVEL = "minecraft:stone_shovel"; public const STONE_SWORD = "minecraft:stone_sword"; + public const STONEBRICK = "minecraft:stonebrick"; public const STRAY_SPAWN_EGG = "minecraft:stray_spawn_egg"; public const STRIDER_SPAWN_EGG = "minecraft:strider_spawn_egg"; public const STRING = "minecraft:string"; @@ -468,6 +500,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/entity/Living.php b/src/entity/Living.php index e695ba425ff..81f46424f17 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -68,6 +68,7 @@ use function ceil; use function count; use function floor; +use function ksort; use function lcg_value; use function max; use function min; @@ -76,6 +77,7 @@ use function round; use function sqrt; use const M_PI; +use const SORT_NUMERIC; abstract class Living extends Entity{ protected const DEFAULT_BREATH_TICKS = 300; @@ -149,24 +151,6 @@ protected function initEntity(CompoundTag $nbt) : void{ $this->getViewers(), fn(EntityEventBroadcaster $broadcaster, array $recipients) => $broadcaster->onMobArmorChange($recipients, $this) ))); - $playArmorSound = function(Item $newItem, Item $oldItem) : void{ - if(!$newItem->isNull() && $newItem instanceof Armor && !$newItem->equalsExact($oldItem)){ - $equipSound = $newItem->getMaterial()->getEquipSound(); - if($equipSound !== null){ - $this->broadcastSound($equipSound); - } - } - }; - $this->armorInventory->getListeners()->add(new CallbackInventoryListener( - function(Inventory $inventory, int $slot, Item $oldItem) use ($playArmorSound) : void{ - $playArmorSound($inventory->getItem($slot), $oldItem); - }, - function(Inventory $inventory, array $oldContents) use ($playArmorSound) : void{ - foreach($oldContents as $slot => $oldItem){ - $playArmorSound($inventory->getItem($slot), $oldItem); - } - } - )); $health = $this->getMaxHealth(); @@ -573,26 +557,33 @@ public function attack(EntityDamageEvent $source) : void{ return; } - $this->attackTime = $source->getAttackCooldown(); + if($this->attackTime <= 0){ + //this logic only applies if the entity was cold attacked - if($source instanceof EntityDamageByChildEntityEvent){ - $e = $source->getChild(); - if($e !== null){ - $motion = $e->getMotion(); - $this->knockBack($motion->x, $motion->z, $source->getKnockBack(), $source->getVerticalKnockBackLimit()); + $this->attackTime = $source->getAttackCooldown(); + + if($source instanceof EntityDamageByChildEntityEvent){ + $e = $source->getChild(); + if($e !== null){ + $motion = $e->getMotion(); + $this->knockBack($motion->x, $motion->z, $source->getKnockBack(), $source->getVerticalKnockBackLimit()); + } + }elseif($source instanceof EntityDamageByEntityEvent){ + $e = $source->getDamager(); + if($e !== null){ + $deltaX = $this->location->x - $e->location->x; + $deltaZ = $this->location->z - $e->location->z; + $this->knockBack($deltaX, $deltaZ, $source->getKnockBack(), $source->getVerticalKnockBackLimit()); + } } - }elseif($source instanceof EntityDamageByEntityEvent){ - $e = $source->getDamager(); - if($e !== null){ - $deltaX = $this->location->x - $e->location->x; - $deltaZ = $this->location->z - $e->location->z; - $this->knockBack($deltaX, $deltaZ, $source->getKnockBack(), $source->getVerticalKnockBackLimit()); + + if($this->isAlive()){ + $this->doHitAnimation(); } } if($this->isAlive()){ $this->applyPostDamageEffects($source); - $this->doHitAnimation(); } } @@ -894,8 +885,30 @@ protected function sendSpawnPacket(Player $player) : void{ protected function syncNetworkData(EntityMetadataCollection $properties) : void{ parent::syncNetworkData($properties); - $properties->setByte(EntityMetadataProperties::POTION_AMBIENT, $this->effectManager->hasOnlyAmbientEffects() ? 1 : 0); - $properties->setInt(EntityMetadataProperties::POTION_COLOR, Binary::signInt($this->effectManager->getBubbleColor()->toARGB())); + $visibleEffects = []; + foreach ($this->effectManager->all() as $effect) { + if (!$effect->isVisible() || !$effect->getType()->hasBubbles()) { + continue; + } + $visibleEffects[EffectIdMap::getInstance()->toId($effect->getType())] = $effect->isAmbient(); + } + + //TODO: HACK! the client may not be able to identify effects if they are not sorted. + ksort($visibleEffects, SORT_NUMERIC); + + $effectsData = 0; + $packedEffectsCount = 0; + foreach ($visibleEffects as $effectId => $isAmbient) { + $effectsData = ($effectsData << 7) | + (($effectId & 0x3f) << 1) | //Why not use 7 bits instead of only 6? mojang... + ($isAmbient ? 1 : 0); + + if (++$packedEffectsCount >= 8) { + break; + } + } + $properties->setLong(EntityMetadataProperties::VISIBLE_MOB_EFFECTS, $effectsData); + $properties->setShort(EntityMetadataProperties::AIR, $this->breathTicks); $properties->setShort(EntityMetadataProperties::MAX_AIR, $this->maxBreathTicks); diff --git a/src/entity/object/PaintingMotive.php b/src/entity/object/PaintingMotive.php index a456630fca3..00114c508be 100644 --- a/src/entity/object/PaintingMotive.php +++ b/src/entity/object/PaintingMotive.php @@ -37,9 +37,11 @@ public static function init() : void{ 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 @@ public static function init() : void{ 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 @@ public static function init() : void{ 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); } diff --git a/src/event/block/CampfireCookEvent.php b/src/event/block/CampfireCookEvent.php new file mode 100644 index 00000000000..3762f5848f1 --- /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/Armor.php b/src/item/Armor.php index e9667a8a89a..417c57f75ca 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -146,6 +146,10 @@ public function onClickAir(Player $player, Vector3 $directionVector, array &$ret $new = $thisCopy->pop(); $player->getArmorInventory()->setItem($this->getArmorSlot(), $new); $player->getInventory()->setItemInHand($existing); + $sound = $new->getMaterial()->getEquipSound(); + if($sound !== null){ + $player->broadcastSound($sound); + } if(!$thisCopy->isNull()){ //if the stack size was bigger than 1 (usually won't happen, but might be caused by plugins) $returnedItems[] = $thisCopy; diff --git a/src/item/Bowl.php b/src/item/Bowl.php index d83044307d7..217346df54c 100644 --- a/src/item/Bowl.php +++ b/src/item/Bowl.php @@ -25,5 +25,7 @@ class Bowl extends Item{ - //TODO: check fuel + public function getFuelTime() : int{ + return 200; + } } diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 91fd2ab4a43..9f5db6950c6 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -205,6 +205,7 @@ private static function registerBlocks(self $result) : void{ $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()); @@ -239,6 +240,8 @@ private static function registerBlocks(self $result) : void{ $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()); @@ -897,6 +900,10 @@ private static function registerBlocks(self $result) : void{ $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()); @@ -1003,6 +1010,7 @@ private static function registerBlocks(self $result) : void{ $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()); @@ -1096,6 +1104,13 @@ private static function registerBlocks(self $result) : void{ $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/src/item/VanillaItems.php b/src/item/VanillaItems.php index bbd0dfc01b3..5115ee48a8b 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -591,12 +591,12 @@ protected function createEntity(World $world, Vector3 $pos, float $yaw, float $p } }); 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)); } }); diff --git a/src/item/enchantment/AvailableEnchantmentRegistry.php b/src/item/enchantment/AvailableEnchantmentRegistry.php index 2c6f421ede0..cae94c666f5 100644 --- a/src/item/enchantment/AvailableEnchantmentRegistry.php +++ b/src/item/enchantment/AvailableEnchantmentRegistry.php @@ -56,6 +56,7 @@ private function __construct(){ $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 cd57eb203a5..47a750ff27d 100644 --- a/src/item/enchantment/StringToEnchantmentParser.php +++ b/src/item/enchantment/StringToEnchantmentParser.php @@ -52,6 +52,7 @@ private static function make() : self{ $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 779098c770e..19ce3971633 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -33,6 +33,7 @@ * @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 @@ protected static function setup() : void{ 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(), diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index e2b71ab3106..16898283a9a 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 @@ public function onCurrentWindowChange(Inventory $inventory) : void{ 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 @@ public function onClientOpenMainInventory() : void{ $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 @@ public function onClientOpenMainInventory() : void{ 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 @@ public function onClientRemoveWindow(int $id) : void{ //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; @@ -492,14 +500,16 @@ private function sendInventorySlotPackets(int $windowId, int $netSlot, ItemStack $this->session->sendDataPacket(InventorySlotPacket::create( $windowId, $netSlot, - new ItemStackWrapper(0, ItemStack::null()) + new ItemStackWrapper(0, ItemStack::null()), + 0 )); } //now send the real contents $this->session->sendDataPacket(InventorySlotPacket::create( $windowId, $netSlot, - $itemStackWrapper + $itemStackWrapper, + 0 )); } @@ -517,10 +527,11 @@ private function sendInventoryContentPackets(int $windowId, array $itemStackWrap */ $this->session->sendDataPacket(InventoryContentPacket::create( $windowId, - array_fill_keys(array_keys($itemStackWrappers), new ItemStackWrapper(0, ItemStack::null())) + array_fill_keys(array_keys($itemStackWrappers), new ItemStackWrapper(0, ItemStack::null())), + 0 )); //now send the real contents - $this->session->sendDataPacket(InventoryContentPacket::create($windowId, $itemStackWrappers)); + $this->session->sendDataPacket(InventoryContentPacket::create($windowId, $itemStackWrappers, 0)); } public function syncSlot(Inventory $inventory, int $slot, ItemStack $itemStack) : void{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 04cc7b932fb..33a9303a30d 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -54,6 +54,7 @@ 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; @@ -742,7 +743,7 @@ private function sendDisconnectPacket(Translatable|string $message) : void{ }else{ $translated = $message; } - $this->sendDataPacket(DisconnectPacket::create(0, $translated)); + $this->sendDataPacket(DisconnectPacket::create(0, $translated, "")); } /** @@ -1170,6 +1171,10 @@ public function onFormSent(int $id, Form $form) : bool{ 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/network/mcpe/StandardEntityEventBroadcaster.php b/src/network/mcpe/StandardEntityEventBroadcaster.php index 6b8a83fe1ad..e2a707a3db7 100644 --- a/src/network/mcpe/StandardEntityEventBroadcaster.php +++ b/src/network/mcpe/StandardEntityEventBroadcaster.php @@ -41,6 +41,7 @@ use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute; use pocketmine\network\mcpe\protocol\types\entity\PropertySyncData; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use function array_map; @@ -131,7 +132,8 @@ public function onMobArmorChange(array $recipients, Living $mob) : void{ ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getHelmet())), ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getChestplate())), ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getLeggings())), - ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getBoots())) + ItemStackWrapper::legacy($converter->coreItemStackToNet($inv->getBoots())), + new ItemStackWrapper(0, ItemStack::null()) )); } diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 1aa64c5970d..14523f74c7f 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\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 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData $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 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData $nullUUID, $typeTag, 50, + $noUnlockingRequirement, $index ); }elseif($recipe instanceof ShapedRecipe){ @@ -113,7 +116,9 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData $nullUUID, CraftingRecipeBlockName::CRAFTING_TABLE, 50, - $index + true, + $noUnlockingRequirement, + $index, ); }else{ //TODO: probably special recipe types @@ -125,6 +130,8 @@ private function buildCraftingDataCache(CraftingManager $manager) : CraftingData 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/network/mcpe/handler/ItemStackRequestExecutor.php b/src/network/mcpe/handler/ItemStackRequestExecutor.php index a36ae9f4051..a1d5e48124a 100644 --- a/src/network/mcpe/handler/ItemStackRequestExecutor.php +++ b/src/network/mcpe/handler/ItemStackRequestExecutor.php @@ -112,10 +112,10 @@ private function matchItemStack(Inventory $inventory, int $slotId, int $clientIt * @throws ItemStackRequestProcessException */ protected function getBuilderInventoryAndSlot(ItemStackRequestSlotInfo $info) : array{ - [$windowId, $slotId] = ItemStackContainerIdTranslator::translate($info->getContainerId(), $this->inventoryManager->getCurrentWindowId(), $info->getSlotId()); + [$windowId, $slotId] = ItemStackContainerIdTranslator::translate($info->getContainerName()->getContainerId(), $this->inventoryManager->getCurrentWindowId(), $info->getSlotId()); $windowAndSlot = $this->inventoryManager->locateWindowAndSlot($windowId, $slotId); if($windowAndSlot === null){ - throw new ItemStackRequestProcessException("No open inventory matches container UI ID: " . $info->getContainerId() . ", slot ID: " . $info->getSlotId()); + throw new ItemStackRequestProcessException("No open inventory matches container UI ID: " . $info->getContainerName()->getContainerId() . ", slot ID: " . $info->getSlotId()); } [$inventory, $slot] = $windowAndSlot; if(!$inventory->slotExists($slot)){ @@ -142,7 +142,7 @@ protected function transferItems(ItemStackRequestSlotInfo $source, ItemStackRequ * @throws ItemStackRequestProcessException */ protected function removeItemFromSlot(ItemStackRequestSlotInfo $slotInfo, int $count) : Item{ - if($slotInfo->getContainerId() === ContainerUIIds::CREATED_OUTPUT && $slotInfo->getSlotId() === UIInventorySlotOffset::CREATED_ITEM_OUTPUT){ + if($slotInfo->getContainerName()->getContainerId() === ContainerUIIds::CREATED_OUTPUT && $slotInfo->getSlotId() === UIInventorySlotOffset::CREATED_ITEM_OUTPUT){ //special case for the "created item" output slot //TODO: do we need to send a response for this slot info? return $this->takeCreatedItem($count); @@ -391,7 +391,7 @@ public function generateInventoryTransaction() : InventoryTransaction{ public function buildItemStackResponse() : ItemStackResponse{ $builder = new ItemStackResponseBuilder($this->request->getRequestId(), $this->inventoryManager); foreach($this->requestSlotInfos as $requestInfo){ - $builder->addSlot($requestInfo->getContainerId(), $requestInfo->getSlotId()); + $builder->addSlot($requestInfo->getContainerName()->getContainerId(), $requestInfo->getSlotId()); } return $builder->build(); diff --git a/src/network/mcpe/handler/ItemStackResponseBuilder.php b/src/network/mcpe/handler/ItemStackResponseBuilder.php index 09af69f2a3b..a947eae7268 100644 --- a/src/network/mcpe/handler/ItemStackResponseBuilder.php +++ b/src/network/mcpe/handler/ItemStackResponseBuilder.php @@ -27,6 +27,7 @@ use pocketmine\item\Durable; use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\protocol\types\inventory\ContainerUIIds; +use pocketmine\network\mcpe\protocol\types\inventory\FullContainerName; use pocketmine\network\mcpe\protocol\types\inventory\stackresponse\ItemStackResponse; use pocketmine\network\mcpe\protocol\types\inventory\stackresponse\ItemStackResponseContainerInfo; use pocketmine\network\mcpe\protocol\types\inventory\stackresponse\ItemStackResponseSlotInfo; @@ -99,7 +100,7 @@ public function build() : ItemStackResponse{ $responseContainerInfos = []; foreach($responseInfosByContainer as $containerInterfaceId => $responseInfos){ - $responseContainerInfos[] = new ItemStackResponseContainerInfo($containerInterfaceId, $responseInfos); + $responseContainerInfos[] = new ItemStackResponseContainerInfo(new FullContainerName($containerInterfaceId, 0), $responseInfos); } return new ItemStackResponse(ItemStackResponse::RESULT_OK, $this->requestId, $responseContainerInfos); diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 69761c366f3..b99775886ce 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -177,7 +177,7 @@ public function handleResourcePackClientResponse(ResourcePackClientResponsePacke //we don't force here, because it doesn't have user-facing effects //but it does have an annoying side-effect when true: it makes //the client remove its own non-server-supplied resource packs. - $this->session->sendDataPacket(ResourcePackStackPacket::create($stack, [], false, ProtocolInfo::MINECRAFT_VERSION_NETWORK, new Experiments([], false))); + $this->session->sendDataPacket(ResourcePackStackPacket::create($stack, [], false, ProtocolInfo::MINECRAFT_VERSION_NETWORK, new Experiments([], false), false)); $this->session->getLogger()->debug("Applying resource pack stack"); break; case ResourcePackClientResponsePacket::STATUS_COMPLETED: diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 4af3d1b099c..c72765af6bc 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -83,7 +83,7 @@ public static function registerCorePermissions() : void{ 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]); diff --git a/src/player/Player.php b/src/player/Player.php index 0cefbe71f22..d442c6a3b20 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2151,6 +2151,13 @@ public function onFormSubmit(int $formId, mixed $responseData) : bool{ return true; } + /** + * Closes the current viewing form and forms in queue. + */ + public function closeAllForms() : void{ + $this->getNetworkSession()->onCloseAllForms(); + } + /** * Transfers a player to another server. * diff --git a/src/resourcepacks/ResourcePack.php b/src/resourcepacks/ResourcePack.php index 04feeeb3d70..cdab3447b8d 100644 --- a/src/resourcepacks/ResourcePack.php +++ b/src/resourcepacks/ResourcePack.php @@ -60,6 +60,8 @@ public function getSha256() : string; * @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 da7db1db7a0..c4daeedf7b2 100644 --- a/src/resourcepacks/ZippedResourcePack.php +++ b/src/resourcepacks/ZippedResourcePack.php @@ -154,6 +154,9 @@ public function getSha256(bool $cached = true) : string{ } 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/thread/CommonThreadPartsTrait.php b/src/thread/CommonThreadPartsTrait.php index 9a14b23454b..e1c9d7c6bb1 100644 --- a/src/thread/CommonThreadPartsTrait.php +++ b/src/thread/CommonThreadPartsTrait.php @@ -25,6 +25,7 @@ use pmmp\thread\Thread as NativeThread; use pmmp\thread\ThreadSafeArray; +use pocketmine\crash\CrashDump; use pocketmine\errorhandler\ErrorToExceptionHandler; use pocketmine\Server; use function error_get_last; @@ -150,7 +151,7 @@ protected function onShutdown() : void{ $this->synchronized(function() : void{ if($this->isTerminated() && $this->crashInfo === null){ $last = error_get_last(); - if($last !== null){ + if($last !== null && ($last["type"] & CrashDump::FATAL_ERROR_MASK) !== 0){ //fatal error $crashInfo = ThreadCrashInfo::fromLastErrorInfo($last, $this->getThreadName()); }else{ diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index da2ba73da17..2eaee78831d 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -44,7 +44,7 @@ class MainLogger extends AttachableThreadSafeLogger implements \BufferedLogger{ /** * @throws \RuntimeException */ - public function __construct(?string $logFile, string $logArchiveDir, bool $useFormattingCodes, string $mainThreadName, \DateTimeZone $timezone, bool $logDebug = false){ + public function __construct(?string $logFile, bool $useFormattingCodes, string $mainThreadName, \DateTimeZone $timezone, bool $logDebug = false, ?string $logArchiveDir = null){ parent::__construct(); $this->logDebug = $logDebug; diff --git a/src/utils/MainLoggerThread.php b/src/utils/MainLoggerThread.php index e7acf973762..990644f65cd 100644 --- a/src/utils/MainLoggerThread.php +++ b/src/utils/MainLoggerThread.php @@ -52,12 +52,12 @@ final class MainLoggerThread extends Thread{ public function __construct( private string $logFile, - private string $archiveDir, + private ?string $archiveDir, private readonly int $maxFileSize = 32 * 1024 * 1024 //32 MB ){ $this->buffer = new ThreadSafeArray(); touch($this->logFile); - if(!@mkdir($this->archiveDir) && !is_dir($this->archiveDir)){ + if($this->archiveDir !== null && !@mkdir($this->archiveDir) && !is_dir($this->archiveDir)){ throw new \RuntimeException("Unable to create archive directory: " . ( is_file($this->archiveDir) ? "it already exists and is not a directory" : "permission denied")); } @@ -108,7 +108,7 @@ private function openLogFile(string $file, int &$size){ * @param resource $logResource * @return resource */ - private function archiveLogFile($logResource, int &$size){ + private function archiveLogFile($logResource, int &$size, string $archiveDir){ fclose($logResource); clearstatcache(); @@ -125,7 +125,7 @@ private function archiveLogFile($logResource, int &$size){ }while(file_exists($out)); //the user may have externally deleted the whole directory - make sure it exists before we do anything - @mkdir($this->archiveDir); + @mkdir($archiveDir); rename($this->logFile, $out); $logResource = $this->openLogFile($this->logFile, $size); @@ -141,12 +141,12 @@ private function logFileReadyToArchive(int $size) : bool{ /** * @param resource $logResource */ - private function writeLogStream(&$logResource, int &$size) : void{ + private function writeLogStream(&$logResource, int &$size, ?string $archiveDir) : void{ while(($chunk = $this->buffer->shift()) !== null){ fwrite($logResource, $chunk); $size += strlen($chunk); - if($this->logFileReadyToArchive($size)){ - $logResource = $this->archiveLogFile($logResource, $size); + if($archiveDir !== null && $this->logFileReadyToArchive($size)){ + $logResource = $this->archiveLogFile($logResource, $size, $archiveDir); } } @@ -161,12 +161,13 @@ private function writeLogStream(&$logResource, int &$size) : void{ public function run() : void{ $size = 0; $logResource = $this->openLogFile($this->logFile, $size); - if($this->logFileReadyToArchive($size)){ - $logResource = $this->archiveLogFile($logResource, $size); + $archiveDir = $this->archiveDir; + if($archiveDir !== null && $this->logFileReadyToArchive($size)){ + $logResource = $this->archiveLogFile($logResource, $size, $archiveDir); } while(!$this->shutdown){ - $this->writeLogStream($logResource, $size); + $this->writeLogStream($logResource, $size, $archiveDir); $this->synchronized(function() : void{ if(!$this->shutdown && !$this->syncFlush){ $this->wait(); @@ -174,7 +175,7 @@ public function run() : void{ }); } - $this->writeLogStream($logResource, $size); + $this->writeLogStream($logResource, $size, $archiveDir); fclose($logResource); } diff --git a/src/utils/Process.php b/src/utils/Process.php index c57b96d4a0c..1370ab27c79 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -23,7 +23,7 @@ namespace pocketmine\utils; -use pocketmine\thread\ThreadManager; +use pocketmine\thread\Thread; use function count; use function exec; use function fclose; @@ -122,7 +122,7 @@ public static function getThreadCount() : int{ //TODO: more OS - return count(ThreadManager::getInstance()->getAll()) + 2; //MainLogger + Main Thread + return Thread::getRunningCount() + 1; //pmmpthread doesn't count the main thread } /** diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 4b57dd2d8d6..709dadf974a 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -51,12 +51,12 @@ class BedrockWorldData extends BaseNbtWorldData{ public const CURRENT_STORAGE_VERSION = 10; - public const CURRENT_STORAGE_NETWORK_VERSION = 662; + public const CURRENT_STORAGE_NETWORK_VERSION = 712; public const CURRENT_CLIENT_VERSION_TARGET = [ 1, //major - 20, //minor - 71, //patch - 1, //revision + 21, //minor + 20, //patch + 0, //revision 0 //is beta ]; diff --git a/src/world/format/io/region/RegionLocationTableEntry.php b/src/world/format/io/region/RegionLocationTableEntry.php index abb92accf24..ad0b1ce487e 100644 --- a/src/world/format/io/region/RegionLocationTableEntry.php +++ b/src/world/format/io/region/RegionLocationTableEntry.php @@ -27,6 +27,7 @@ class RegionLocationTableEntry{ private int $firstSector; + /** @phpstan-var positive-int */ private int $sectorCount; private int $timestamp; @@ -61,6 +62,9 @@ public function getUsedSectors() : array{ return range($this->getFirstSector(), $this->getLastSector()); } + /** + * @phpstan-return positive-int + */ public function getSectorCount() : int{ return $this->sectorCount; } diff --git a/src/world/sound/CampfireSound.php b/src/world/sound/CampfireSound.php new file mode 100644 index 00000000000..7e01342efe6 --- /dev/null +++ b/src/world/sound/CampfireSound.php @@ -0,0 +1,35 @@ +, stateDataBits: int}"); + /** + * @return int[] + * @phpstan-return array + */ + public static function computeConsistencyCheckTable(RuntimeBlockStateRegistry $blockStateRegistry) : array{ + $newTable = []; + + $idNameLookup = []; + //if we ever split up block registration into multiple registries (e.g. separating chemistry blocks), + //we'll need to ensure those additional registries are also included here + foreach(Utils::stringifyKeys(VanillaBlocks::getAll()) as $name => $blockType){ + $id = $blockType->getTypeId(); + if(isset($idNameLookup[$id])){ + throw new AssumptionFailedError("TypeID $name collides with " . $idNameLookup[$id]); + } + $idNameLookup[$id] = $name; } - $knownStates = []; - /** - * @var string $name - * @var int[] $stateIds - */ - foreach($list["knownStates"] as $name => $stateIds){ - foreach($stateIds as $stateId){ - $knownStates[$stateId] = $name; + + foreach($blockStateRegistry->getAllKnownStates() as $index => $block){ + if($index !== $block->getStateId()){ + throw new AssumptionFailedError("State index should always match state ID"); } + $idName = $idNameLookup[$block->getTypeId()]; + $newTable[$idName] = ($newTable[$idName] ?? 0) + 1; } - $oldStateDataSize = $list["stateDataBits"]; - self::assertSame($oldStateDataSize, Block::INTERNAL_STATE_DATA_BITS, "Changed number of state data bits - consistency check probably need regenerating"); - $states = $this->blockFactory->getAllKnownStates(); - foreach($states as $stateId => $state){ - self::assertArrayHasKey($stateId, $knownStates, "New block state $stateId (" . print_r($state, true) . ") - consistency check may need regenerating"); - self::assertSame($knownStates[$stateId], $state->getName()); + return $newTable; + } + + /** + * @phpstan-param array $actual + * + * @return string[] + */ + public static function computeConsistencyCheckDiff(string $expectedFile, array $actual) : array{ + $expected = json_decode(Filesystem::fileGetContents($expectedFile), true, 2, JSON_THROW_ON_ERROR); + if(!is_array($expected)){ + throw new AssumptionFailedError("Old table should be array"); } - asort($knownStates, SORT_STRING); - foreach($knownStates as $k => $name){ - self::assertArrayHasKey($k, $states, "Missing previously-known block state $k " . ($k >> Block::INTERNAL_STATE_DATA_BITS) . ":" . ($k & Block::INTERNAL_STATE_DATA_MASK) . " ($name)"); - self::assertSame($name, $states[$k]->getName()); + + $errors = []; + foreach($expected as $typeName => $numStates){ + if(!is_string($typeName) || !is_int($numStates)){ + throw new AssumptionFailedError("Old table should be array"); + } + if(!isset($actual[$typeName])){ + $errors[] = "Removed block type $typeName ($numStates permutations)"; + }elseif($actual[$typeName] !== $numStates){ + $errors[] = "Block type $typeName permutation count changed: $numStates -> " . $actual[$typeName]; + } } + foreach(Utils::stringifyKeys($actual) as $typeName => $numStates){ + if(!isset($expected[$typeName])){ + $errors[] = "Added block type $typeName (" . $actual[$typeName] . " permutations)"; + } + } + + return $errors; + } + + public function testConsistency() : void{ + $newTable = self::computeConsistencyCheckTable($this->blockFactory); + $errors = self::computeConsistencyCheckDiff(__DIR__ . '/block_factory_consistency_check.json', $newTable); + + self::assertEmpty($errors, "Block factory consistency check failed:\n" . implode("\n", $errors)); } public function testEmptyStateId() : void{ diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 9e68daf0c4b..97c24b52ec7 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1,707 @@ -{"knownStates":{"???":[20992881],"Acacia Button":[20482064,20482065,20482068,20482069,20482070,20482071,20482072,20482073,20482076,20482077,20482078,20482079],"Acacia Door":[20484288,20484289,20484290,20484291,20484292,20484293,20484294,20484295,20484296,20484297,20484298,20484299,20484300,20484301,20484302,20484303,20484304,20484305,20484306,20484307,20484308,20484309,20484310,20484311,20484312,20484313,20484314,20484315,20484316,20484317,20484318,20484319],"Acacia Fence":[20487161],"Acacia Fence Gate":[20489840,20489841,20489842,20489843,20489844,20489845,20489846,20489847,20489848,20489849,20489850,20489851,20489852,20489853,20489854,20489855],"Acacia Leaves":[20490916,20490917,20490918,20490919],"Acacia Log":[20492840,20492841,20492842,20492843,20492846,20492847],"Acacia Planks":[20496170],"Acacia Pressure Plate":[20497912,20497913],"Acacia Sapling":[20499538,20499539],"Acacia Sign":[20502272,20502273,20502274,20502275,20502276,20502277,20502278,20502279,20502280,20502281,20502282,20502283,20502284,20502285,20502286,20502287],"Acacia Slab":[20502804,20502805,20502806],"Acacia Stairs":[20504680,20504681,20504682,20504683,20504684,20504685,20504686,20504687],"Acacia Trapdoor":[20508544,20508545,20508546,20508547,20508548,20508549,20508550,20508551,20508552,20508553,20508554,20508555,20508556,20508557,20508558,20508559],"Acacia Wall Sign":[20508856,20508857,20508858,20508859],"Acacia Wood":[20511120,20511121,20511122,20511123,20511124,20511125],"Actinium":[20754337],"Activator Rail":[20513778,20513779,20513780,20513781,20513782,20513783,20513786,20513787,20513788,20513789,20513790,20513791],"Air":[20481500],"All Sided Mushroom Stem":[20515945],"Allium":[20517436],"Aluminum":[20756409],"Americium":[20756900],"Amethyst":[21587565],"Amethyst Cluster":[21582624,21582625,21582626,21582627,21582628,21582629,21582630,21582631,21582632,21582633,21582634,21582635,21582636,21582637,21582638,21582639,21582640,21582641,21582642,21582643,21582644,21582645,21582646,21582647],"Ancient Debris":[21589690],"Andesite":[20520193],"Andesite Slab":[20521816,20521818,20521819],"Andesite Stairs":[20523416,20523417,20523418,20523419,20523420,20523421,20523422,20523423],"Andesite Wall":[20525824,20525825,20525826,20525827,20525828,20525829,20525830,20525831,20525832,20525833,20525834,20525835,20525836,20525837,20525838,20525839,20525846,20525888,20525889,20525890,20525891,20525892,20525893,20525894,20525895,20525896,20525897,20525898,20525899,20525900,20525901,20525902,20525903,20525904,20525905,20525906,20525907,20525908,20525909,20525910,20525911,20525912,20525913,20525914,20525915,20525916,20525917,20525918,20525919,20525920,20525921,20525922,20525923,20525924,20525925,20525926,20525927,20525928,20525929,20525930,20525931,20525932,20525933,20525934,20525935,20525936,20525937,20525938,20525939,20525940,20525941,20525942,20525943,20525944,20525945,20525946,20525947,20525948,20525949,20525950,20525951,20525952,20525953,20525954,20525955,20525956,20525957,20525958,20525959,20525960,20525961,20525962,20525963,20525964,20525965,20525966,20525967,20525974,20526016,20526017,20526018,20526019,20526020,20526021,20526022,20526023,20526024,20526025,20526026,20526027,20526028,20526029,20526030,20526031,20526032,20526033,20526034,20526035,20526036,20526037,20526038,20526039,20526040,20526041,20526042,20526043,20526044,20526045,20526046,20526047,20526048,20526049,20526050,20526051,20526052,20526053,20526054,20526055,20526056,20526057,20526058,20526059,20526060,20526061,20526062,20526063,20526064,20526065,20526066,20526067,20526068,20526069,20526070,20526071,20526072,20526073,20526074,20526075,20526076,20526077,20526078,20526079],"Antimony":[20760253],"Anvil":[20528176,20528177,20528179,20528180,20528181,20528183,20528184,20528185,20528187,20528188,20528189,20528191],"Argon":[20760826],"Arsenic":[20763178],"Astatine":[20766501],"Azalea Leaves":[21886340,21886341,21886342,21886343],"Azure Bluet":[20531031],"Bamboo":[20531777,20531778,20531779,20531781,20531782,20531783,20531785,20531786,20531787,20531789,20531790,20531791],"Bamboo Sapling":[20533516,20533517],"Banner":[20535808,20535809,20535810,20535811,20535812,20535813,20535814,20535815,20535816,20535817,20535818,20535819,20535820,20535821,20535822,20535823,20535824,20535825,20535826,20535827,20535828,20535829,20535830,20535831,20535832,20535833,20535834,20535835,20535836,20535837,20535838,20535839,20535840,20535841,20535842,20535843,20535844,20535845,20535846,20535847,20535848,20535849,20535850,20535851,20535852,20535853,20535854,20535855,20535856,20535857,20535858,20535859,20535860,20535861,20535862,20535863,20535864,20535865,20535866,20535867,20535868,20535869,20535870,20535871,20535872,20535873,20535874,20535875,20535876,20535877,20535878,20535879,20535880,20535881,20535882,20535883,20535884,20535885,20535886,20535887,20535888,20535889,20535890,20535891,20535892,20535893,20535894,20535895,20535896,20535897,20535898,20535899,20535900,20535901,20535902,20535903,20535904,20535905,20535906,20535907,20535908,20535909,20535910,20535911,20535912,20535913,20535914,20535915,20535916,20535917,20535918,20535919,20535920,20535921,20535922,20535923,20535924,20535925,20535926,20535927,20535928,20535929,20535930,20535931,20535932,20535933,20535934,20535935,20535936,20535937,20535938,20535939,20535940,20535941,20535942,20535943,20535944,20535945,20535946,20535947,20535948,20535949,20535950,20535951,20535952,20535953,20535954,20535955,20535956,20535957,20535958,20535959,20535960,20535961,20535962,20535963,20535964,20535965,20535966,20535967,20535968,20535969,20535970,20535971,20535972,20535973,20535974,20535975,20535976,20535977,20535978,20535979,20535980,20535981,20535982,20535983,20535984,20535985,20535986,20535987,20535988,20535989,20535990,20535991,20535992,20535993,20535994,20535995,20535996,20535997,20535998,20535999,20536000,20536001,20536002,20536003,20536004,20536005,20536006,20536007,20536008,20536009,20536010,20536011,20536012,20536013,20536014,20536015,20536016,20536017,20536018,20536019,20536020,20536021,20536022,20536023,20536024,20536025,20536026,20536027,20536028,20536029,20536030,20536031,20536032,20536033,20536034,20536035,20536036,20536037,20536038,20536039,20536040,20536041,20536042,20536043,20536044,20536045,20536046,20536047,20536048,20536049,20536050,20536051,20536052,20536053,20536054,20536055,20536056,20536057,20536058,20536059,20536060,20536061,20536062,20536063],"Barium":[20767788],"Barrel":[20538288,20538289,20538290,20538291,20538294,20538295,20538296,20538297,20538298,20538299,20538302,20538303],"Barrier":[20541302],"Basalt":[21591048,21591049,21591050],"Beacon":[20541801],"Bed Block":[20545280,20545281,20545282,20545283,20545284,20545285,20545286,20545287,20545288,20545289,20545290,20545291,20545292,20545293,20545294,20545295,20545296,20545297,20545298,20545299,20545300,20545301,20545302,20545303,20545304,20545305,20545306,20545307,20545308,20545309,20545310,20545311,20545312,20545313,20545314,20545315,20545316,20545317,20545318,20545319,20545320,20545321,20545322,20545323,20545324,20545325,20545326,20545327,20545328,20545329,20545330,20545331,20545332,20545333,20545334,20545335,20545336,20545337,20545338,20545339,20545340,20545341,20545342,20545343,20545344,20545345,20545346,20545347,20545348,20545349,20545350,20545351,20545352,20545353,20545354,20545355,20545356,20545357,20545358,20545359,20545360,20545361,20545362,20545363,20545364,20545365,20545366,20545367,20545368,20545369,20545370,20545371,20545372,20545373,20545374,20545375,20545376,20545377,20545378,20545379,20545380,20545381,20545382,20545383,20545384,20545385,20545386,20545387,20545388,20545389,20545390,20545391,20545392,20545393,20545394,20545395,20545396,20545397,20545398,20545399,20545400,20545401,20545402,20545403,20545404,20545405,20545406,20545407,20545408,20545409,20545410,20545411,20545412,20545413,20545414,20545415,20545416,20545417,20545418,20545419,20545420,20545421,20545422,20545423,20545424,20545425,20545426,20545427,20545428,20545429,20545430,20545431,20545432,20545433,20545434,20545435,20545436,20545437,20545438,20545439,20545440,20545441,20545442,20545443,20545444,20545445,20545446,20545447,20545448,20545449,20545450,20545451,20545452,20545453,20545454,20545455,20545456,20545457,20545458,20545459,20545460,20545461,20545462,20545463,20545464,20545465,20545466,20545467,20545468,20545469,20545470,20545471,20545472,20545473,20545474,20545475,20545476,20545477,20545478,20545479,20545480,20545481,20545482,20545483,20545484,20545485,20545486,20545487,20545488,20545489,20545490,20545491,20545492,20545493,20545494,20545495,20545496,20545497,20545498,20545499,20545500,20545501,20545502,20545503,20545504,20545505,20545506,20545507,20545508,20545509,20545510,20545511,20545512,20545513,20545514,20545515,20545516,20545517,20545518,20545519,20545520,20545521,20545522,20545523,20545524,20545525,20545526,20545527,20545528,20545529,20545530,20545531,20545532,20545533,20545534,20545535],"Bedrock":[20545540,20545541],"Beetroot Block":[20549328,20549329,20549330,20549331,20549332,20549333,20549334,20549335],"Bell":[20551488,20551489,20551490,20551491,20551492,20551493,20551494,20551495,20551496,20551497,20551498,20551499,20551500,20551501,20551502,20551503],"Berkelium":[20768774],"Beryllium":[20771395],"Big Dripleaf":[21929936,21929937,21929938,21929939,21929940,21929941,21929942,21929943,21929944,21929945,21929946,21929947,21929948,21929949,21929950,21929951],"Big Dripleaf Stem":[21931976,21931977,21931978,21931979],"Birch Button":[20552224,20552225,20552226,20552227,20552230,20552231,20552232,20552233,20552234,20552235,20552238,20552239],"Birch Door":[20554848,20554849,20554850,20554851,20554852,20554853,20554854,20554855,20554856,20554857,20554858,20554859,20554860,20554861,20554862,20554863,20554864,20554865,20554866,20554867,20554868,20554869,20554870,20554871,20554872,20554873,20554874,20554875,20554876,20554877,20554878,20554879],"Birch Fence":[20557622],"Birch Fence Gate":[20559792,20559793,20559794,20559795,20559796,20559797,20559798,20559799,20559800,20559801,20559802,20559803,20559804,20559805,20559806,20559807],"Birch Leaves":[20560344,20560345,20560346,20560347],"Birch Log":[20563648,20563649,20563652,20563653,20563654,20563655],"Birch Planks":[20564186],"Birch Pressure Plate":[20567746,20567747],"Birch Sapling":[20568972,20568973],"Birch Sign":[20571536,20571537,20571538,20571539,20571540,20571541,20571542,20571543,20571544,20571545,20571546,20571547,20571548,20571549,20571550,20571551],"Birch Slab":[20573196,20573197,20573198],"Birch Stairs":[20575080,20575081,20575082,20575083,20575084,20575085,20575086,20575087],"Birch Trapdoor":[20577008,20577009,20577010,20577011,20577012,20577013,20577014,20577015,20577016,20577017,20577018,20577019,20577020,20577021,20577022,20577023],"Birch Wall Sign":[20579020,20579021,20579022,20579023],"Birch Wood":[20580826,20580827,20580828,20580829,20580830,20580831],"Bismuth":[20773935],"Blackstone":[21596307],"Blackstone Slab":[21599012,21599014,21599015],"Blackstone Stairs":[21601800,21601801,21601802,21601803,21601804,21601805,21601806,21601807],"Blackstone Wall":[21604098,21604112,21604113,21604114,21604115,21604116,21604117,21604118,21604119,21604120,21604121,21604122,21604123,21604124,21604125,21604126,21604127,21604160,21604161,21604162,21604163,21604164,21604165,21604166,21604167,21604168,21604169,21604170,21604171,21604172,21604173,21604174,21604175,21604176,21604177,21604178,21604179,21604180,21604181,21604182,21604183,21604184,21604185,21604186,21604187,21604188,21604189,21604190,21604191,21604192,21604193,21604194,21604195,21604196,21604197,21604198,21604199,21604200,21604201,21604202,21604203,21604204,21604205,21604206,21604207,21604208,21604209,21604210,21604211,21604212,21604213,21604214,21604215,21604216,21604217,21604218,21604219,21604220,21604221,21604222,21604223,21604226,21604240,21604241,21604242,21604243,21604244,21604245,21604246,21604247,21604248,21604249,21604250,21604251,21604252,21604253,21604254,21604255,21604288,21604289,21604290,21604291,21604292,21604293,21604294,21604295,21604296,21604297,21604298,21604299,21604300,21604301,21604302,21604303,21604304,21604305,21604306,21604307,21604308,21604309,21604310,21604311,21604312,21604313,21604314,21604315,21604316,21604317,21604318,21604319,21604320,21604321,21604322,21604323,21604324,21604325,21604326,21604327,21604328,21604329,21604330,21604331,21604332,21604333,21604334,21604335,21604336,21604337,21604338,21604339,21604340,21604341,21604342,21604343,21604344,21604345,21604346,21604347,21604348,21604349,21604350,21604351],"Blast Furnace":[20585328,20585329,20585330,20585331,20585332,20585333,20585334,20585335],"Blue Ice":[20588595],"Blue Orchid":[20591829],"Blue Torch":[20593968,20593969,20593973,20593974,20593975],"Bohrium":[20775552],"Bone Block":[20596340,20596341,20596343],"Bookshelf":[20597864],"Boron":[20777985],"Brewing Stand":[20600176,20600177,20600178,20600179,20600180,20600181,20600182,20600183],"Brick Slab":[20601168,20601169,20601171],"Brick Stairs":[20604408,20604409,20604410,20604411,20604412,20604413,20604414,20604415],"Brick Wall":[20605952,20605953,20605954,20605955,20605956,20605957,20605958,20605959,20605960,20605961,20605962,20605963,20605964,20605965,20605966,20605967,20605968,20605969,20605970,20605971,20605972,20605973,20605974,20605975,20605976,20605977,20605978,20605979,20605980,20605981,20605982,20605983,20605984,20605985,20605986,20605987,20605988,20605989,20605990,20605991,20605992,20605993,20605994,20605995,20605996,20605997,20605998,20605999,20606000,20606001,20606002,20606003,20606004,20606005,20606006,20606007,20606008,20606009,20606010,20606011,20606012,20606013,20606014,20606015,20606053,20606064,20606065,20606066,20606067,20606068,20606069,20606070,20606071,20606072,20606073,20606074,20606075,20606076,20606077,20606078,20606079,20606080,20606081,20606082,20606083,20606084,20606085,20606086,20606087,20606088,20606089,20606090,20606091,20606092,20606093,20606094,20606095,20606096,20606097,20606098,20606099,20606100,20606101,20606102,20606103,20606104,20606105,20606106,20606107,20606108,20606109,20606110,20606111,20606112,20606113,20606114,20606115,20606116,20606117,20606118,20606119,20606120,20606121,20606122,20606123,20606124,20606125,20606126,20606127,20606128,20606129,20606130,20606131,20606132,20606133,20606134,20606135,20606136,20606137,20606138,20606139,20606140,20606141,20606142,20606143,20606181,20606192,20606193,20606194,20606195,20606196,20606197,20606198,20606199,20606200,20606201,20606202,20606203,20606204,20606205,20606206,20606207],"Bricks":[20608594],"Bromine":[20779949],"Brown Mushroom":[20613080],"Brown Mushroom Block":[20614032,20614033,20614034,20614035,20614036,20614037,20614038,20614039,20614044,20614045,20614047],"Budding Amethyst":[21577592],"Cactus":[20616384,20616385,20616386,20616387,20616388,20616389,20616390,20616391,20616392,20616393,20616394,20616395,20616396,20616397,20616398,20616399],"Cadmium":[20781893],"Cake":[20618584,20618585,20618586,20618587,20618588,20618589,20618590],"Cake With Candle":[21837222,21837223],"Cake With Dyed Candle":[21839232,21839233,21839234,21839235,21839236,21839237,21839238,21839239,21839240,21839241,21839242,21839243,21839244,21839245,21839246,21839247,21839248,21839249,21839250,21839251,21839252,21839253,21839254,21839255,21839256,21839257,21839258,21839259,21839260,21839261,21839262,21839263],"Calcite":[21638381],"Calcium":[20783925],"Californium":[20787131],"Candle":[21832176,21832177,21832178,21832179,21832180,21832181,21832182,21832183],"Carbon":[20789232],"Carpet":[20619280,20619281,20619282,20619283,20619284,20619285,20619286,20619287,20619288,20619289,20619290,20619291,20619292,20619293,20619294,20619295],"Carrot Block":[20622752,20622753,20622754,20622755,20622756,20622757,20622758,20622759],"Cartography Table":[21845741],"Carved Pumpkin":[20624628,20624629,20624630,20624631],"Cauldron":[21852969],"Cave Vines":[21892224,21892225,21892226,21892227,21892228,21892229,21892230,21892231,21892232,21892233,21892234,21892235,21892236,21892237,21892238,21892239,21892244,21892245,21892248,21892249,21892250,21892251,21892252,21892253,21892254,21892255,21892256,21892257,21892258,21892259,21892260,21892261,21892262,21892263,21892264,21892265,21892266,21892267,21892268,21892269,21892270,21892271,21892276,21892277,21892280,21892281,21892282,21892283,21892284,21892285,21892286,21892287,21892288,21892289,21892290,21892291,21892292,21892293,21892294,21892295,21892296,21892297,21892298,21892299,21892300,21892301,21892302,21892303,21892308,21892309,21892312,21892313,21892314,21892315,21892316,21892317,21892318,21892319,21892320,21892321,21892322,21892323,21892324,21892325,21892326,21892327,21892328,21892329,21892330,21892331,21892332,21892333,21892334,21892335,21892340,21892341,21892344,21892345,21892346,21892347,21892348,21892349,21892350,21892351],"Cerium":[20789431],"Cesium":[20791798],"Chain":[21878573,21878574,21878575],"Cherry Button":[21895570,21895571,21895572,21895573,21895574,21895575,21895578,21895579,21895580,21895581,21895582,21895583],"Cherry Door":[21898304,21898305,21898306,21898307,21898308,21898309,21898310,21898311,21898312,21898313,21898314,21898315,21898316,21898317,21898318,21898319,21898320,21898321,21898322,21898323,21898324,21898325,21898326,21898327,21898328,21898329,21898330,21898331,21898332,21898333,21898334,21898335],"Cherry Fence":[21900661],"Cherry Fence Gate":[21901904,21901905,21901906,21901907,21901908,21901909,21901910,21901911,21901912,21901913,21901914,21901915,21901916,21901917,21901918,21901919],"Cherry Leaves":[21904412,21904413,21904414,21904415],"Cherry Log":[21905784,21905785,21905786,21905787,21905790,21905791],"Cherry Planks":[21908756],"Cherry Pressure Plate":[21911536,21911537],"Cherry Sign":[21914944,21914945,21914946,21914947,21914948,21914949,21914950,21914951,21914952,21914953,21914954,21914955,21914956,21914957,21914958,21914959],"Cherry Slab":[21917632,21917633,21917635],"Cherry Stairs":[21918912,21918913,21918914,21918915,21918916,21918917,21918918,21918919],"Cherry Trapdoor":[21919968,21919969,21919970,21919971,21919972,21919973,21919974,21919975,21919976,21919977,21919978,21919979,21919980,21919981,21919982,21919983],"Cherry Wall Sign":[21923100,21923101,21923102,21923103],"Cherry Wood":[21924008,21924009,21924012,21924013,21924014,21924015],"Chest":[20628872,20628873,20628874,20628875],"Chiseled Bookshelf":[21938176,21938177,21938178,21938179,21938180,21938181,21938182,21938183,21938184,21938185,21938186,21938187,21938188,21938189,21938190,21938191,21938192,21938193,21938194,21938195,21938196,21938197,21938198,21938199,21938200,21938201,21938202,21938203,21938204,21938205,21938206,21938207,21938208,21938209,21938210,21938211,21938212,21938213,21938214,21938215,21938216,21938217,21938218,21938219,21938220,21938221,21938222,21938223,21938224,21938225,21938226,21938227,21938228,21938229,21938230,21938231,21938232,21938233,21938234,21938235,21938236,21938237,21938238,21938239,21938240,21938241,21938242,21938243,21938244,21938245,21938246,21938247,21938248,21938249,21938250,21938251,21938252,21938253,21938254,21938255,21938256,21938257,21938258,21938259,21938260,21938261,21938262,21938263,21938264,21938265,21938266,21938267,21938268,21938269,21938270,21938271,21938272,21938273,21938274,21938275,21938276,21938277,21938278,21938279,21938280,21938281,21938282,21938283,21938284,21938285,21938286,21938287,21938288,21938289,21938290,21938291,21938292,21938293,21938294,21938295,21938296,21938297,21938298,21938299,21938300,21938301,21938302,21938303,21938304,21938305,21938306,21938307,21938308,21938309,21938310,21938311,21938312,21938313,21938314,21938315,21938316,21938317,21938318,21938319,21938320,21938321,21938322,21938323,21938324,21938325,21938326,21938327,21938328,21938329,21938330,21938331,21938332,21938333,21938334,21938335,21938336,21938337,21938338,21938339,21938340,21938341,21938342,21938343,21938344,21938345,21938346,21938347,21938348,21938349,21938350,21938351,21938352,21938353,21938354,21938355,21938356,21938357,21938358,21938359,21938360,21938361,21938362,21938363,21938364,21938365,21938366,21938367,21938368,21938369,21938370,21938371,21938372,21938373,21938374,21938375,21938376,21938377,21938378,21938379,21938380,21938381,21938382,21938383,21938384,21938385,21938386,21938387,21938388,21938389,21938390,21938391,21938392,21938393,21938394,21938395,21938396,21938397,21938398,21938399,21938400,21938401,21938402,21938403,21938404,21938405,21938406,21938407,21938408,21938409,21938410,21938411,21938412,21938413,21938414,21938415,21938416,21938417,21938418,21938419,21938420,21938421,21938422,21938423,21938424,21938425,21938426,21938427,21938428,21938429,21938430,21938431],"Chiseled Deepslate":[21680290],"Chiseled Nether Bricks":[21682906],"Chiseled Polished Blackstone":[21618038],"Chiseled Quartz Block":[20630148,20630150,20630151],"Chiseled Red Sandstone":[20633244],"Chiseled Sandstone":[20635615],"Chiseled Stone Bricks":[20636034],"Chlorine":[20794258],"Chorus Flower":[21864360,21864361,21864364,21864365,21864366,21864367],"Chorus Plant":[21866123],"Chromium":[20797122],"Clay Block":[20639448],"Coal Block":[20641681],"Coal Ore":[20642280],"Cobalt":[20799311],"Cobbled Deepslate":[21662962],"Cobbled Deepslate Slab":[21665324,21665326,21665327],"Cobbled Deepslate Stairs":[21666232,21666233,21666234,21666235,21666236,21666237,21666238,21666239],"Cobbled Deepslate Wall":[21668389,21668400,21668401,21668402,21668403,21668404,21668405,21668406,21668407,21668408,21668409,21668410,21668411,21668412,21668413,21668414,21668415,21668416,21668417,21668418,21668419,21668420,21668421,21668422,21668423,21668424,21668425,21668426,21668427,21668428,21668429,21668430,21668431,21668432,21668433,21668434,21668435,21668436,21668437,21668438,21668439,21668440,21668441,21668442,21668443,21668444,21668445,21668446,21668447,21668448,21668449,21668450,21668451,21668452,21668453,21668454,21668455,21668456,21668457,21668458,21668459,21668460,21668461,21668462,21668463,21668464,21668465,21668466,21668467,21668468,21668469,21668470,21668471,21668472,21668473,21668474,21668475,21668476,21668477,21668478,21668479,21668517,21668528,21668529,21668530,21668531,21668532,21668533,21668534,21668535,21668536,21668537,21668538,21668539,21668540,21668541,21668542,21668543,21668544,21668545,21668546,21668547,21668548,21668549,21668550,21668551,21668552,21668553,21668554,21668555,21668556,21668557,21668558,21668559,21668560,21668561,21668562,21668563,21668564,21668565,21668566,21668567,21668568,21668569,21668570,21668571,21668572,21668573,21668574,21668575,21668576,21668577,21668578,21668579,21668580,21668581,21668582,21668583,21668584,21668585,21668586,21668587,21668588,21668589,21668590,21668591,21668592,21668593,21668594,21668595,21668596,21668597,21668598,21668599,21668600,21668601,21668602,21668603,21668604,21668605,21668606,21668607],"Cobblestone":[20645646],"Cobblestone Slab":[20647760,20647762,20647763],"Cobblestone Stairs":[20648720,20648721,20648722,20648723,20648724,20648725,20648726,20648727],"Cobblestone Wall":[20649984,20649985,20649986,20649987,20649988,20649989,20649990,20649991,20649992,20649993,20649994,20649995,20649996,20649997,20649998,20649999,20650000,20650001,20650002,20650003,20650004,20650005,20650006,20650007,20650008,20650009,20650010,20650011,20650012,20650013,20650014,20650015,20650016,20650017,20650018,20650019,20650020,20650021,20650022,20650023,20650024,20650025,20650026,20650027,20650028,20650029,20650030,20650031,20650032,20650033,20650034,20650035,20650036,20650037,20650038,20650039,20650040,20650041,20650042,20650043,20650044,20650045,20650046,20650047,20650080,20650081,20650082,20650083,20650084,20650085,20650086,20650087,20650088,20650089,20650090,20650091,20650092,20650093,20650094,20650095,20650099,20650112,20650113,20650114,20650115,20650116,20650117,20650118,20650119,20650120,20650121,20650122,20650123,20650124,20650125,20650126,20650127,20650128,20650129,20650130,20650131,20650132,20650133,20650134,20650135,20650136,20650137,20650138,20650139,20650140,20650141,20650142,20650143,20650144,20650145,20650146,20650147,20650148,20650149,20650150,20650151,20650152,20650153,20650154,20650155,20650156,20650157,20650158,20650159,20650160,20650161,20650162,20650163,20650164,20650165,20650166,20650167,20650168,20650169,20650170,20650171,20650172,20650173,20650174,20650175,20650208,20650209,20650210,20650211,20650212,20650213,20650214,20650215,20650216,20650217,20650218,20650219,20650220,20650221,20650222,20650223,20650227],"Cobweb":[20652464],"Cocoa Block":[20655024,20655025,20655026,20655027,20655028,20655029,20655030,20655031,20655032,20655033,20655034,20655035],"Compound Creator":[20656176,20656177,20656178,20656179],"Concrete":[20659968,20659969,20659970,20659971,20659972,20659973,20659974,20659975,20659976,20659977,20659978,20659979,20659980,20659981,20659982,20659983],"Concrete Powder":[20661296,20661297,20661298,20661299,20661300,20661301,20661302,20661303,20661304,20661305,20661306,20661307,20661308,20661309,20661310,20661311],"Copernicium":[20802812],"Copper":[20804760],"Copper Block":[21823528,21823529,21823530,21823531,21823532,21823533,21823534,21823535],"Copper Ore":[21798993],"Coral":[20663618,20663620,20663621,20663622,20663623,20663626,20663628,20663629,20663630,20663631],"Coral Block":[20664465,20664468,20664469,20664470,20664471,20664473,20664476,20664477,20664478,20664479],"Coral Fan":[20668131,20668132,20668133,20668134,20668135,20668139,20668140,20668141,20668142,20668143,20668147,20668148,20668149,20668150,20668151,20668155,20668156,20668157,20668158,20668159],"Cornflower":[20670352],"Cracked Deepslate Bricks":[21650157],"Cracked Deepslate Tiles":[21661164],"Cracked Nether Bricks":[21685186],"Cracked Polished Blackstone Bricks":[21628426],"Cracked Stone Bricks":[20670706],"Crafting Table":[20672716],"Crimson Button":[21737520,21737521,21737522,21737523,21737526,21737527,21737528,21737529,21737530,21737531,21737534,21737535],"Crimson Door":[21751360,21751361,21751362,21751363,21751364,21751365,21751366,21751367,21751368,21751369,21751370,21751371,21751372,21751373,21751374,21751375,21751376,21751377,21751378,21751379,21751380,21751381,21751382,21751383,21751384,21751385,21751386,21751387,21751388,21751389,21751390,21751391],"Crimson Fence":[21707929],"Crimson Fence Gate":[21757232,21757233,21757234,21757235,21757236,21757237,21757238,21757239,21757240,21757241,21757242,21757243,21757244,21757245,21757246,21757247],"Crimson Hyphae":[21726912,21726913,21726916,21726917,21726918,21726919],"Crimson Planks":[21701319],"Crimson Pressure Plate":[21745172,21745173],"Crimson Roots":[21934477],"Crimson Sign":[21769568,21769569,21769570,21769571,21769572,21769573,21769574,21769575,21769576,21769577,21769578,21769579,21769580,21769581,21769582,21769583],"Crimson Slab":[21714416,21714417,21714418],"Crimson Stairs":[21763896,21763897,21763898,21763899,21763900,21763901,21763902,21763903],"Crimson Stem":[21719642,21719643,21719644,21719645,21719646,21719647],"Crimson Trapdoor":[21733344,21733345,21733346,21733347,21733348,21733349,21733350,21733351,21733352,21733353,21733354,21733355,21733356,21733357,21733358,21733359],"Crimson Wall Sign":[21774384,21774385,21774386,21774387],"Crying Obsidian":[21818013],"Curium":[20805897],"Cut Copper Block":[21827208,21827209,21827210,21827211,21827212,21827213,21827214,21827215],"Cut Copper Slab Slab":[21827976,21827977,21827978,21827979,21827980,21827981,21827982,21827983,21827984,21827985,21827986,21827987,21827988,21827989,21827990,21827991,21827992,21827993,21827994,21827995,21827996,21827997,21827998,21827999],"Cut Copper Stairs":[21830080,21830081,21830082,21830083,21830084,21830085,21830086,21830087,21830088,21830089,21830090,21830091,21830092,21830093,21830094,21830095,21830096,21830097,21830098,21830099,21830100,21830101,21830102,21830103,21830104,21830105,21830106,21830107,21830108,21830109,21830110,21830111,21830112,21830113,21830114,21830115,21830116,21830117,21830118,21830119,21830120,21830121,21830122,21830123,21830124,21830125,21830126,21830127,21830128,21830129,21830130,21830131,21830132,21830133,21830134,21830135,21830136,21830137,21830138,21830139,21830140,21830141,21830142,21830143],"Cut Red Sandstone":[20674620],"Cut Red Sandstone Slab":[20676996,20676997,20676999],"Cut Sandstone":[20679139],"Cut Sandstone Slab":[20681972,20681973,20681974],"Dandelion":[20686168],"Dark Oak Button":[20688624,20688625,20688626,20688627,20688630,20688631,20688632,20688633,20688634,20688635,20688638,20688639],"Dark Oak Door":[20690144,20690145,20690146,20690147,20690148,20690149,20690150,20690151,20690152,20690153,20690154,20690155,20690156,20690157,20690158,20690159,20690160,20690161,20690162,20690163,20690164,20690165,20690166,20690167,20690168,20690169,20690170,20690171,20690172,20690173,20690174,20690175],"Dark Oak Fence":[20692929],"Dark Oak Fence Gate":[20694464,20694465,20694466,20694467,20694468,20694469,20694470,20694471,20694472,20694473,20694474,20694475,20694476,20694477,20694478,20694479],"Dark Oak Leaves":[20696240,20696241,20696242,20696243],"Dark Oak Log":[20698832,20698833,20698836,20698837,20698838,20698839],"Dark Oak Planks":[20699858],"Dark Oak Pressure Plate":[20701726,20701727],"Dark Oak Sapling":[20704518,20704519],"Dark Oak Sign":[20705760,20705761,20705762,20705763,20705764,20705765,20705766,20705767,20705768,20705769,20705770,20705771,20705772,20705773,20705774,20705775],"Dark Oak Slab":[20708816,20708817,20708818],"Dark Oak Stairs":[20711344,20711345,20711346,20711347,20711348,20711349,20711350,20711351],"Dark Oak Trapdoor":[20713024,20713025,20713026,20713027,20713028,20713029,20713030,20713031,20713032,20713033,20713034,20713035,20713036,20713037,20713038,20713039],"Dark Oak Wall Sign":[20715224,20715225,20715226,20715227],"Dark Oak Wood":[20716738,20716739,20716740,20716741,20716742,20716743],"Dark Prismarine":[20719220],"Dark Prismarine Slab":[20721200,20721202,20721203],"Dark Prismarine Stairs":[20722592,20722593,20722594,20722595,20722596,20722597,20722598,20722599],"Darmstadtium":[20809292],"Daylight Sensor":[20724416,20724417,20724418,20724419,20724420,20724421,20724422,20724423,20724424,20724425,20724426,20724427,20724428,20724429,20724430,20724431,20724432,20724433,20724434,20724435,20724436,20724437,20724438,20724439,20724440,20724441,20724442,20724443,20724444,20724445,20724446,20724447],"Dead Bush":[20727625],"Deepslate":[21640384,21640385,21640387],"Deepslate Brick Slab":[21644892,21644893,21644894],"Deepslate Brick Stairs":[21646904,21646905,21646906,21646907,21646908,21646909,21646910,21646911],"Deepslate Brick Wall":[21649152,21649153,21649154,21649155,21649156,21649157,21649158,21649159,21649160,21649161,21649162,21649163,21649164,21649165,21649166,21649167,21649168,21649169,21649170,21649171,21649172,21649173,21649174,21649175,21649176,21649177,21649178,21649179,21649180,21649181,21649182,21649183,21649184,21649185,21649186,21649187,21649188,21649189,21649190,21649191,21649192,21649193,21649194,21649195,21649196,21649197,21649198,21649199,21649200,21649201,21649202,21649203,21649204,21649205,21649206,21649207,21649208,21649209,21649210,21649211,21649212,21649213,21649214,21649215,21649217,21649232,21649233,21649234,21649235,21649236,21649237,21649238,21649239,21649240,21649241,21649242,21649243,21649244,21649245,21649246,21649247,21649280,21649281,21649282,21649283,21649284,21649285,21649286,21649287,21649288,21649289,21649290,21649291,21649292,21649293,21649294,21649295,21649296,21649297,21649298,21649299,21649300,21649301,21649302,21649303,21649304,21649305,21649306,21649307,21649308,21649309,21649310,21649311,21649312,21649313,21649314,21649315,21649316,21649317,21649318,21649319,21649320,21649321,21649322,21649323,21649324,21649325,21649326,21649327,21649328,21649329,21649330,21649331,21649332,21649333,21649334,21649335,21649336,21649337,21649338,21649339,21649340,21649341,21649342,21649343,21649345,21649360,21649361,21649362,21649363,21649364,21649365,21649366,21649367,21649368,21649369,21649370,21649371,21649372,21649373,21649374,21649375],"Deepslate Bricks":[21642473],"Deepslate Coal Ore":[21783821],"Deepslate Copper Ore":[21797493],"Deepslate Diamond Ore":[21785055],"Deepslate Emerald Ore":[21788073],"Deepslate Gold Ore":[21795656],"Deepslate Iron Ore":[21794765],"Deepslate Lapis Lazuli Ore":[21788910],"Deepslate Redstone Ore":[21791572,21791573],"Deepslate Tile Slab":[21655484,21655485,21655487],"Deepslate Tile Stairs":[21657328,21657329,21657330,21657331,21657332,21657333,21657334,21657335],"Deepslate Tile Wall":[21658912,21658913,21658914,21658915,21658916,21658917,21658918,21658919,21658920,21658921,21658922,21658923,21658924,21658925,21658926,21658927,21658930,21658944,21658945,21658946,21658947,21658948,21658949,21658950,21658951,21658952,21658953,21658954,21658955,21658956,21658957,21658958,21658959,21658960,21658961,21658962,21658963,21658964,21658965,21658966,21658967,21658968,21658969,21658970,21658971,21658972,21658973,21658974,21658975,21658976,21658977,21658978,21658979,21658980,21658981,21658982,21658983,21658984,21658985,21658986,21658987,21658988,21658989,21658990,21658991,21658992,21658993,21658994,21658995,21658996,21658997,21658998,21658999,21659000,21659001,21659002,21659003,21659004,21659005,21659006,21659007,21659040,21659041,21659042,21659043,21659044,21659045,21659046,21659047,21659048,21659049,21659050,21659051,21659052,21659053,21659054,21659055,21659058,21659072,21659073,21659074,21659075,21659076,21659077,21659078,21659079,21659080,21659081,21659082,21659083,21659084,21659085,21659086,21659087,21659088,21659089,21659090,21659091,21659092,21659093,21659094,21659095,21659096,21659097,21659098,21659099,21659100,21659101,21659102,21659103,21659104,21659105,21659106,21659107,21659108,21659109,21659110,21659111,21659112,21659113,21659114,21659115,21659116,21659117,21659118,21659119,21659120,21659121,21659122,21659123,21659124,21659125,21659126,21659127,21659128,21659129,21659130,21659131,21659132,21659133,21659134,21659135],"Deepslate Tiles":[21652461],"Detector Rail":[20728240,20728241,20728242,20728243,20728246,20728247,20728248,20728249,20728250,20728251,20728254,20728255],"Diamond Block":[20730418],"Diamond Ore":[20733642],"Diorite":[20734079],"Diorite Slab":[20737469,20737470,20737471],"Diorite Stairs":[20739504,20739505,20739506,20739507,20739508,20739509,20739510,20739511],"Diorite Wall":[20741920,20741921,20741922,20741923,20741924,20741925,20741926,20741927,20741928,20741929,20741930,20741931,20741932,20741933,20741934,20741935,20741937,20741952,20741953,20741954,20741955,20741956,20741957,20741958,20741959,20741960,20741961,20741962,20741963,20741964,20741965,20741966,20741967,20741968,20741969,20741970,20741971,20741972,20741973,20741974,20741975,20741976,20741977,20741978,20741979,20741980,20741981,20741982,20741983,20741984,20741985,20741986,20741987,20741988,20741989,20741990,20741991,20741992,20741993,20741994,20741995,20741996,20741997,20741998,20741999,20742000,20742001,20742002,20742003,20742004,20742005,20742006,20742007,20742008,20742009,20742010,20742011,20742012,20742013,20742014,20742015,20742048,20742049,20742050,20742051,20742052,20742053,20742054,20742055,20742056,20742057,20742058,20742059,20742060,20742061,20742062,20742063,20742065,20742080,20742081,20742082,20742083,20742084,20742085,20742086,20742087,20742088,20742089,20742090,20742091,20742092,20742093,20742094,20742095,20742096,20742097,20742098,20742099,20742100,20742101,20742102,20742103,20742104,20742105,20742106,20742107,20742108,20742109,20742110,20742111,20742112,20742113,20742114,20742115,20742116,20742117,20742118,20742119,20742120,20742121,20742122,20742123,20742124,20742125,20742126,20742127,20742128,20742129,20742130,20742131,20742132,20742133,20742134,20742135,20742136,20742137,20742138,20742139,20742140,20742141,20742142,20742143],"Dirt":[20742760,20742761,20742763],"Double Pitcher Crop":[21950064,21950065,21950066,21950067],"Double Tallgrass":[20744902,20744903],"Dragon Egg":[20747804],"Dried Kelp Block":[20749160],"Dubnium":[20811286],"Dyed Candle":[21834240,21834241,21834242,21834243,21834244,21834245,21834246,21834247,21834248,21834249,21834250,21834251,21834252,21834253,21834254,21834255,21834256,21834257,21834258,21834259,21834260,21834261,21834262,21834263,21834264,21834265,21834266,21834267,21834268,21834269,21834270,21834271,21834272,21834273,21834274,21834275,21834276,21834277,21834278,21834279,21834280,21834281,21834282,21834283,21834284,21834285,21834286,21834287,21834288,21834289,21834290,21834291,21834292,21834293,21834294,21834295,21834296,21834297,21834298,21834299,21834300,21834301,21834302,21834303,21834304,21834305,21834306,21834307,21834308,21834309,21834310,21834311,21834312,21834313,21834314,21834315,21834316,21834317,21834318,21834319,21834320,21834321,21834322,21834323,21834324,21834325,21834326,21834327,21834328,21834329,21834330,21834331,21834332,21834333,21834334,21834335,21834336,21834337,21834338,21834339,21834340,21834341,21834342,21834343,21834344,21834345,21834346,21834347,21834348,21834349,21834350,21834351,21834352,21834353,21834354,21834355,21834356,21834357,21834358,21834359,21834360,21834361,21834362,21834363,21834364,21834365,21834366,21834367],"Dyed Shulker Box":[20750816,20750817,20750818,20750819,20750820,20750821,20750822,20750823,20750824,20750825,20750826,20750827,20750828,20750829,20750830,20750831],"Dysprosium":[20812845],"Einsteinium":[20813977],"Element Constructor":[20799584,20799585,20799586,20799587],"Emerald Block":[20998956],"Emerald Ore":[21001840],"Enchanting Table":[21002728],"End Portal Frame":[21005904,21005905,21005906,21005907,21005908,21005909,21005910,21005911],"End Rod":[21006744,21006745,21006746,21006747,21006750,21006751],"End Stone":[21010195],"End Stone Brick Slab":[21011608,21011609,21011611],"End Stone Brick Stairs":[21014200,21014201,21014202,21014203,21014204,21014205,21014206,21014207],"End Stone Brick Wall":[21015589,21015600,21015601,21015602,21015603,21015604,21015605,21015606,21015607,21015608,21015609,21015610,21015611,21015612,21015613,21015614,21015615,21015616,21015617,21015618,21015619,21015620,21015621,21015622,21015623,21015624,21015625,21015626,21015627,21015628,21015629,21015630,21015631,21015632,21015633,21015634,21015635,21015636,21015637,21015638,21015639,21015640,21015641,21015642,21015643,21015644,21015645,21015646,21015647,21015648,21015649,21015650,21015651,21015652,21015653,21015654,21015655,21015656,21015657,21015658,21015659,21015660,21015661,21015662,21015663,21015664,21015665,21015666,21015667,21015668,21015669,21015670,21015671,21015672,21015673,21015674,21015675,21015676,21015677,21015678,21015679,21015717,21015728,21015729,21015730,21015731,21015732,21015733,21015734,21015735,21015736,21015737,21015738,21015739,21015740,21015741,21015742,21015743,21015744,21015745,21015746,21015747,21015748,21015749,21015750,21015751,21015752,21015753,21015754,21015755,21015756,21015757,21015758,21015759,21015760,21015761,21015762,21015763,21015764,21015765,21015766,21015767,21015768,21015769,21015770,21015771,21015772,21015773,21015774,21015775,21015776,21015777,21015778,21015779,21015780,21015781,21015782,21015783,21015784,21015785,21015786,21015787,21015788,21015789,21015790,21015791,21015792,21015793,21015794,21015795,21015796,21015797,21015798,21015799,21015800,21015801,21015802,21015803,21015804,21015805,21015806,21015807],"End Stone Bricks":[21017562],"Ender Chest":[21019660,21019661,21019662,21019663],"Erbium":[20817537],"Europium":[20819484],"Fake Wooden Slab":[21021009,21021010,21021011],"Farmland":[21022720,21022721,21022722,21022723,21022724,21022725,21022726,21022727,21022728,21022729,21022730,21022731,21022732,21022733,21022734,21022735,21022736,21022737,21022738,21022739,21022740,21022741,21022742,21022743,21022744,21022745,21022746,21022747,21022748,21022749,21022750,21022751,21022752,21022753,21022754,21022755,21022756,21022757,21022758,21022759,21022760,21022761,21022762,21022763,21022764,21022765,21022766,21022767,21022768,21022769,21022770,21022771,21022772,21022773,21022774,21022775,21022776,21022777,21022778,21022779,21022780,21022781,21022782,21022783,21022784,21022785,21022786,21022787,21022788,21022789,21022790,21022791,21022792,21022793,21022794,21022795,21022796,21022797,21022798,21022799,21022800,21022801,21022802,21022803,21022804,21022805,21022806,21022807,21022808,21022809,21022810,21022811,21022812,21022813,21022814,21022815,21022816,21022817,21022818,21022819,21022820,21022821,21022822,21022823,21022824,21022825,21022826,21022827,21022828,21022829,21022830,21022831,21022832,21022833,21022834,21022835,21022836,21022837,21022838,21022839,21022840,21022841,21022842,21022843,21022844,21022845,21022846,21022847,21022848,21022849,21022850,21022851,21022852,21022853,21022854,21022855,21022856,21022857,21022858,21022859,21022860,21022861,21022862,21022863,21022864,21022865,21022866,21022867,21022868,21022869,21022870,21022871,21022872,21022873,21022874,21022875,21022876,21022877,21022878,21022879,21022880,21022881,21022882,21022883,21022884,21022885,21022886,21022887,21022888,21022889,21022890,21022891,21022892,21022893,21022894,21022895,21022896,21022897,21022898,21022899,21022900,21022901,21022902,21022903,21022904,21022905,21022906,21022907,21022908,21022909,21022910,21022911,21022912,21022913,21022914,21022915,21022916,21022917,21022918,21022919,21022920,21022921,21022922,21022923,21022924,21022925,21022926,21022927,21022928,21022929,21022930,21022931,21022932,21022933,21022934,21022935,21022936,21022937,21022938,21022939,21022940,21022941,21022942,21022943,21022944,21022945,21022946,21022947,21022948,21022949,21022950,21022951,21022952,21022953,21022954,21022955,21022956,21022957,21022958,21022959,21022960,21022961,21022962,21022963,21022964,21022965,21022966,21022967,21022968,21022969,21022970,21022971,21022972,21022973,21022974,21022975,21022976,21022977,21022978,21022979,21022980,21022981,21022982,21022983,21022984,21022985,21022986,21022987,21022988,21022989,21022990,21022991,21022992,21022993,21022994,21022995,21022996,21022997,21022998,21022999,21023000,21023001,21023002,21023003,21023004,21023005,21023006,21023007,21023008,21023009,21023010,21023011,21023012,21023013,21023014,21023015,21023016,21023017,21023018,21023019,21023020,21023021,21023022,21023023,21023024,21023025,21023026,21023027,21023028,21023029,21023030,21023031,21023032,21023033,21023034,21023035,21023036,21023037,21023038,21023039,21023040,21023041,21023042,21023043,21023044,21023045,21023046,21023047,21023048,21023049,21023050,21023051,21023052,21023053,21023054,21023055,21023056,21023057,21023058,21023059,21023060,21023061,21023062,21023063,21023064,21023065,21023066,21023067,21023068,21023069,21023070,21023071,21023072,21023073,21023074,21023075,21023076,21023077,21023078,21023079,21023080,21023081,21023082,21023083,21023084,21023085,21023086,21023087,21023088,21023089,21023090,21023091,21023092,21023093,21023094,21023095,21023096,21023097,21023098,21023099,21023100,21023101,21023102,21023103,21023104,21023105,21023106,21023107,21023108,21023109,21023110,21023111,21023112,21023113,21023114,21023115,21023116,21023117,21023118,21023119,21023120,21023121,21023122,21023123,21023124,21023125,21023126,21023127,21023128,21023129,21023130,21023131,21023132,21023133,21023134,21023135,21023136,21023137,21023138,21023139,21023140,21023141,21023142,21023143,21023144,21023145,21023146,21023147,21023148,21023149,21023150,21023151,21023152,21023153,21023154,21023155,21023156,21023157,21023158,21023159,21023160,21023161,21023162,21023163,21023164,21023165,21023166,21023167,21023168,21023169,21023170,21023171,21023172,21023173,21023174,21023175,21023176,21023177,21023178,21023179,21023180,21023181,21023182,21023183,21023184,21023185,21023186,21023187,21023188,21023189,21023190,21023191,21023192,21023193,21023194,21023195,21023196,21023197,21023198,21023199,21023200,21023201,21023202,21023203,21023204,21023205,21023206,21023207,21023208,21023209,21023210,21023211,21023212,21023213,21023214,21023215,21023216,21023217,21023218,21023219,21023220,21023221,21023222,21023223,21023224,21023225,21023226,21023227,21023228,21023229,21023230,21023231,21023232,21023233,21023234,21023235,21023236,21023237,21023238,21023239,21023240,21023241,21023242,21023243,21023244,21023245,21023246,21023247,21023248,21023249,21023250,21023251,21023252,21023253,21023254,21023255,21023256,21023257,21023258,21023259,21023260,21023261,21023262,21023263,21023264,21023265,21023266,21023267,21023268,21023269,21023270,21023271,21023272,21023273,21023274,21023275,21023276,21023277,21023278,21023279,21023280,21023281,21023282,21023283,21023284,21023285,21023286,21023287,21023288,21023289,21023290,21023291,21023292,21023293,21023294,21023295,21023296,21023297,21023298,21023299,21023300,21023301,21023302,21023303,21023304,21023305,21023306,21023307,21023308,21023309,21023310,21023311,21023312,21023313,21023314,21023315,21023316,21023317,21023318,21023319,21023320,21023321,21023322,21023323,21023324,21023325,21023326,21023327,21023328,21023329,21023330,21023331,21023332,21023333,21023334,21023335,21023336,21023337,21023338,21023339,21023340,21023341,21023342,21023343,21023344,21023345,21023346,21023347,21023348,21023349,21023350,21023351,21023352,21023353,21023354,21023355,21023356,21023357,21023358,21023359,21023360,21023361,21023362,21023363,21023364,21023365,21023366,21023367,21023368,21023369,21023370,21023371,21023372,21023373,21023374,21023375,21023376,21023377,21023378,21023379,21023380,21023381,21023382,21023383,21023384,21023385,21023386,21023387,21023388,21023389,21023390,21023391,21023392,21023393,21023394,21023395,21023396,21023397,21023398,21023399,21023400,21023401,21023402,21023403,21023404,21023405,21023406,21023407,21023408,21023409,21023410,21023411,21023412,21023413,21023414,21023415,21023416,21023417,21023418,21023419,21023420,21023421,21023422,21023423,21023424,21023425,21023426,21023427,21023428,21023429,21023430,21023431,21023432,21023433,21023434,21023435,21023436,21023437,21023438,21023439,21023440,21023441,21023442,21023443,21023444,21023445,21023446,21023447,21023448,21023449,21023450,21023451,21023452,21023453,21023454,21023455,21023456,21023457,21023458,21023459,21023460,21023461,21023462,21023463,21023464,21023465,21023466,21023467,21023468,21023469,21023470,21023471,21023472,21023473,21023474,21023475,21023476,21023477,21023478,21023479,21023480,21023481,21023482,21023483,21023484,21023485,21023486,21023487,21023488,21023489,21023490,21023491,21023492,21023493,21023494,21023495,21023496,21023497,21023498,21023499,21023500,21023501,21023502,21023503,21023504,21023505,21023506,21023507,21023508,21023509,21023510,21023511,21023512,21023513,21023514,21023515,21023516,21023517,21023518,21023519,21023520,21023521,21023522,21023523,21023524,21023525,21023526,21023527,21023528,21023529,21023530,21023531,21023532,21023533,21023534,21023535,21023536,21023537,21023538,21023539,21023540,21023541,21023542,21023543,21023544,21023545,21023546,21023547,21023548,21023549,21023550,21023551,21023552,21023553,21023554,21023555,21023556,21023557,21023558,21023559,21023560,21023561,21023562,21023563,21023564,21023565,21023566,21023567,21023568,21023569,21023570,21023571,21023572,21023573,21023574,21023575,21023576,21023577,21023578,21023579,21023580,21023581,21023582,21023583,21023584,21023585,21023586,21023587,21023588,21023589,21023590,21023591,21023592,21023593,21023594,21023595,21023596,21023597,21023598,21023599,21023600,21023601,21023602,21023603,21023604,21023605,21023606,21023607,21023608,21023609,21023610,21023611,21023612,21023613,21023614,21023615,21023616,21023617,21023618,21023619,21023620,21023621,21023622,21023623,21023624,21023625,21023626,21023627,21023628,21023629,21023630,21023631,21023632,21023633,21023634,21023635,21023636,21023637,21023638,21023639,21023640,21023641,21023642,21023643,21023644,21023645,21023646,21023647,21023648,21023649,21023650,21023651,21023652,21023653,21023654,21023655,21023656,21023657,21023658,21023659,21023660,21023661,21023662,21023663,21023664,21023665,21023666,21023667,21023668,21023669,21023670,21023671,21023672,21023673,21023674,21023675,21023676,21023677,21023678,21023679,21023680,21023681,21023682,21023683,21023684,21023685,21023686,21023687,21023688,21023689,21023690,21023691,21023692,21023693,21023694,21023695,21023696,21023697,21023698,21023699,21023700,21023701,21023702,21023703,21023704,21023705,21023706,21023707,21023708,21023709,21023710,21023711,21023712,21023713,21023714,21023715,21023716,21023717,21023718,21023719,21023720,21023721,21023722,21023723,21023724,21023725,21023726,21023727,21023728,21023729,21023730,21023731,21023732,21023733,21023734,21023735,21023736,21023737,21023738,21023739,21023740,21023741,21023742,21023743,21024256,21024257,21024258,21024259,21024260,21024261,21024262,21024263,21024264,21024265,21024266,21024267,21024268,21024269,21024270,21024271,21024272,21024273,21024274,21024275,21024276,21024277,21024278,21024279,21024280,21024281,21024282,21024283,21024284,21024285,21024286,21024287,21024288,21024289,21024290,21024291,21024292,21024293,21024294,21024295,21024296,21024297,21024298,21024299,21024300,21024301,21024302,21024303,21024304,21024305,21024306,21024307,21024308,21024309,21024310,21024311,21024312,21024313,21024314,21024315,21024316,21024317,21024318,21024319,21024320,21024321,21024322,21024323,21024324,21024325,21024326,21024327,21024328,21024329,21024330,21024331,21024332,21024333,21024334,21024335,21024336,21024337,21024338,21024339,21024340,21024341,21024342,21024343,21024344,21024345,21024346,21024347,21024348,21024349,21024350,21024351,21024352,21024353,21024354,21024355,21024356,21024357,21024358,21024359,21024360,21024361,21024362,21024363,21024364,21024365,21024366,21024367,21024368,21024369,21024370,21024371,21024372,21024373,21024374,21024375,21024376,21024377,21024378,21024379,21024380,21024381,21024382,21024383,21024384,21024385,21024386,21024387,21024388,21024389,21024390,21024391,21024392,21024393,21024394,21024395,21024396,21024397,21024398,21024399,21024400,21024401,21024402,21024403,21024404,21024405,21024406,21024407,21024408,21024409,21024410,21024411,21024412,21024413,21024414,21024415,21024416,21024417,21024418,21024419,21024420,21024421,21024422,21024423,21024424,21024425,21024426,21024427,21024428,21024429,21024430,21024431,21024432,21024433,21024434,21024435,21024436,21024437,21024438,21024439,21024440,21024441,21024442,21024443,21024444,21024445,21024446,21024447,21024448,21024449,21024450,21024451,21024452,21024453,21024454,21024455,21024456,21024457,21024458,21024459,21024460,21024461,21024462,21024463,21024464,21024465,21024466,21024467,21024468,21024469,21024470,21024471,21024472,21024473,21024474,21024475,21024476,21024477,21024478,21024479,21024480,21024481,21024482,21024483,21024484,21024485,21024486,21024487,21024488,21024489,21024490,21024491,21024492,21024493,21024494,21024495,21024496,21024497,21024498,21024499,21024500,21024501,21024502,21024503,21024504,21024505,21024506,21024507,21024508,21024509,21024510,21024511,21024640,21024641,21024642,21024643,21024644,21024645,21024646,21024647,21024648,21024649,21024650,21024651,21024652,21024653,21024654,21024655,21024664,21024665,21024666,21024667,21024668,21024669,21024670,21024671],"Fermium":[20821256],"Fern":[21026077],"Fire Block":[21027184,21027185,21027186,21027187,21027188,21027189,21027190,21027191,21027192,21027193,21027194,21027195,21027196,21027197,21027198,21027199],"Flerovium":[20823370],"Fletching Table":[21030063],"Flower Pot":[21031217],"Flowering Azalea Leaves":[21888168,21888169,21888170,21888171],"Fluorine":[20824372],"Francium":[20827305],"Froglight":[21872001,21872002,21872003,21872005,21872006,21872007,21872009,21872010,21872011],"Frosted Ice":[21034052,21034053,21034054,21034055],"Furnace":[21036512,21036513,21036514,21036515,21036516,21036517,21036518,21036519],"Gadolinium":[20828273],"Gallium":[20832169],"Germanium":[20833509],"Gilded Blackstone":[21820646],"Glass":[21038329],"Glass Pane":[21040585],"Glazed Terracotta":[21585152,21585153,21585154,21585155,21585156,21585157,21585158,21585159,21585160,21585161,21585162,21585163,21585164,21585165,21585166,21585167,21585168,21585169,21585170,21585171,21585172,21585173,21585174,21585175,21585176,21585177,21585178,21585179,21585180,21585181,21585182,21585183,21585184,21585185,21585186,21585187,21585188,21585189,21585190,21585191,21585192,21585193,21585194,21585195,21585196,21585197,21585198,21585199,21585200,21585201,21585202,21585203,21585204,21585205,21585206,21585207,21585208,21585209,21585210,21585211,21585212,21585213,21585214,21585215],"Glow Item Frame":[21881552,21881553,21881556,21881557,21881558,21881559,21881560,21881561,21881564,21881565,21881566,21881567],"Glow Lichen":[21893760,21893761,21893762,21893763,21893764,21893765,21893766,21893767,21893768,21893769,21893770,21893771,21893772,21893773,21893774,21893775,21893776,21893777,21893778,21893779,21893780,21893781,21893782,21893783,21893784,21893785,21893786,21893787,21893788,21893789,21893790,21893791,21893792,21893793,21893794,21893795,21893796,21893797,21893798,21893799,21893800,21893801,21893802,21893803,21893804,21893805,21893806,21893807,21893808,21893809,21893810,21893811,21893812,21893813,21893814,21893815,21893816,21893817,21893818,21893819,21893820,21893821,21893822,21893823],"Glowing Obsidian":[21043028],"Glowstone":[21043624],"Gold":[20835704],"Gold Block":[21046696],"Gold Ore":[21049010],"Granite":[21049750],"Granite Slab":[21053256,21053257,21053258],"Granite Stairs":[21054536,21054537,21054538,21054539,21054540,21054541,21054542,21054543],"Granite Wall":[21055488,21055489,21055490,21055491,21055492,21055493,21055494,21055495,21055496,21055497,21055498,21055499,21055500,21055501,21055502,21055503,21055504,21055505,21055506,21055507,21055508,21055509,21055510,21055511,21055512,21055513,21055514,21055515,21055516,21055517,21055518,21055519,21055520,21055521,21055522,21055523,21055524,21055525,21055526,21055527,21055528,21055529,21055530,21055531,21055532,21055533,21055534,21055535,21055536,21055537,21055538,21055539,21055540,21055541,21055542,21055543,21055544,21055545,21055546,21055547,21055548,21055549,21055550,21055551,21055584,21055585,21055586,21055587,21055588,21055589,21055590,21055591,21055592,21055593,21055594,21055595,21055596,21055597,21055598,21055599,21055615,21055616,21055617,21055618,21055619,21055620,21055621,21055622,21055623,21055624,21055625,21055626,21055627,21055628,21055629,21055630,21055631,21055632,21055633,21055634,21055635,21055636,21055637,21055638,21055639,21055640,21055641,21055642,21055643,21055644,21055645,21055646,21055647,21055648,21055649,21055650,21055651,21055652,21055653,21055654,21055655,21055656,21055657,21055658,21055659,21055660,21055661,21055662,21055663,21055664,21055665,21055666,21055667,21055668,21055669,21055670,21055671,21055672,21055673,21055674,21055675,21055676,21055677,21055678,21055679,21055712,21055713,21055714,21055715,21055716,21055717,21055718,21055719,21055720,21055721,21055722,21055723,21055724,21055725,21055726,21055727,21055743],"Grass":[21058118],"Grass Path":[21061327],"Gravel":[21062456],"Green Torch":[21068985,21068986,21068987,21068988,21068989],"Hafnium":[20837560],"Hanging Roots":[21842426],"Hardened Clay":[21071190],"Hardened Glass":[21072075],"Hardened Glass Pane":[21075766],"Hassium":[20839994],"Hay Bale":[21077748,21077749,21077750],"Heat Block":[20625734],"Helium":[20840704],"Holmium":[20842739],"Honeycomb Block":[21782395],"Hopper":[21079520,21079521,21079525,21079526,21079527,21079528,21079529,21079533,21079534,21079535],"Hydrogen":[20844910],"Ice":[21080304],"Indium":[20848311],"Infested Chiseled Stone Brick":[21083943],"Infested Cobblestone":[21085393],"Infested Cracked Stone Brick":[21087627],"Infested Mossy Stone Brick":[21088835],"Infested Stone":[21091396],"Infested Stone Brick":[21092358],"Invisible Bedrock":[21100447],"Iodine":[20850310],"Iridium":[20851638],"Iron":[20854572],"Iron Bars":[21104146],"Iron Block":[21101750],"Iron Door":[21105792,21105793,21105794,21105795,21105796,21105797,21105798,21105799,21105800,21105801,21105802,21105803,21105804,21105805,21105806,21105807,21105808,21105809,21105810,21105811,21105812,21105813,21105814,21105815,21105816,21105817,21105818,21105819,21105820,21105821,21105822,21105823],"Iron Ore":[21107313],"Iron Trapdoor":[21109264,21109265,21109266,21109267,21109268,21109269,21109270,21109271,21109272,21109273,21109274,21109275,21109276,21109277,21109278,21109279],"Item Frame":[21111952,21111953,21111954,21111955,21111956,21111957,21111960,21111961,21111962,21111963,21111964,21111965],"Jack o'Lantern":[21179952,21179953,21179954,21179955],"Jukebox":[21113057],"Jungle Button":[21115488,21115489,21115490,21115491,21115492,21115493,21115496,21115497,21115498,21115499,21115500,21115501],"Jungle Door":[21117568,21117569,21117570,21117571,21117572,21117573,21117574,21117575,21117576,21117577,21117578,21117579,21117580,21117581,21117582,21117583,21117584,21117585,21117586,21117587,21117588,21117589,21117590,21117591,21117592,21117593,21117594,21117595,21117596,21117597,21117598,21117599],"Jungle Fence":[21119582],"Jungle Fence Gate":[21122144,21122145,21122146,21122147,21122148,21122149,21122150,21122151,21122152,21122153,21122154,21122155,21122156,21122157,21122158,21122159],"Jungle Leaves":[21124916,21124917,21124918,21124919],"Jungle Log":[21126656,21126657,21126658,21126659,21126662,21126663],"Jungle Planks":[21127877],"Jungle Pressure Plate":[21130628,21130629],"Jungle Sapling":[21132062,21132063],"Jungle Sign":[21134400,21134401,21134402,21134403,21134404,21134405,21134406,21134407,21134408,21134409,21134410,21134411,21134412,21134413,21134414,21134415],"Jungle Slab":[21135720,21135721,21135722],"Jungle Stairs":[21137656,21137657,21137658,21137659,21137660,21137661,21137662,21137663],"Jungle Trapdoor":[21139728,21139729,21139730,21139731,21139732,21139733,21139734,21139735,21139736,21139737,21139738,21139739,21139740,21139741,21139742,21139743],"Jungle Wall Sign":[21143348,21143349,21143350,21143351],"Jungle Wood":[21145480,21145481,21145484,21145485,21145486,21145487],"Krypton":[20856167],"Lab Table":[21146608,21146609,21146610,21146611],"Ladder":[21148984,21148985,21148986,21148987],"Lantern":[21149740,21149741],"Lanthanum":[20858521],"Lapis Lazuli Block":[21152040],"Lapis Lazuli Ore":[21154437],"Large Fern":[21156644,21156645],"Lava":[21159648,21159649,21159650,21159651,21159652,21159653,21159654,21159655,21159656,21159657,21159658,21159659,21159660,21159661,21159662,21159663,21159664,21159665,21159666,21159667,21159668,21159669,21159670,21159671,21159672,21159673,21159674,21159675,21159676,21159677,21159678,21159679],"Lava Cauldron":[21857912,21857913,21857914,21857915,21857916,21857917],"Lawrencium":[20860323],"Lead":[20861284],"Lectern":[21160360,21160361,21160362,21160363,21160364,21160365,21160366,21160367],"Legacy Stonecutter":[21162264],"Lever":[21165776,21165777,21165778,21165779,21165780,21165781,21165782,21165783,21165784,21165785,21165786,21165787,21165788,21165789,21165790,21165791],"Light Block":[21629408,21629409,21629410,21629411,21629412,21629413,21629414,21629415,21629416,21629417,21629418,21629419,21629420,21629421,21629422,21629423],"Lightning Rod":[21821570,21821571,21821572,21821573,21821574,21821575],"Lilac":[21171834,21171835],"Lily Pad":[21174431],"Lily of the Valley":[21173216],"Lithium":[20863911],"Livermorium":[20865878],"Loom":[21182044,21182045,21182046,21182047],"Lutetium":[20867537],"Magma Block":[21186488],"Magnesium":[20869155],"Manganese":[20872294],"Mangrove Button":[21735552,21735553,21735554,21735555,21735558,21735559,21735560,21735561,21735562,21735563,21735566,21735567],"Mangrove Door":[21749248,21749249,21749250,21749251,21749252,21749253,21749254,21749255,21749256,21749257,21749258,21749259,21749260,21749261,21749262,21749263,21749264,21749265,21749266,21749267,21749268,21749269,21749270,21749271,21749272,21749273,21749274,21749275,21749276,21749277,21749278,21749279],"Mangrove Fence":[21706659],"Mangrove Fence Gate":[21755424,21755425,21755426,21755427,21755428,21755429,21755430,21755431,21755432,21755433,21755434,21755435,21755436,21755437,21755438,21755439],"Mangrove Leaves":[21884612,21884613,21884614,21884615],"Mangrove Log":[21717272,21717273,21717274,21717275,21717278,21717279],"Mangrove Planks":[21700363],"Mangrove Pressure Plate":[21742138,21742139],"Mangrove Roots":[21868046],"Mangrove Sign":[21766688,21766689,21766690,21766691,21766692,21766693,21766694,21766695,21766696,21766697,21766698,21766699,21766700,21766701,21766702,21766703],"Mangrove Slab":[21711233,21711234,21711235],"Mangrove Stairs":[21760624,21760625,21760626,21760627,21760628,21760629,21760630,21760631],"Mangrove Trapdoor":[21729584,21729585,21729586,21729587,21729588,21729589,21729590,21729591,21729592,21729593,21729594,21729595,21729596,21729597,21729598,21729599],"Mangrove Wall Sign":[21774240,21774241,21774242,21774243],"Mangrove Wood":[21723914,21723915,21723916,21723917,21723918,21723919],"Material Reducer":[21187744,21187745,21187746,21187747],"Meitnerium":[20874589],"Melon Block":[21189795],"Melon Stem":[21190912,21190913,21190914,21190915,21190916,21190917,21190918,21190919,21190920,21190921,21190922,21190923,21190924,21190925,21190926,21190927,21190944,21190945,21190946,21190947,21190948,21190949,21190950,21190951,21190960,21190961,21190962,21190963,21190964,21190965,21190966,21190967,21190968,21190969,21190970,21190971,21190972,21190973,21190974,21190975],"Mendelevium":[20876625],"Mercury":[20877937],"Mob Head":[21193344,21193345,21193346,21193347,21193349,21193350,21193351,21193352,21193353,21193354,21193355,21193357,21193358,21193359,21193376,21193377,21193378,21193379,21193381,21193382,21193383,21193392,21193393,21193394,21193395,21193397,21193398,21193399,21193400,21193401,21193402,21193403,21193405,21193406,21193407],"Molybdenum":[20879537],"Monster Spawner":[21195322],"Moscovium":[20883402],"Mossy Cobblestone":[21197453],"Mossy Cobblestone Slab":[21200052,21200054,21200055],"Mossy Cobblestone Stairs":[21202568,21202569,21202570,21202571,21202572,21202573,21202574,21202575],"Mossy Cobblestone Wall":[21204224,21204225,21204226,21204227,21204228,21204229,21204230,21204231,21204232,21204233,21204234,21204235,21204236,21204237,21204238,21204239,21204240,21204241,21204242,21204243,21204244,21204245,21204246,21204247,21204248,21204249,21204250,21204251,21204252,21204253,21204254,21204255,21204256,21204257,21204258,21204259,21204260,21204261,21204262,21204263,21204264,21204265,21204266,21204267,21204268,21204269,21204270,21204271,21204272,21204273,21204274,21204275,21204276,21204277,21204278,21204279,21204280,21204281,21204282,21204283,21204284,21204285,21204286,21204287,21204288,21204289,21204290,21204291,21204292,21204293,21204294,21204295,21204296,21204297,21204298,21204299,21204300,21204301,21204302,21204303,21204306,21204352,21204353,21204354,21204355,21204356,21204357,21204358,21204359,21204360,21204361,21204362,21204363,21204364,21204365,21204366,21204367,21204368,21204369,21204370,21204371,21204372,21204373,21204374,21204375,21204376,21204377,21204378,21204379,21204380,21204381,21204382,21204383,21204384,21204385,21204386,21204387,21204388,21204389,21204390,21204391,21204392,21204393,21204394,21204395,21204396,21204397,21204398,21204399,21204400,21204401,21204402,21204403,21204404,21204405,21204406,21204407,21204408,21204409,21204410,21204411,21204412,21204413,21204414,21204415,21204416,21204417,21204418,21204419,21204420,21204421,21204422,21204423,21204424,21204425,21204426,21204427,21204428,21204429,21204430,21204431,21204434],"Mossy Stone Brick Slab":[21205992,21205993,21205995],"Mossy Stone Brick Stairs":[21207584,21207585,21207586,21207587,21207588,21207589,21207590,21207591],"Mossy Stone Brick Wall":[21210147,21210160,21210161,21210162,21210163,21210164,21210165,21210166,21210167,21210168,21210169,21210170,21210171,21210172,21210173,21210174,21210175,21210176,21210177,21210178,21210179,21210180,21210181,21210182,21210183,21210184,21210185,21210186,21210187,21210188,21210189,21210190,21210191,21210192,21210193,21210194,21210195,21210196,21210197,21210198,21210199,21210200,21210201,21210202,21210203,21210204,21210205,21210206,21210207,21210208,21210209,21210210,21210211,21210212,21210213,21210214,21210215,21210216,21210217,21210218,21210219,21210220,21210221,21210222,21210223,21210224,21210225,21210226,21210227,21210228,21210229,21210230,21210231,21210232,21210233,21210234,21210235,21210236,21210237,21210238,21210239,21210275,21210288,21210289,21210290,21210291,21210292,21210293,21210294,21210295,21210296,21210297,21210298,21210299,21210300,21210301,21210302,21210303,21210304,21210305,21210306,21210307,21210308,21210309,21210310,21210311,21210312,21210313,21210314,21210315,21210316,21210317,21210318,21210319,21210320,21210321,21210322,21210323,21210324,21210325,21210326,21210327,21210328,21210329,21210330,21210331,21210332,21210333,21210334,21210335,21210336,21210337,21210338,21210339,21210340,21210341,21210342,21210343,21210344,21210345,21210346,21210347,21210348,21210349,21210350,21210351,21210352,21210353,21210354,21210355,21210356,21210357,21210358,21210359,21210360,21210361,21210362,21210363,21210364,21210365,21210366,21210367],"Mossy Stone Bricks":[21212641],"Mud":[21804596],"Mud Brick Slab":[21807848,21807850,21807851],"Mud Brick Stairs":[21810184,21810185,21810186,21810187,21810188,21810189,21810190,21810191],"Mud Brick Wall":[21812238,21812240,21812241,21812242,21812243,21812244,21812245,21812246,21812247,21812248,21812249,21812250,21812251,21812252,21812253,21812254,21812255,21812288,21812289,21812290,21812291,21812292,21812293,21812294,21812295,21812296,21812297,21812298,21812299,21812300,21812301,21812302,21812303,21812304,21812305,21812306,21812307,21812308,21812309,21812310,21812311,21812312,21812313,21812314,21812315,21812316,21812317,21812318,21812319,21812320,21812321,21812322,21812323,21812324,21812325,21812326,21812327,21812328,21812329,21812330,21812331,21812332,21812333,21812334,21812335,21812336,21812337,21812338,21812339,21812340,21812341,21812342,21812343,21812344,21812345,21812346,21812347,21812348,21812349,21812350,21812351,21812366,21812368,21812369,21812370,21812371,21812372,21812373,21812374,21812375,21812376,21812377,21812378,21812379,21812380,21812381,21812382,21812383,21812416,21812417,21812418,21812419,21812420,21812421,21812422,21812423,21812424,21812425,21812426,21812427,21812428,21812429,21812430,21812431,21812432,21812433,21812434,21812435,21812436,21812437,21812438,21812439,21812440,21812441,21812442,21812443,21812444,21812445,21812446,21812447,21812448,21812449,21812450,21812451,21812452,21812453,21812454,21812455,21812456,21812457,21812458,21812459,21812460,21812461,21812462,21812463,21812464,21812465,21812466,21812467,21812468,21812469,21812470,21812471,21812472,21812473,21812474,21812475,21812476,21812477,21812478,21812479],"Mud Bricks":[21805580],"Muddy Mangrove Roots":[21870173,21870174,21870175],"Mushroom Stem":[21214847],"Mycelium":[21215507],"Neodymium":[20883794],"Neon":[20887178],"Neptunium":[20888366],"Nether Brick Fence":[21219143],"Nether Brick Slab":[21219584,21219585,21219587],"Nether Brick Stairs":[21222456,21222457,21222458,21222459,21222460,21222461,21222462,21222463],"Nether Brick Wall":[21223712,21223713,21223714,21223715,21223716,21223717,21223718,21223719,21223720,21223721,21223722,21223723,21223724,21223725,21223726,21223727,21223728,21223744,21223745,21223746,21223747,21223748,21223749,21223750,21223751,21223752,21223753,21223754,21223755,21223756,21223757,21223758,21223759,21223760,21223761,21223762,21223763,21223764,21223765,21223766,21223767,21223768,21223769,21223770,21223771,21223772,21223773,21223774,21223775,21223776,21223777,21223778,21223779,21223780,21223781,21223782,21223783,21223784,21223785,21223786,21223787,21223788,21223789,21223790,21223791,21223792,21223793,21223794,21223795,21223796,21223797,21223798,21223799,21223800,21223801,21223802,21223803,21223804,21223805,21223806,21223807,21223840,21223841,21223842,21223843,21223844,21223845,21223846,21223847,21223848,21223849,21223850,21223851,21223852,21223853,21223854,21223855,21223856,21223872,21223873,21223874,21223875,21223876,21223877,21223878,21223879,21223880,21223881,21223882,21223883,21223884,21223885,21223886,21223887,21223888,21223889,21223890,21223891,21223892,21223893,21223894,21223895,21223896,21223897,21223898,21223899,21223900,21223901,21223902,21223903,21223904,21223905,21223906,21223907,21223908,21223909,21223910,21223911,21223912,21223913,21223914,21223915,21223916,21223917,21223918,21223919,21223920,21223921,21223922,21223923,21223924,21223925,21223926,21223927,21223928,21223929,21223930,21223931,21223932,21223933,21223934,21223935],"Nether Bricks":[21225672],"Nether Gold Ore":[21801107],"Nether Portal":[21229304,21229305],"Nether Quartz Ore":[21230807],"Nether Reactor Core":[21233112],"Nether Wart":[21235588,21235589,21235590,21235591],"Nether Wart Block":[21237079],"Netherite Block":[21848862],"Netherrack":[21239734],"Nickel":[20891060],"Nihonium":[20892811],"Niobium":[20895630],"Nitrogen":[20897160],"Nobelium":[20898460],"Note Block":[21241302],"Oak Button":[21243152,21243153,21243156,21243157,21243158,21243159,21243160,21243161,21243164,21243165,21243166,21243167],"Oak Door":[21245696,21245697,21245698,21245699,21245700,21245701,21245702,21245703,21245704,21245705,21245706,21245707,21245708,21245709,21245710,21245711,21245712,21245713,21245714,21245715,21245716,21245717,21245718,21245719,21245720,21245721,21245722,21245723,21245724,21245725,21245726,21245727],"Oak Fence":[21247506],"Oak Fence Gate":[21248560,21248561,21248562,21248563,21248564,21248565,21248566,21248567,21248568,21248569,21248570,21248571,21248572,21248573,21248574,21248575],"Oak Leaves":[21250248,21250249,21250250,21250251],"Oak Log":[21253352,21253353,21253356,21253357,21253358,21253359],"Oak Planks":[21255504],"Oak Pressure Plate":[21257680,21257681],"Oak Sapling":[21258462,21258463],"Oak Sign":[21262208,21262209,21262210,21262211,21262212,21262213,21262214,21262215,21262216,21262217,21262218,21262219,21262220,21262221,21262222,21262223],"Oak Slab":[21264373,21264374,21264375],"Oak Stairs":[21264984,21264985,21264986,21264987,21264988,21264989,21264990,21264991],"Oak Trapdoor":[21267760,21267761,21267762,21267763,21267764,21267765,21267766,21267767,21267768,21267769,21267770,21267771,21267772,21267773,21267774,21267775],"Oak Wall Sign":[21270344,21270345,21270346,21270347],"Oak Wood":[21272410,21272411,21272412,21272413,21272414,21272415],"Obsidian":[21273247],"Oganesson":[20901372],"Orange Tulip":[21278363],"Osmium":[20902298],"Oxeye Daisy":[21280579],"Oxygen":[20904205],"Packed Ice":[21282488],"Packed Mud":[21814973],"Palladium":[20907027],"Peony":[21283348,21283349],"Phosphorus":[20908773],"Pink Petals":[21933456,21933457,21933458,21933459,21933460,21933461,21933462,21933463,21933464,21933465,21933466,21933467,21933468,21933469,21933470,21933471],"Pink Tulip":[21286997],"Pitcher Crop":[21947997,21947998,21947999],"Pitcher Plant":[21945642,21945643],"Platinum":[20911235],"Plutonium":[20912900],"Podzol":[21290197],"Polished Andesite":[21292531],"Polished Andesite Slab":[21294924,21294925,21294927],"Polished Andesite Stairs":[21295920,21295921,21295922,21295923,21295924,21295925,21295926,21295927],"Polished Basalt":[21592160,21592162,21592163],"Polished Blackstone":[21605632],"Polished Blackstone Brick Slab":[21622088,21622089,21622090],"Polished Blackstone Brick Stairs":[21622992,21622993,21622994,21622995,21622996,21622997,21622998,21622999],"Polished Blackstone Brick Wall":[21624832,21624833,21624834,21624835,21624836,21624837,21624838,21624839,21624840,21624841,21624842,21624843,21624844,21624845,21624846,21624847,21624848,21624849,21624850,21624851,21624852,21624853,21624854,21624855,21624856,21624857,21624858,21624859,21624860,21624861,21624862,21624863,21624864,21624865,21624866,21624867,21624868,21624869,21624870,21624871,21624872,21624873,21624874,21624875,21624876,21624877,21624878,21624879,21624880,21624881,21624882,21624883,21624884,21624885,21624886,21624887,21624888,21624889,21624890,21624891,21624892,21624893,21624894,21624895,21624896,21624912,21624913,21624914,21624915,21624916,21624917,21624918,21624919,21624920,21624921,21624922,21624923,21624924,21624925,21624926,21624927,21624960,21624961,21624962,21624963,21624964,21624965,21624966,21624967,21624968,21624969,21624970,21624971,21624972,21624973,21624974,21624975,21624976,21624977,21624978,21624979,21624980,21624981,21624982,21624983,21624984,21624985,21624986,21624987,21624988,21624989,21624990,21624991,21624992,21624993,21624994,21624995,21624996,21624997,21624998,21624999,21625000,21625001,21625002,21625003,21625004,21625005,21625006,21625007,21625008,21625009,21625010,21625011,21625012,21625013,21625014,21625015,21625016,21625017,21625018,21625019,21625020,21625021,21625022,21625023,21625024,21625040,21625041,21625042,21625043,21625044,21625045,21625046,21625047,21625048,21625049,21625050,21625051,21625052,21625053,21625054,21625055],"Polished Blackstone Bricks":[21619830],"Polished Blackstone Button":[21607152,21607153,21607154,21607155,21607156,21607157,21607160,21607161,21607162,21607163,21607164,21607165],"Polished Blackstone Pressure Plate":[21609892,21609893],"Polished Blackstone Slab":[21611892,21611893,21611894],"Polished Blackstone Stairs":[21614000,21614001,21614002,21614003,21614004,21614005,21614006,21614007],"Polished Blackstone Wall":[21614848,21614849,21614850,21614851,21614852,21614853,21614854,21614855,21614856,21614857,21614858,21614859,21614860,21614861,21614862,21614863,21614864,21614865,21614866,21614867,21614868,21614869,21614870,21614871,21614872,21614873,21614874,21614875,21614876,21614877,21614878,21614879,21614880,21614881,21614882,21614883,21614884,21614885,21614886,21614887,21614888,21614889,21614890,21614891,21614892,21614893,21614894,21614895,21614896,21614897,21614898,21614899,21614900,21614901,21614902,21614903,21614904,21614905,21614906,21614907,21614908,21614909,21614910,21614911,21614917,21614928,21614929,21614930,21614931,21614932,21614933,21614934,21614935,21614936,21614937,21614938,21614939,21614940,21614941,21614942,21614943,21614976,21614977,21614978,21614979,21614980,21614981,21614982,21614983,21614984,21614985,21614986,21614987,21614988,21614989,21614990,21614991,21614992,21614993,21614994,21614995,21614996,21614997,21614998,21614999,21615000,21615001,21615002,21615003,21615004,21615005,21615006,21615007,21615008,21615009,21615010,21615011,21615012,21615013,21615014,21615015,21615016,21615017,21615018,21615019,21615020,21615021,21615022,21615023,21615024,21615025,21615026,21615027,21615028,21615029,21615030,21615031,21615032,21615033,21615034,21615035,21615036,21615037,21615038,21615039,21615045,21615056,21615057,21615058,21615059,21615060,21615061,21615062,21615063,21615064,21615065,21615066,21615067,21615068,21615069,21615070,21615071],"Polished Deepslate":[21670363],"Polished Deepslate Slab":[21672268,21672270,21672271],"Polished Deepslate Stairs":[21674288,21674289,21674290,21674291,21674292,21674293,21674294,21674295],"Polished Deepslate Wall":[21676076,21676080,21676081,21676082,21676083,21676084,21676085,21676086,21676087,21676088,21676089,21676090,21676091,21676092,21676093,21676094,21676095,21676096,21676097,21676098,21676099,21676100,21676101,21676102,21676103,21676104,21676105,21676106,21676107,21676108,21676109,21676110,21676111,21676112,21676113,21676114,21676115,21676116,21676117,21676118,21676119,21676120,21676121,21676122,21676123,21676124,21676125,21676126,21676127,21676128,21676129,21676130,21676131,21676132,21676133,21676134,21676135,21676136,21676137,21676138,21676139,21676140,21676141,21676142,21676143,21676144,21676145,21676146,21676147,21676148,21676149,21676150,21676151,21676152,21676153,21676154,21676155,21676156,21676157,21676158,21676159,21676204,21676208,21676209,21676210,21676211,21676212,21676213,21676214,21676215,21676216,21676217,21676218,21676219,21676220,21676221,21676222,21676223,21676224,21676225,21676226,21676227,21676228,21676229,21676230,21676231,21676232,21676233,21676234,21676235,21676236,21676237,21676238,21676239,21676240,21676241,21676242,21676243,21676244,21676245,21676246,21676247,21676248,21676249,21676250,21676251,21676252,21676253,21676254,21676255,21676256,21676257,21676258,21676259,21676260,21676261,21676262,21676263,21676264,21676265,21676266,21676267,21676268,21676269,21676270,21676271,21676272,21676273,21676274,21676275,21676276,21676277,21676278,21676279,21676280,21676281,21676282,21676283,21676284,21676285,21676286,21676287],"Polished Diorite":[21298589],"Polished Diorite Slab":[21299568,21299570,21299571],"Polished Diorite Stairs":[21301328,21301329,21301330,21301331,21301332,21301333,21301334,21301335],"Polished Granite":[21304978],"Polished Granite Slab":[21307024,21307025,21307027],"Polished Granite Stairs":[21307536,21307537,21307538,21307539,21307540,21307541,21307542,21307543],"Polonium":[20915922],"Poppy":[21310628],"Potassium":[20916939],"Potato Block":[21312968,21312969,21312970,21312971,21312972,21312973,21312974,21312975],"Potion Cauldron":[21859216,21859217,21859218,21859219,21859220,21859221],"Powered Rail":[21313936,21313937,21313938,21313939,21313942,21313943,21313944,21313945,21313946,21313947,21313950,21313951],"Praseodymium":[20918290],"Prismarine":[21317514],"Prismarine Bricks":[21318880],"Prismarine Bricks Slab":[21319764,21319766,21319767],"Prismarine Bricks Stairs":[21322480,21322481,21322482,21322483,21322484,21322485,21322486,21322487],"Prismarine Slab":[21324568,21324569,21324571],"Prismarine Stairs":[21327832,21327833,21327834,21327835,21327836,21327837,21327838,21327839],"Prismarine Wall":[21327872,21327873,21327874,21327875,21327876,21327877,21327878,21327879,21327880,21327881,21327882,21327883,21327884,21327885,21327886,21327887,21327888,21327889,21327890,21327891,21327892,21327893,21327894,21327895,21327896,21327897,21327898,21327899,21327900,21327901,21327902,21327903,21327904,21327905,21327906,21327907,21327908,21327909,21327910,21327911,21327912,21327913,21327914,21327915,21327916,21327917,21327918,21327919,21327920,21327921,21327922,21327923,21327924,21327925,21327926,21327927,21327928,21327929,21327930,21327931,21327932,21327933,21327934,21327935,21327974,21327984,21327985,21327986,21327987,21327988,21327989,21327990,21327991,21327992,21327993,21327994,21327995,21327996,21327997,21327998,21327999,21328000,21328001,21328002,21328003,21328004,21328005,21328006,21328007,21328008,21328009,21328010,21328011,21328012,21328013,21328014,21328015,21328016,21328017,21328018,21328019,21328020,21328021,21328022,21328023,21328024,21328025,21328026,21328027,21328028,21328029,21328030,21328031,21328032,21328033,21328034,21328035,21328036,21328037,21328038,21328039,21328040,21328041,21328042,21328043,21328044,21328045,21328046,21328047,21328048,21328049,21328050,21328051,21328052,21328053,21328054,21328055,21328056,21328057,21328058,21328059,21328060,21328061,21328062,21328063,21328102,21328112,21328113,21328114,21328115,21328116,21328117,21328118,21328119,21328120,21328121,21328122,21328123,21328124,21328125,21328126,21328127],"Promethium":[20920321],"Protactinium":[20923161],"Pumpkin":[21331624],"Pumpkin Stem":[21333968,21333969,21333970,21333971,21333972,21333973,21333974,21333975,21333976,21333977,21333978,21333979,21333980,21333981,21333982,21333983,21333984,21333985,21333986,21333987,21333988,21333989,21333990,21333991,21333992,21333993,21333994,21333995,21333996,21333997,21333998,21333999,21334000,21334001,21334002,21334003,21334004,21334005,21334006,21334007],"Purple Torch":[21337610,21337611,21337612,21337613,21337614],"Purpur Block":[21338315],"Purpur Pillar":[21340545,21340546,21340547],"Purpur Slab":[21344168,21344169,21344170],"Purpur Stairs":[21344432,21344433,21344434,21344435,21344436,21344437,21344438,21344439],"Quartz Block":[21347391],"Quartz Bricks":[21678669],"Quartz Pillar":[21348820,21348821,21348823],"Quartz Slab":[21351776,21351777,21351779],"Quartz Stairs":[21352904,21352905,21352906,21352907,21352908,21352909,21352910,21352911],"Radium":[20925466],"Radon":[20927914],"Rail":[21356230,21356231,21356232,21356233,21356234,21356235,21356236,21356237,21356238,21356239],"Raw Copper Block":[21632127],"Raw Gold Block":[21634601],"Raw Iron Block":[21635367],"Red Mushroom":[21359866],"Red Mushroom Block":[21361105,21361106,21361107,21361112,21361113,21361114,21361115,21361116,21361117,21361118,21361119],"Red Nether Brick Slab":[21363940,21363942,21363943],"Red Nether Brick Stairs":[21365640,21365641,21365642,21365643,21365644,21365645,21365646,21365647],"Red Nether Brick Wall":[21367808,21367809,21367810,21367811,21367812,21367813,21367814,21367815,21367816,21367817,21367818,21367819,21367820,21367821,21367822,21367823,21367824,21367825,21367826,21367827,21367828,21367829,21367830,21367831,21367832,21367833,21367834,21367835,21367836,21367837,21367838,21367839,21367840,21367841,21367842,21367843,21367844,21367845,21367846,21367847,21367848,21367849,21367850,21367851,21367852,21367853,21367854,21367855,21367856,21367857,21367858,21367859,21367860,21367861,21367862,21367863,21367864,21367865,21367866,21367867,21367868,21367869,21367870,21367871,21367872,21367888,21367889,21367890,21367891,21367892,21367893,21367894,21367895,21367896,21367897,21367898,21367899,21367900,21367901,21367902,21367903,21367936,21367937,21367938,21367939,21367940,21367941,21367942,21367943,21367944,21367945,21367946,21367947,21367948,21367949,21367950,21367951,21367952,21367953,21367954,21367955,21367956,21367957,21367958,21367959,21367960,21367961,21367962,21367963,21367964,21367965,21367966,21367967,21367968,21367969,21367970,21367971,21367972,21367973,21367974,21367975,21367976,21367977,21367978,21367979,21367980,21367981,21367982,21367983,21367984,21367985,21367986,21367987,21367988,21367989,21367990,21367991,21367992,21367993,21367994,21367995,21367996,21367997,21367998,21367999,21368000,21368016,21368017,21368018,21368019,21368020,21368021,21368022,21368023,21368024,21368025,21368026,21368027,21368028,21368029,21368030,21368031],"Red Nether Bricks":[21368920],"Red Sand":[21371243],"Red Sandstone":[21373682],"Red Sandstone Slab":[21375308,21375309,21375310],"Red Sandstone Stairs":[21377256,21377257,21377258,21377259,21377260,21377261,21377262,21377263],"Red Sandstone Wall":[21380352,21380353,21380354,21380355,21380356,21380357,21380358,21380359,21380360,21380361,21380362,21380363,21380364,21380365,21380366,21380367,21380383,21380416,21380417,21380418,21380419,21380420,21380421,21380422,21380423,21380424,21380425,21380426,21380427,21380428,21380429,21380430,21380431,21380432,21380433,21380434,21380435,21380436,21380437,21380438,21380439,21380440,21380441,21380442,21380443,21380444,21380445,21380446,21380447,21380448,21380449,21380450,21380451,21380452,21380453,21380454,21380455,21380456,21380457,21380458,21380459,21380460,21380461,21380462,21380463,21380464,21380465,21380466,21380467,21380468,21380469,21380470,21380471,21380472,21380473,21380474,21380475,21380476,21380477,21380478,21380479,21380480,21380481,21380482,21380483,21380484,21380485,21380486,21380487,21380488,21380489,21380490,21380491,21380492,21380493,21380494,21380495,21380511,21380544,21380545,21380546,21380547,21380548,21380549,21380550,21380551,21380552,21380553,21380554,21380555,21380556,21380557,21380558,21380559,21380560,21380561,21380562,21380563,21380564,21380565,21380566,21380567,21380568,21380569,21380570,21380571,21380572,21380573,21380574,21380575,21380576,21380577,21380578,21380579,21380580,21380581,21380582,21380583,21380584,21380585,21380586,21380587,21380588,21380589,21380590,21380591,21380592,21380593,21380594,21380595,21380596,21380597,21380598,21380599,21380600,21380601,21380602,21380603,21380604,21380605,21380606,21380607],"Red Torch":[21381490,21381491,21381492,21381493,21381495],"Red Tulip":[21384139],"Redstone":[21397872,21397873,21397874,21397875,21397876,21397877,21397878,21397879,21397880,21397881,21397882,21397883,21397884,21397885,21397886,21397887],"Redstone Block":[21385654],"Redstone Comparator":[21388928,21388929,21388930,21388931,21388932,21388933,21388934,21388935,21388936,21388937,21388938,21388939,21388940,21388941,21388942,21388943],"Redstone Lamp":[21390644,21390645],"Redstone Ore":[21392016,21392017],"Redstone Repeater":[21394976,21394977,21394978,21394979,21394980,21394981,21394982,21394983,21394984,21394985,21394986,21394987,21394988,21394989,21394990,21394991,21394992,21394993,21394994,21394995,21394996,21394997,21394998,21394999,21395000,21395001,21395002,21395003,21395004,21395005,21395006,21395007],"Redstone Torch":[21396497,21396498,21396499,21396500,21396501,21396505,21396506,21396507,21396508,21396509],"Reinforced Deepslate":[21889612],"Rhenium":[20930190],"Rhodium":[20931608],"Roentgenium":[20934217],"Rose Bush":[21402408,21402409],"Rubidium":[20936670],"Ruthenium":[20937111],"Rutherfordium":[20939938],"Samarium":[20942830],"Sand":[21405599],"Sandstone":[21406854],"Sandstone Slab":[21408357,21408358,21408359],"Sandstone Stairs":[21410360,21410361,21410362,21410363,21410364,21410365,21410366,21410367],"Sandstone Wall":[21413632,21413633,21413634,21413635,21413636,21413637,21413638,21413639,21413640,21413641,21413642,21413643,21413644,21413645,21413646,21413647,21413648,21413649,21413650,21413651,21413652,21413653,21413654,21413655,21413656,21413657,21413658,21413659,21413660,21413661,21413662,21413663,21413664,21413665,21413666,21413667,21413668,21413669,21413670,21413671,21413672,21413673,21413674,21413675,21413676,21413677,21413678,21413679,21413680,21413681,21413682,21413683,21413684,21413685,21413686,21413687,21413688,21413689,21413690,21413691,21413692,21413693,21413694,21413695,21413696,21413697,21413698,21413699,21413700,21413701,21413702,21413703,21413704,21413705,21413706,21413707,21413708,21413709,21413710,21413711,21413719,21413760,21413761,21413762,21413763,21413764,21413765,21413766,21413767,21413768,21413769,21413770,21413771,21413772,21413773,21413774,21413775,21413776,21413777,21413778,21413779,21413780,21413781,21413782,21413783,21413784,21413785,21413786,21413787,21413788,21413789,21413790,21413791,21413792,21413793,21413794,21413795,21413796,21413797,21413798,21413799,21413800,21413801,21413802,21413803,21413804,21413805,21413806,21413807,21413808,21413809,21413810,21413811,21413812,21413813,21413814,21413815,21413816,21413817,21413818,21413819,21413820,21413821,21413822,21413823,21413824,21413825,21413826,21413827,21413828,21413829,21413830,21413831,21413832,21413833,21413834,21413835,21413836,21413837,21413838,21413839,21413847],"Scandium":[20944835],"Sculk":[21880279],"Sea Lantern":[21415151],"Sea Pickle":[21417344,21417345,21417346,21417347,21417348,21417349,21417350,21417351],"Seaborgium":[20946478],"Selenium":[20948963],"Shroomlight":[21696604],"Shulker Box":[21418259],"Silicon":[20949447],"Silver":[20952835],"Slime Block":[21421890],"Small Dripleaf":[21927576,21927577,21927578,21927579,21927580,21927581,21927582,21927583],"Smithing Table":[21847863],"Smoker":[21423456,21423457,21423458,21423459,21423460,21423461,21423462,21423463],"Smooth Basalt":[21595261],"Smooth Quartz Block":[21425097],"Smooth Quartz Slab":[21428056,21428057,21428058],"Smooth Quartz Stairs":[21429504,21429505,21429506,21429507,21429508,21429509,21429510,21429511],"Smooth Red Sandstone":[21431324],"Smooth Red Sandstone Slab":[21432877,21432878,21432879],"Smooth Red Sandstone Stairs":[21436184,21436185,21436186,21436187,21436188,21436189,21436190,21436191],"Smooth Sandstone":[21438242],"Smooth Sandstone Slab":[21439385,21439386,21439387],"Smooth Sandstone Stairs":[21440752,21440753,21440754,21440755,21440756,21440757,21440758,21440759],"Smooth Stone":[21444566],"Smooth Stone Slab":[21446216,21446217,21446219],"Snow Block":[21448652],"Snow Layer":[21449736,21449737,21449738,21449739,21449740,21449741,21449742,21449743],"Sodium":[20953522],"Soul Fire":[21696136],"Soul Lantern":[21692144,21692145],"Soul Sand":[21451142],"Soul Soil":[21693270],"Soul Torch":[21689448,21689449,21689452,21689454,21689455],"Sponge":[21454292,21454293],"Spore Blossom":[21852156],"Spruce Button":[21456688,21456689,21456690,21456691,21456692,21456693,21456696,21456697,21456698,21456699,21456700,21456701],"Spruce Door":[21458400,21458401,21458402,21458403,21458404,21458405,21458406,21458407,21458408,21458409,21458410,21458411,21458412,21458413,21458414,21458415,21458416,21458417,21458418,21458419,21458420,21458421,21458422,21458423,21458424,21458425,21458426,21458427,21458428,21458429,21458430,21458431],"Spruce Fence":[21459375],"Spruce Fence Gate":[21462512,21462513,21462514,21462515,21462516,21462517,21462518,21462519,21462520,21462521,21462522,21462523,21462524,21462525,21462526,21462527],"Spruce Leaves":[21463656,21463657,21463658,21463659],"Spruce Log":[21465720,21465721,21465724,21465725,21465726,21465727],"Spruce Planks":[21468562],"Spruce Pressure Plate":[21469450,21469451],"Spruce Sapling":[21472860,21472861],"Spruce Sign":[21473424,21473425,21473426,21473427,21473428,21473429,21473430,21473431,21473432,21473433,21473434,21473435,21473436,21473437,21473438,21473439],"Spruce Slab":[21475816,21475817,21475818],"Spruce Stairs":[21477456,21477457,21477458,21477459,21477460,21477461,21477462,21477463],"Spruce Trapdoor":[21481008,21481009,21481010,21481011,21481012,21481013,21481014,21481015,21481016,21481017,21481018,21481019,21481020,21481021,21481022,21481023],"Spruce Wall Sign":[21483504,21483505,21483506,21483507],"Spruce Wood":[21484912,21484913,21484914,21484915,21484918,21484919],"Stained Clay":[21486144,21486145,21486146,21486147,21486148,21486149,21486150,21486151,21486152,21486153,21486154,21486155,21486156,21486157,21486158,21486159],"Stained Glass":[21489584,21489585,21489586,21489587,21489588,21489589,21489590,21489591,21489592,21489593,21489594,21489595,21489596,21489597,21489598,21489599],"Stained Glass Pane":[21489792,21489793,21489794,21489795,21489796,21489797,21489798,21489799,21489800,21489801,21489802,21489803,21489804,21489805,21489806,21489807],"Stained Hardened Glass":[21491728,21491729,21491730,21491731,21491732,21491733,21491734,21491735,21491736,21491737,21491738,21491739,21491740,21491741,21491742,21491743],"Stained Hardened Glass Pane":[21495136,21495137,21495138,21495139,21495140,21495141,21495142,21495143,21495144,21495145,21495146,21495147,21495148,21495149,21495150,21495151],"Stone":[21496052],"Stone Brick Slab":[21498972,21498973,21498974],"Stone Brick Stairs":[21500248,21500249,21500250,21500251,21500252,21500253,21500254,21500255],"Stone Brick Wall":[21503744,21503745,21503746,21503747,21503748,21503749,21503750,21503751,21503752,21503753,21503754,21503755,21503756,21503757,21503758,21503759,21503773,21503808,21503809,21503810,21503811,21503812,21503813,21503814,21503815,21503816,21503817,21503818,21503819,21503820,21503821,21503822,21503823,21503824,21503825,21503826,21503827,21503828,21503829,21503830,21503831,21503832,21503833,21503834,21503835,21503836,21503837,21503838,21503839,21503840,21503841,21503842,21503843,21503844,21503845,21503846,21503847,21503848,21503849,21503850,21503851,21503852,21503853,21503854,21503855,21503856,21503857,21503858,21503859,21503860,21503861,21503862,21503863,21503864,21503865,21503866,21503867,21503868,21503869,21503870,21503871,21503872,21503873,21503874,21503875,21503876,21503877,21503878,21503879,21503880,21503881,21503882,21503883,21503884,21503885,21503886,21503887,21503901,21503936,21503937,21503938,21503939,21503940,21503941,21503942,21503943,21503944,21503945,21503946,21503947,21503948,21503949,21503950,21503951,21503952,21503953,21503954,21503955,21503956,21503957,21503958,21503959,21503960,21503961,21503962,21503963,21503964,21503965,21503966,21503967,21503968,21503969,21503970,21503971,21503972,21503973,21503974,21503975,21503976,21503977,21503978,21503979,21503980,21503981,21503982,21503983,21503984,21503985,21503986,21503987,21503988,21503989,21503990,21503991,21503992,21503993,21503994,21503995,21503996,21503997,21503998,21503999],"Stone Bricks":[21505414],"Stone Button":[21507712,21507713,21507714,21507715,21507718,21507719,21507720,21507721,21507722,21507723,21507726,21507727],"Stone Pressure Plate":[21508356,21508357],"Stone Slab":[21512017,21512018,21512019],"Stone Stairs":[21512192,21512193,21512194,21512195,21512196,21512197,21512198,21512199],"Stonecutter":[21514984,21514985,21514986,21514987],"Strontium":[20955164],"Sugarcane":[21542656,21542657,21542658,21542659,21542660,21542661,21542662,21542663,21542664,21542665,21542666,21542667,21542668,21542669,21542670,21542671],"Sulfur":[20958068],"Sunflower":[21544506,21544507],"Sweet Berry Bush":[21545764,21545765,21545766,21545767],"TNT":[21550004,21550005,21550006,21550007],"Tall Grass":[21547986],"Tantalum":[20959931],"Technetium":[20962279],"Tellurium":[20964192],"Tennessine":[20965501],"Terbium":[20968631],"Thallium":[20971328],"Thorium":[20973507],"Thulium":[20974346],"Tin":[20976139],"Tinted Glass":[21779734],"Titanium":[20978911],"Torch":[21551770,21551771,21551772,21551773,21551775],"Torchflower":[21940847],"Torchflower Crop":[21943796,21943797],"Trapped Chest":[21553240,21553241,21553242,21553243],"Tripwire":[21556976,21556977,21556978,21556979,21556980,21556981,21556982,21556983,21556984,21556985,21556986,21556987,21556988,21556989,21556990,21556991],"Tripwire Hook":[21559008,21559009,21559010,21559011,21559012,21559013,21559014,21559015,21559016,21559017,21559018,21559019,21559020,21559021,21559022,21559023],"Tuff":[21688162],"Tungsten":[20981723],"Twisting Vines":[21873664,21873665,21873666,21873667,21873668,21873669,21873670,21873671,21873672,21873673,21873674,21873675,21873676,21873677,21873678,21873679,21873680,21873681,21873688,21873689,21873690,21873691,21873692,21873693,21873694,21873695],"Underwater Torch":[21560248,21560249,21560252,21560254,21560255],"Uranium":[20982778],"Vanadium":[20984123],"Vines":[21562368,21562369,21562370,21562371,21562372,21562373,21562374,21562375,21562376,21562377,21562378,21562379,21562380,21562381,21562382,21562383],"Wall Banner":[21564672,21564673,21564674,21564675,21564676,21564677,21564678,21564679,21564680,21564681,21564682,21564683,21564684,21564685,21564686,21564687,21564688,21564689,21564690,21564691,21564692,21564693,21564694,21564695,21564696,21564697,21564698,21564699,21564700,21564701,21564702,21564703,21564704,21564705,21564706,21564707,21564708,21564709,21564710,21564711,21564712,21564713,21564714,21564715,21564716,21564717,21564718,21564719,21564720,21564721,21564722,21564723,21564724,21564725,21564726,21564727,21564728,21564729,21564730,21564731,21564732,21564733,21564734,21564735],"Wall Coral Fan":[21567296,21567300,21567301,21567302,21567303,21567304,21567308,21567309,21567310,21567311,21567312,21567316,21567317,21567318,21567319,21567320,21567324,21567325,21567326,21567327,21567328,21567332,21567333,21567334,21567335,21567336,21567340,21567341,21567342,21567343,21567344,21567348,21567349,21567350,21567351,21567352,21567356,21567357,21567358,21567359],"Warped Button":[21741552,21741553,21741556,21741557,21741558,21741559,21741560,21741561,21741564,21741565,21741566,21741567],"Warped Door":[21752672,21752673,21752674,21752675,21752676,21752677,21752678,21752679,21752680,21752681,21752682,21752683,21752684,21752685,21752686,21752687,21752688,21752689,21752690,21752691,21752692,21752693,21752694,21752695,21752696,21752697,21752698,21752699,21752700,21752701,21752702,21752703],"Warped Fence":[21709978],"Warped Fence Gate":[21759616,21759617,21759618,21759619,21759620,21759621,21759622,21759623,21759624,21759625,21759626,21759627,21759628,21759629,21759630,21759631],"Warped Hyphae":[21727976,21727977,21727980,21727981,21727982,21727983],"Warped Planks":[21703045],"Warped Pressure Plate":[21747528,21747529],"Warped Roots":[21938097],"Warped Sign":[21771312,21771313,21771314,21771315,21771316,21771317,21771318,21771319,21771320,21771321,21771322,21771323,21771324,21771325,21771326,21771327],"Warped Slab":[21715036,21715038,21715039],"Warped Stairs":[21765928,21765929,21765930,21765931,21765932,21765933,21765934,21765935],"Warped Stem":[21721496,21721497,21721500,21721501,21721502,21721503],"Warped Trapdoor":[21734544,21734545,21734546,21734547,21734548,21734549,21734550,21734551,21734552,21734553,21734554,21734555,21734556,21734557,21734558,21734559],"Warped Wall Sign":[21777200,21777201,21777202,21777203],"Warped Wart Block":[21815813],"Water":[21568608,21568609,21568610,21568611,21568612,21568613,21568614,21568615,21568616,21568617,21568618,21568619,21568620,21568621,21568622,21568623,21568624,21568625,21568626,21568627,21568628,21568629,21568630,21568631,21568632,21568633,21568634,21568635,21568636,21568637,21568638,21568639],"Water Cauldron":[21854480,21854481,21854482,21854483,21854486,21854487],"Weeping Vines":[21875072,21875073,21875074,21875075,21875076,21875077,21875078,21875079,21875080,21875081,21875082,21875083,21875084,21875085,21875086,21875087,21875088,21875089,21875090,21875091,21875092,21875093,21875094,21875095,21875102,21875103],"Weighted Pressure Plate Heavy":[21570544,21570545,21570546,21570547,21570548,21570549,21570550,21570551,21570552,21570553,21570554,21570555,21570556,21570557,21570558,21570559],"Weighted Pressure Plate Light":[21572160,21572161,21572162,21572163,21572164,21572165,21572166,21572167,21572168,21572169,21572170,21572171,21572172,21572173,21572174,21572175],"Wheat Block":[21575552,21575553,21575554,21575555,21575556,21575557,21575558,21575559],"White Tulip":[21578492],"Wither Rose":[21841807],"Wool":[21580784,21580785,21580786,21580787,21580788,21580789,21580790,21580791,21580792,21580793,21580794,21580795,21580796,21580797,21580798,21580799],"Xenon":[20987135],"Ytterbium":[20989425],"Yttrium":[20991002],"Zinc":[20995928],"Zirconium":[20996890],"ate!upd":[21097998],"reserved6":[21399796],"update!":[21096340]},"stateDataBits":11} \ No newline at end of file +{ + "ACACIA_BUTTON": 12, + "ACACIA_DOOR": 32, + "ACACIA_FENCE": 1, + "ACACIA_FENCE_GATE": 16, + "ACACIA_LEAVES": 4, + "ACACIA_LOG": 6, + "ACACIA_PLANKS": 1, + "ACACIA_PRESSURE_PLATE": 2, + "ACACIA_SAPLING": 2, + "ACACIA_SIGN": 16, + "ACACIA_SLAB": 3, + "ACACIA_STAIRS": 8, + "ACACIA_TRAPDOOR": 16, + "ACACIA_WALL_SIGN": 4, + "ACACIA_WOOD": 6, + "ACTIVATOR_RAIL": 12, + "AIR": 1, + "ALLIUM": 1, + "ALL_SIDED_MUSHROOM_STEM": 1, + "AMETHYST": 1, + "AMETHYST_CLUSTER": 24, + "ANCIENT_DEBRIS": 1, + "ANDESITE": 1, + "ANDESITE_SLAB": 3, + "ANDESITE_STAIRS": 8, + "ANDESITE_WALL": 162, + "ANVIL": 12, + "AZALEA_LEAVES": 4, + "AZURE_BLUET": 1, + "BAMBOO": 12, + "BAMBOO_SAPLING": 2, + "BANNER": 256, + "BARREL": 12, + "BARRIER": 1, + "BASALT": 3, + "BEACON": 1, + "BED": 256, + "BEDROCK": 2, + "BEETROOTS": 8, + "BELL": 16, + "BIG_DRIPLEAF_HEAD": 16, + "BIG_DRIPLEAF_STEM": 4, + "BIRCH_BUTTON": 12, + "BIRCH_DOOR": 32, + "BIRCH_FENCE": 1, + "BIRCH_FENCE_GATE": 16, + "BIRCH_LEAVES": 4, + "BIRCH_LOG": 6, + "BIRCH_PLANKS": 1, + "BIRCH_PRESSURE_PLATE": 2, + "BIRCH_SAPLING": 2, + "BIRCH_SIGN": 16, + "BIRCH_SLAB": 3, + "BIRCH_STAIRS": 8, + "BIRCH_TRAPDOOR": 16, + "BIRCH_WALL_SIGN": 4, + "BIRCH_WOOD": 6, + "BLACKSTONE": 1, + "BLACKSTONE_SLAB": 3, + "BLACKSTONE_STAIRS": 8, + "BLACKSTONE_WALL": 162, + "BLAST_FURNACE": 8, + "BLUE_ICE": 1, + "BLUE_ORCHID": 1, + "BLUE_TORCH": 5, + "BONE_BLOCK": 3, + "BOOKSHELF": 1, + "BREWING_STAND": 8, + "BRICKS": 1, + "BRICK_SLAB": 3, + "BRICK_STAIRS": 8, + "BRICK_WALL": 162, + "BROWN_MUSHROOM": 1, + "BROWN_MUSHROOM_BLOCK": 11, + "BUDDING_AMETHYST": 1, + "CACTUS": 16, + "CAKE": 7, + "CAKE_WITH_CANDLE": 2, + "CAKE_WITH_DYED_CANDLE": 32, + "CALCITE": 1, + "CAMPFIRE": 8, + "CANDLE": 8, + "CARPET": 16, + "CARROTS": 8, + "CARTOGRAPHY_TABLE": 1, + "CARVED_PUMPKIN": 4, + "CAULDRON": 1, + "CAVE_VINES": 104, + "CHAIN": 3, + "CHEMICAL_HEAT": 1, + "CHERRY_BUTTON": 12, + "CHERRY_DOOR": 32, + "CHERRY_FENCE": 1, + "CHERRY_FENCE_GATE": 16, + "CHERRY_LEAVES": 4, + "CHERRY_LOG": 6, + "CHERRY_PLANKS": 1, + "CHERRY_PRESSURE_PLATE": 2, + "CHERRY_SIGN": 16, + "CHERRY_SLAB": 3, + "CHERRY_STAIRS": 8, + "CHERRY_TRAPDOOR": 16, + "CHERRY_WALL_SIGN": 4, + "CHERRY_WOOD": 6, + "CHEST": 4, + "CHISELED_BOOKSHELF": 256, + "CHISELED_DEEPSLATE": 1, + "CHISELED_NETHER_BRICKS": 1, + "CHISELED_POLISHED_BLACKSTONE": 1, + "CHISELED_QUARTZ": 3, + "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, + "COAL": 1, + "COAL_ORE": 1, + "COBBLED_DEEPSLATE": 1, + "COBBLED_DEEPSLATE_SLAB": 3, + "COBBLED_DEEPSLATE_STAIRS": 8, + "COBBLED_DEEPSLATE_WALL": 162, + "COBBLESTONE": 1, + "COBBLESTONE_SLAB": 3, + "COBBLESTONE_STAIRS": 8, + "COBBLESTONE_WALL": 162, + "COBWEB": 1, + "COCOA_POD": 12, + "COMPOUND_CREATOR": 4, + "CONCRETE": 16, + "CONCRETE_POWDER": 16, + "COPPER": 8, + "COPPER_ORE": 1, + "CORAL": 10, + "CORAL_BLOCK": 10, + "CORAL_FAN": 20, + "CORNFLOWER": 1, + "CRACKED_DEEPSLATE_BRICKS": 1, + "CRACKED_DEEPSLATE_TILES": 1, + "CRACKED_NETHER_BRICKS": 1, + "CRACKED_POLISHED_BLACKSTONE_BRICKS": 1, + "CRACKED_STONE_BRICKS": 1, + "CRAFTING_TABLE": 1, + "CRIMSON_BUTTON": 12, + "CRIMSON_DOOR": 32, + "CRIMSON_FENCE": 1, + "CRIMSON_FENCE_GATE": 16, + "CRIMSON_HYPHAE": 6, + "CRIMSON_PLANKS": 1, + "CRIMSON_PRESSURE_PLATE": 2, + "CRIMSON_ROOTS": 1, + "CRIMSON_SIGN": 16, + "CRIMSON_SLAB": 3, + "CRIMSON_STAIRS": 8, + "CRIMSON_STEM": 6, + "CRIMSON_TRAPDOOR": 16, + "CRIMSON_WALL_SIGN": 4, + "CRYING_OBSIDIAN": 1, + "CUT_COPPER": 8, + "CUT_COPPER_SLAB": 24, + "CUT_COPPER_STAIRS": 64, + "CUT_RED_SANDSTONE": 1, + "CUT_RED_SANDSTONE_SLAB": 3, + "CUT_SANDSTONE": 1, + "CUT_SANDSTONE_SLAB": 3, + "DANDELION": 1, + "DARK_OAK_BUTTON": 12, + "DARK_OAK_DOOR": 32, + "DARK_OAK_FENCE": 1, + "DARK_OAK_FENCE_GATE": 16, + "DARK_OAK_LEAVES": 4, + "DARK_OAK_LOG": 6, + "DARK_OAK_PLANKS": 1, + "DARK_OAK_PRESSURE_PLATE": 2, + "DARK_OAK_SAPLING": 2, + "DARK_OAK_SIGN": 16, + "DARK_OAK_SLAB": 3, + "DARK_OAK_STAIRS": 8, + "DARK_OAK_TRAPDOOR": 16, + "DARK_OAK_WALL_SIGN": 4, + "DARK_OAK_WOOD": 6, + "DARK_PRISMARINE": 1, + "DARK_PRISMARINE_SLAB": 3, + "DARK_PRISMARINE_STAIRS": 8, + "DAYLIGHT_SENSOR": 32, + "DEAD_BUSH": 1, + "DEEPSLATE": 3, + "DEEPSLATE_BRICKS": 1, + "DEEPSLATE_BRICK_SLAB": 3, + "DEEPSLATE_BRICK_STAIRS": 8, + "DEEPSLATE_BRICK_WALL": 162, + "DEEPSLATE_COAL_ORE": 1, + "DEEPSLATE_COPPER_ORE": 1, + "DEEPSLATE_DIAMOND_ORE": 1, + "DEEPSLATE_EMERALD_ORE": 1, + "DEEPSLATE_GOLD_ORE": 1, + "DEEPSLATE_IRON_ORE": 1, + "DEEPSLATE_LAPIS_LAZULI_ORE": 1, + "DEEPSLATE_REDSTONE_ORE": 2, + "DEEPSLATE_TILES": 1, + "DEEPSLATE_TILE_SLAB": 3, + "DEEPSLATE_TILE_STAIRS": 8, + "DEEPSLATE_TILE_WALL": 162, + "DETECTOR_RAIL": 12, + "DIAMOND": 1, + "DIAMOND_ORE": 1, + "DIORITE": 1, + "DIORITE_SLAB": 3, + "DIORITE_STAIRS": 8, + "DIORITE_WALL": 162, + "DIRT": 3, + "DOUBLE_PITCHER_CROP": 4, + "DOUBLE_TALLGRASS": 2, + "DRAGON_EGG": 1, + "DRIED_KELP": 1, + "DYED_CANDLE": 128, + "DYED_SHULKER_BOX": 16, + "ELEMENT_ACTINIUM": 1, + "ELEMENT_ALUMINUM": 1, + "ELEMENT_AMERICIUM": 1, + "ELEMENT_ANTIMONY": 1, + "ELEMENT_ARGON": 1, + "ELEMENT_ARSENIC": 1, + "ELEMENT_ASTATINE": 1, + "ELEMENT_BARIUM": 1, + "ELEMENT_BERKELIUM": 1, + "ELEMENT_BERYLLIUM": 1, + "ELEMENT_BISMUTH": 1, + "ELEMENT_BOHRIUM": 1, + "ELEMENT_BORON": 1, + "ELEMENT_BROMINE": 1, + "ELEMENT_CADMIUM": 1, + "ELEMENT_CALCIUM": 1, + "ELEMENT_CALIFORNIUM": 1, + "ELEMENT_CARBON": 1, + "ELEMENT_CERIUM": 1, + "ELEMENT_CESIUM": 1, + "ELEMENT_CHLORINE": 1, + "ELEMENT_CHROMIUM": 1, + "ELEMENT_COBALT": 1, + "ELEMENT_CONSTRUCTOR": 4, + "ELEMENT_COPERNICIUM": 1, + "ELEMENT_COPPER": 1, + "ELEMENT_CURIUM": 1, + "ELEMENT_DARMSTADTIUM": 1, + "ELEMENT_DUBNIUM": 1, + "ELEMENT_DYSPROSIUM": 1, + "ELEMENT_EINSTEINIUM": 1, + "ELEMENT_ERBIUM": 1, + "ELEMENT_EUROPIUM": 1, + "ELEMENT_FERMIUM": 1, + "ELEMENT_FLEROVIUM": 1, + "ELEMENT_FLUORINE": 1, + "ELEMENT_FRANCIUM": 1, + "ELEMENT_GADOLINIUM": 1, + "ELEMENT_GALLIUM": 1, + "ELEMENT_GERMANIUM": 1, + "ELEMENT_GOLD": 1, + "ELEMENT_HAFNIUM": 1, + "ELEMENT_HASSIUM": 1, + "ELEMENT_HELIUM": 1, + "ELEMENT_HOLMIUM": 1, + "ELEMENT_HYDROGEN": 1, + "ELEMENT_INDIUM": 1, + "ELEMENT_IODINE": 1, + "ELEMENT_IRIDIUM": 1, + "ELEMENT_IRON": 1, + "ELEMENT_KRYPTON": 1, + "ELEMENT_LANTHANUM": 1, + "ELEMENT_LAWRENCIUM": 1, + "ELEMENT_LEAD": 1, + "ELEMENT_LITHIUM": 1, + "ELEMENT_LIVERMORIUM": 1, + "ELEMENT_LUTETIUM": 1, + "ELEMENT_MAGNESIUM": 1, + "ELEMENT_MANGANESE": 1, + "ELEMENT_MEITNERIUM": 1, + "ELEMENT_MENDELEVIUM": 1, + "ELEMENT_MERCURY": 1, + "ELEMENT_MOLYBDENUM": 1, + "ELEMENT_MOSCOVIUM": 1, + "ELEMENT_NEODYMIUM": 1, + "ELEMENT_NEON": 1, + "ELEMENT_NEPTUNIUM": 1, + "ELEMENT_NICKEL": 1, + "ELEMENT_NIHONIUM": 1, + "ELEMENT_NIOBIUM": 1, + "ELEMENT_NITROGEN": 1, + "ELEMENT_NOBELIUM": 1, + "ELEMENT_OGANESSON": 1, + "ELEMENT_OSMIUM": 1, + "ELEMENT_OXYGEN": 1, + "ELEMENT_PALLADIUM": 1, + "ELEMENT_PHOSPHORUS": 1, + "ELEMENT_PLATINUM": 1, + "ELEMENT_PLUTONIUM": 1, + "ELEMENT_POLONIUM": 1, + "ELEMENT_POTASSIUM": 1, + "ELEMENT_PRASEODYMIUM": 1, + "ELEMENT_PROMETHIUM": 1, + "ELEMENT_PROTACTINIUM": 1, + "ELEMENT_RADIUM": 1, + "ELEMENT_RADON": 1, + "ELEMENT_RHENIUM": 1, + "ELEMENT_RHODIUM": 1, + "ELEMENT_ROENTGENIUM": 1, + "ELEMENT_RUBIDIUM": 1, + "ELEMENT_RUTHENIUM": 1, + "ELEMENT_RUTHERFORDIUM": 1, + "ELEMENT_SAMARIUM": 1, + "ELEMENT_SCANDIUM": 1, + "ELEMENT_SEABORGIUM": 1, + "ELEMENT_SELENIUM": 1, + "ELEMENT_SILICON": 1, + "ELEMENT_SILVER": 1, + "ELEMENT_SODIUM": 1, + "ELEMENT_STRONTIUM": 1, + "ELEMENT_SULFUR": 1, + "ELEMENT_TANTALUM": 1, + "ELEMENT_TECHNETIUM": 1, + "ELEMENT_TELLURIUM": 1, + "ELEMENT_TENNESSINE": 1, + "ELEMENT_TERBIUM": 1, + "ELEMENT_THALLIUM": 1, + "ELEMENT_THORIUM": 1, + "ELEMENT_THULIUM": 1, + "ELEMENT_TIN": 1, + "ELEMENT_TITANIUM": 1, + "ELEMENT_TUNGSTEN": 1, + "ELEMENT_URANIUM": 1, + "ELEMENT_VANADIUM": 1, + "ELEMENT_XENON": 1, + "ELEMENT_YTTERBIUM": 1, + "ELEMENT_YTTRIUM": 1, + "ELEMENT_ZERO": 1, + "ELEMENT_ZINC": 1, + "ELEMENT_ZIRCONIUM": 1, + "EMERALD": 1, + "EMERALD_ORE": 1, + "ENCHANTING_TABLE": 1, + "ENDER_CHEST": 4, + "END_PORTAL_FRAME": 8, + "END_ROD": 6, + "END_STONE": 1, + "END_STONE_BRICKS": 1, + "END_STONE_BRICK_SLAB": 3, + "END_STONE_BRICK_STAIRS": 8, + "END_STONE_BRICK_WALL": 162, + "FAKE_WOODEN_SLAB": 3, + "FARMLAND": 1304, + "FERN": 1, + "FIRE": 16, + "FLETCHING_TABLE": 1, + "FLOWERING_AZALEA_LEAVES": 4, + "FLOWER_POT": 1, + "FROGLIGHT": 9, + "FROSTED_ICE": 4, + "FURNACE": 8, + "GILDED_BLACKSTONE": 1, + "GLASS": 1, + "GLASS_PANE": 1, + "GLAZED_TERRACOTTA": 64, + "GLOWING_ITEM_FRAME": 12, + "GLOWING_OBSIDIAN": 1, + "GLOWSTONE": 1, + "GLOW_LICHEN": 64, + "GOLD": 1, + "GOLD_ORE": 1, + "GRANITE": 1, + "GRANITE_SLAB": 3, + "GRANITE_STAIRS": 8, + "GRANITE_WALL": 162, + "GRASS": 1, + "GRASS_PATH": 1, + "GRAVEL": 1, + "GREEN_TORCH": 5, + "HANGING_ROOTS": 1, + "HARDENED_CLAY": 1, + "HARDENED_GLASS": 1, + "HARDENED_GLASS_PANE": 1, + "HAY_BALE": 3, + "HONEYCOMB": 1, + "HOPPER": 10, + "ICE": 1, + "INFESTED_CHISELED_STONE_BRICK": 1, + "INFESTED_COBBLESTONE": 1, + "INFESTED_CRACKED_STONE_BRICK": 1, + "INFESTED_MOSSY_STONE_BRICK": 1, + "INFESTED_STONE": 1, + "INFESTED_STONE_BRICK": 1, + "INFO_UPDATE": 1, + "INFO_UPDATE2": 1, + "INVISIBLE_BEDROCK": 1, + "IRON": 1, + "IRON_BARS": 1, + "IRON_DOOR": 32, + "IRON_ORE": 1, + "IRON_TRAPDOOR": 16, + "ITEM_FRAME": 12, + "JUKEBOX": 1, + "JUNGLE_BUTTON": 12, + "JUNGLE_DOOR": 32, + "JUNGLE_FENCE": 1, + "JUNGLE_FENCE_GATE": 16, + "JUNGLE_LEAVES": 4, + "JUNGLE_LOG": 6, + "JUNGLE_PLANKS": 1, + "JUNGLE_PRESSURE_PLATE": 2, + "JUNGLE_SAPLING": 2, + "JUNGLE_SIGN": 16, + "JUNGLE_SLAB": 3, + "JUNGLE_STAIRS": 8, + "JUNGLE_TRAPDOOR": 16, + "JUNGLE_WALL_SIGN": 4, + "JUNGLE_WOOD": 6, + "LAB_TABLE": 4, + "LADDER": 4, + "LANTERN": 2, + "LAPIS_LAZULI": 1, + "LAPIS_LAZULI_ORE": 1, + "LARGE_FERN": 2, + "LAVA": 32, + "LAVA_CAULDRON": 6, + "LECTERN": 8, + "LEGACY_STONECUTTER": 1, + "LEVER": 16, + "LIGHT": 16, + "LIGHTNING_ROD": 6, + "LILAC": 2, + "LILY_OF_THE_VALLEY": 1, + "LILY_PAD": 1, + "LIT_PUMPKIN": 4, + "LOOM": 4, + "MAGMA": 1, + "MANGROVE_BUTTON": 12, + "MANGROVE_DOOR": 32, + "MANGROVE_FENCE": 1, + "MANGROVE_FENCE_GATE": 16, + "MANGROVE_LEAVES": 4, + "MANGROVE_LOG": 6, + "MANGROVE_PLANKS": 1, + "MANGROVE_PRESSURE_PLATE": 2, + "MANGROVE_ROOTS": 1, + "MANGROVE_SIGN": 16, + "MANGROVE_SLAB": 3, + "MANGROVE_STAIRS": 8, + "MANGROVE_TRAPDOOR": 16, + "MANGROVE_WALL_SIGN": 4, + "MANGROVE_WOOD": 6, + "MATERIAL_REDUCER": 4, + "MELON": 1, + "MELON_STEM": 40, + "MOB_HEAD": 35, + "MONSTER_SPAWNER": 1, + "MOSSY_COBBLESTONE": 1, + "MOSSY_COBBLESTONE_SLAB": 3, + "MOSSY_COBBLESTONE_STAIRS": 8, + "MOSSY_COBBLESTONE_WALL": 162, + "MOSSY_STONE_BRICKS": 1, + "MOSSY_STONE_BRICK_SLAB": 3, + "MOSSY_STONE_BRICK_STAIRS": 8, + "MOSSY_STONE_BRICK_WALL": 162, + "MUD": 1, + "MUDDY_MANGROVE_ROOTS": 3, + "MUD_BRICKS": 1, + "MUD_BRICK_SLAB": 3, + "MUD_BRICK_STAIRS": 8, + "MUD_BRICK_WALL": 162, + "MUSHROOM_STEM": 1, + "MYCELIUM": 1, + "NETHERITE": 1, + "NETHERRACK": 1, + "NETHER_BRICKS": 1, + "NETHER_BRICK_FENCE": 1, + "NETHER_BRICK_SLAB": 3, + "NETHER_BRICK_STAIRS": 8, + "NETHER_BRICK_WALL": 162, + "NETHER_GOLD_ORE": 1, + "NETHER_PORTAL": 2, + "NETHER_QUARTZ_ORE": 1, + "NETHER_REACTOR_CORE": 1, + "NETHER_WART": 4, + "NETHER_WART_BLOCK": 1, + "NOTE_BLOCK": 1, + "OAK_BUTTON": 12, + "OAK_DOOR": 32, + "OAK_FENCE": 1, + "OAK_FENCE_GATE": 16, + "OAK_LEAVES": 4, + "OAK_LOG": 6, + "OAK_PLANKS": 1, + "OAK_PRESSURE_PLATE": 2, + "OAK_SAPLING": 2, + "OAK_SIGN": 16, + "OAK_SLAB": 3, + "OAK_STAIRS": 8, + "OAK_TRAPDOOR": 16, + "OAK_WALL_SIGN": 4, + "OAK_WOOD": 6, + "OBSIDIAN": 1, + "ORANGE_TULIP": 1, + "OXEYE_DAISY": 1, + "PACKED_ICE": 1, + "PACKED_MUD": 1, + "PEONY": 2, + "PINK_PETALS": 16, + "PINK_TULIP": 1, + "PITCHER_CROP": 3, + "PITCHER_PLANT": 2, + "PODZOL": 1, + "POLISHED_ANDESITE": 1, + "POLISHED_ANDESITE_SLAB": 3, + "POLISHED_ANDESITE_STAIRS": 8, + "POLISHED_BASALT": 3, + "POLISHED_BLACKSTONE": 1, + "POLISHED_BLACKSTONE_BRICKS": 1, + "POLISHED_BLACKSTONE_BRICK_SLAB": 3, + "POLISHED_BLACKSTONE_BRICK_STAIRS": 8, + "POLISHED_BLACKSTONE_BRICK_WALL": 162, + "POLISHED_BLACKSTONE_BUTTON": 12, + "POLISHED_BLACKSTONE_PRESSURE_PLATE": 2, + "POLISHED_BLACKSTONE_SLAB": 3, + "POLISHED_BLACKSTONE_STAIRS": 8, + "POLISHED_BLACKSTONE_WALL": 162, + "POLISHED_DEEPSLATE": 1, + "POLISHED_DEEPSLATE_SLAB": 3, + "POLISHED_DEEPSLATE_STAIRS": 8, + "POLISHED_DEEPSLATE_WALL": 162, + "POLISHED_DIORITE": 1, + "POLISHED_DIORITE_SLAB": 3, + "POLISHED_DIORITE_STAIRS": 8, + "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, + "POWERED_RAIL": 12, + "PRISMARINE": 1, + "PRISMARINE_BRICKS": 1, + "PRISMARINE_BRICKS_SLAB": 3, + "PRISMARINE_BRICKS_STAIRS": 8, + "PRISMARINE_SLAB": 3, + "PRISMARINE_STAIRS": 8, + "PRISMARINE_WALL": 162, + "PUMPKIN": 1, + "PUMPKIN_STEM": 40, + "PURPLE_TORCH": 5, + "PURPUR": 1, + "PURPUR_PILLAR": 3, + "PURPUR_SLAB": 3, + "PURPUR_STAIRS": 8, + "QUARTZ": 1, + "QUARTZ_BRICKS": 1, + "QUARTZ_PILLAR": 3, + "QUARTZ_SLAB": 3, + "QUARTZ_STAIRS": 8, + "RAIL": 10, + "RAW_COPPER": 1, + "RAW_GOLD": 1, + "RAW_IRON": 1, + "REDSTONE": 1, + "REDSTONE_COMPARATOR": 16, + "REDSTONE_LAMP": 2, + "REDSTONE_ORE": 2, + "REDSTONE_REPEATER": 32, + "REDSTONE_TORCH": 10, + "REDSTONE_WIRE": 16, + "RED_MUSHROOM": 1, + "RED_MUSHROOM_BLOCK": 11, + "RED_NETHER_BRICKS": 1, + "RED_NETHER_BRICK_SLAB": 3, + "RED_NETHER_BRICK_STAIRS": 8, + "RED_NETHER_BRICK_WALL": 162, + "RED_SAND": 1, + "RED_SANDSTONE": 1, + "RED_SANDSTONE_SLAB": 3, + "RED_SANDSTONE_STAIRS": 8, + "RED_SANDSTONE_WALL": 162, + "RED_TORCH": 5, + "RED_TULIP": 1, + "REINFORCED_DEEPSLATE": 1, + "RESERVED6": 1, + "ROSE_BUSH": 2, + "SAND": 1, + "SANDSTONE": 1, + "SANDSTONE_SLAB": 3, + "SANDSTONE_STAIRS": 8, + "SANDSTONE_WALL": 162, + "SCULK": 1, + "SEA_LANTERN": 1, + "SEA_PICKLE": 8, + "SHROOMLIGHT": 1, + "SHULKER_BOX": 1, + "SLIME": 1, + "SMALL_DRIPLEAF": 8, + "SMITHING_TABLE": 1, + "SMOKER": 8, + "SMOOTH_BASALT": 1, + "SMOOTH_QUARTZ": 1, + "SMOOTH_QUARTZ_SLAB": 3, + "SMOOTH_QUARTZ_STAIRS": 8, + "SMOOTH_RED_SANDSTONE": 1, + "SMOOTH_RED_SANDSTONE_SLAB": 3, + "SMOOTH_RED_SANDSTONE_STAIRS": 8, + "SMOOTH_SANDSTONE": 1, + "SMOOTH_SANDSTONE_SLAB": 3, + "SMOOTH_SANDSTONE_STAIRS": 8, + "SMOOTH_STONE": 1, + "SMOOTH_STONE_SLAB": 3, + "SNOW": 1, + "SNOW_LAYER": 8, + "SOUL_CAMPFIRE": 8, + "SOUL_FIRE": 1, + "SOUL_LANTERN": 2, + "SOUL_SAND": 1, + "SOUL_SOIL": 1, + "SOUL_TORCH": 5, + "SPONGE": 2, + "SPORE_BLOSSOM": 1, + "SPRUCE_BUTTON": 12, + "SPRUCE_DOOR": 32, + "SPRUCE_FENCE": 1, + "SPRUCE_FENCE_GATE": 16, + "SPRUCE_LEAVES": 4, + "SPRUCE_LOG": 6, + "SPRUCE_PLANKS": 1, + "SPRUCE_PRESSURE_PLATE": 2, + "SPRUCE_SAPLING": 2, + "SPRUCE_SIGN": 16, + "SPRUCE_SLAB": 3, + "SPRUCE_STAIRS": 8, + "SPRUCE_TRAPDOOR": 16, + "SPRUCE_WALL_SIGN": 4, + "SPRUCE_WOOD": 6, + "STAINED_CLAY": 16, + "STAINED_GLASS": 16, + "STAINED_GLASS_PANE": 16, + "STAINED_HARDENED_GLASS": 16, + "STAINED_HARDENED_GLASS_PANE": 16, + "STONE": 1, + "STONECUTTER": 4, + "STONE_BRICKS": 1, + "STONE_BRICK_SLAB": 3, + "STONE_BRICK_STAIRS": 8, + "STONE_BRICK_WALL": 162, + "STONE_BUTTON": 12, + "STONE_PRESSURE_PLATE": 2, + "STONE_SLAB": 3, + "STONE_STAIRS": 8, + "SUGARCANE": 16, + "SUNFLOWER": 2, + "SWEET_BERRY_BUSH": 4, + "TALL_GRASS": 1, + "TINTED_GLASS": 1, + "TNT": 4, + "TORCH": 5, + "TORCHFLOWER": 1, + "TORCHFLOWER_CROP": 2, + "TRAPPED_CHEST": 4, + "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, + "WALL_BANNER": 64, + "WALL_CORAL_FAN": 40, + "WARPED_BUTTON": 12, + "WARPED_DOOR": 32, + "WARPED_FENCE": 1, + "WARPED_FENCE_GATE": 16, + "WARPED_HYPHAE": 6, + "WARPED_PLANKS": 1, + "WARPED_PRESSURE_PLATE": 2, + "WARPED_ROOTS": 1, + "WARPED_SIGN": 16, + "WARPED_SLAB": 3, + "WARPED_STAIRS": 8, + "WARPED_STEM": 6, + "WARPED_TRAPDOOR": 16, + "WARPED_WALL_SIGN": 4, + "WARPED_WART_BLOCK": 1, + "WATER": 32, + "WATER_CAULDRON": 6, + "WEEPING_VINES": 26, + "WEIGHTED_PRESSURE_PLATE_HEAVY": 16, + "WEIGHTED_PRESSURE_PLATE_LIGHT": 16, + "WHEAT": 8, + "WHITE_TULIP": 1, + "WITHER_ROSE": 1, + "WOOL": 16 +} \ No newline at end of file diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index b4b3875c680..e86f70d70ee 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -21,86 +21,31 @@ declare(strict_types=1); -use pocketmine\block\Block; +use pocketmine\block\BlockTest; use pocketmine\block\RuntimeBlockStateRegistry; -use pocketmine\utils\AssumptionFailedError; -use pocketmine\utils\Utils; require dirname(__DIR__, 3) . '/vendor/autoload.php'; /* This script needs to be re-run after any intentional blockfactory change (adding or removing a block state). */ -$factory = new RuntimeBlockStateRegistry(); -$remaps = []; -$new = []; -foreach(RuntimeBlockStateRegistry::getInstance()->getAllKnownStates() as $index => $block){ - if($index !== $block->getStateId()){ - throw new AssumptionFailedError("State index should always match state ID"); - } - $new[$index] = $block->getName(); -} +$newTable = BlockTest::computeConsistencyCheckTable(RuntimeBlockStateRegistry::getInstance()); $oldTablePath = __DIR__ . '/block_factory_consistency_check.json'; if(file_exists($oldTablePath)){ - $oldTable = json_decode(file_get_contents($oldTablePath), true); - if(!is_array($oldTable)){ - throw new AssumptionFailedError("Old table should be array{knownStates: array, stateDataBits: int}"); - } - $old = []; - /** - * @var string $name - * @var int[] $stateIds - */ - foreach($oldTable["knownStates"] as $name => $stateIds){ - foreach($stateIds as $stateId){ - $old[$stateId] = $name; - } - } - $oldStateDataSize = $oldTable["stateDataBits"]; - $oldStateDataMask = ~(~0 << $oldStateDataSize); + $errors = BlockTest::computeConsistencyCheckDiff($oldTablePath, $newTable); - if($oldStateDataSize !== Block::INTERNAL_STATE_DATA_BITS){ - echo "State data bits changed from $oldStateDataSize to " . Block::INTERNAL_STATE_DATA_BITS . "\n"; - } - - foreach($old as $k => $name){ - [$oldId, $oldStateData] = [$k >> $oldStateDataSize, $k & $oldStateDataMask]; - $reconstructedK = ($oldId << Block::INTERNAL_STATE_DATA_BITS) | $oldStateData; - if(!isset($new[$reconstructedK])){ - echo "Removed state for $name ($oldId:$oldStateData)\n"; - } - } - foreach($new as $k => $name){ - [$newId, $newStateData] = [$k >> Block::INTERNAL_STATE_DATA_BITS, $k & Block::INTERNAL_STATE_DATA_MASK]; - if($newStateData > $oldStateDataMask){ - echo "Added state for $name ($newId, $newStateData)\n"; - }else{ - $reconstructedK = ($newId << $oldStateDataSize) | $newStateData; - if(!isset($old[$reconstructedK])){ - echo "Added state for $name ($newId:$newStateData)\n"; - }elseif($old[$reconstructedK] !== $name){ - echo "Name changed ($newId:$newStateData) " . $old[$reconstructedK] . " -> " . $name . "\n"; - } + if(count($errors) > 0){ + echo count($errors) . " changes detected:\n"; + foreach($errors as $error){ + echo $error . "\n"; } + }else{ + echo "No changes detected\n"; } }else{ echo "WARNING: Unable to calculate diff, no previous consistency check file found\n"; } -$newTable = []; -foreach($new as $stateId => $name){ - $newTable[$name][] = $stateId; -} ksort($newTable, SORT_STRING); -foreach(Utils::stringifyKeys($newTable) as $name => $stateIds){ - sort($stateIds, SORT_NUMERIC); - $newTable[$name] = $stateIds; -} -file_put_contents(__DIR__ . '/block_factory_consistency_check.json', json_encode( - [ - "knownStates" => $newTable, - "stateDataBits" => Block::INTERNAL_STATE_DATA_BITS - ], - JSON_THROW_ON_ERROR -)); +file_put_contents($oldTablePath, json_encode($newTable, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT)); diff --git a/tests/phpunit/data/bedrock/block/BlockStateDataTest.php b/tests/phpunit/data/bedrock/block/BlockStateDataTest.php index 836edfc38f3..7add2eddae6 100644 --- a/tests/phpunit/data/bedrock/block/BlockStateDataTest.php +++ b/tests/phpunit/data/bedrock/block/BlockStateDataTest.php @@ -27,6 +27,7 @@ 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; @@ -39,7 +40,19 @@ public function testCurrentVersion() : void{ ) 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/tests/phpunit/scheduler/AsyncPoolTest.php b/tests/phpunit/scheduler/AsyncPoolTest.php index d7bacd391a4..53ec15c12b6 100644 --- a/tests/phpunit/scheduler/AsyncPoolTest.php +++ b/tests/phpunit/scheduler/AsyncPoolTest.php @@ -32,7 +32,6 @@ use function define; use function dirname; use function microtime; -use function sys_get_temp_dir; use function usleep; class AsyncPoolTest extends TestCase{ @@ -44,13 +43,12 @@ class AsyncPoolTest extends TestCase{ public function setUp() : void{ @define('pocketmine\\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 3) . '/vendor/autoload.php'); - $this->mainLogger = new MainLogger(null, sys_get_temp_dir(), false, "Main", new \DateTimeZone('UTC')); + $this->mainLogger = new MainLogger(null, false, "Main", new \DateTimeZone('UTC')); $this->pool = new AsyncPool(2, 1024, new ThreadSafeClassLoader(), $this->mainLogger, new SleeperHandler()); } public function tearDown() : void{ $this->pool->shutdown(); - $this->mainLogger->shutdownLogWriterThread(); } public function testTaskLeak() : void{ diff --git a/tools/generate-bedrock-data-from-packets.php b/tools/generate-bedrock-data-from-packets.php index ca15bd8bec0..16c3062b845 100644 --- a/tools/generate-bedrock-data-from-packets.php +++ b/tools/generate-bedrock-data-from-packets.php @@ -195,7 +195,7 @@ private function itemStackToJson(ItemStack $itemStack) : ItemStackData{ * @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 @@ private function shapedRecipeToJson(ShapedRecipe $entry) : ShapedRecipeData{ } } } + $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) : [] ); } @@ -407,7 +411,13 @@ public function handleCraftingData(CraftingDataPacket $packet) : bool{ $mappedType = $typeMap[$entry->getTypeId()]; if($entry instanceof ShapedRecipe){ - $recipes[$mappedType][] = $this->shapedRecipeToJson($entry); + //all known recipes are currently symmetric and I don't feel like attaching a `symmetric` field to + //every shaped recipe for this - split it into a separate category instead + if(!$entry->isSymmetric()){ + $recipes[$mappedType . "_asymmetric"][] = $this->shapedRecipeToJson($entry); + }else{ + $recipes[$mappedType][] = $this->shapedRecipeToJson($entry); + } }elseif($entry instanceof ShapelessRecipe){ $recipes[$mappedType][] = $this->shapelessRecipeToJson($entry); }elseif($entry instanceof MultiRecipe){ diff --git a/tools/generate-blockstate-upgrade-schema.php b/tools/generate-blockstate-upgrade-schema.php index dfb8f6066bd..54984d4591a 100644 --- a/tools/generate-blockstate-upgrade-schema.php +++ b/tools/generate-blockstate-upgrade-schema.php @@ -38,18 +38,23 @@ use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; use function array_key_first; +use function array_key_last; use function array_keys; use function array_map; use function array_shift; use function array_values; use function count; use function dirname; -use function explode; use function file_put_contents; use function fwrite; use function implode; use function json_encode; use function ksort; +use function min; +use function sort; +use function strlen; +use function strrev; +use function substr; use function usort; use const JSON_PRETTY_PRINT; use const SORT_STRING; @@ -275,6 +280,77 @@ function processStateGroup(string $oldName, array $upgradeTable, BlockStateUpgra return true; } +/** + * @param string[] $strings + */ +function findCommonPrefix(array $strings) : string{ + sort($strings, SORT_STRING); + + $first = $strings[array_key_first($strings)]; + $last = $strings[array_key_last($strings)]; + + $maxLength = min(strlen($first), strlen($last)); + for($i = 0; $i < $maxLength; ++$i){ + if($first[$i] !== $last[$i]){ + return substr($first, 0, $i); + } + } + + return substr($first, 0, $maxLength); +} + +/** + * @param string[] $strings + */ +function findCommonSuffix(array $strings) : string{ + $reversed = array_map(strrev(...), $strings); + + return strrev(findCommonPrefix($reversed)); +} + +/** + * @param string[][][] $candidateFlattenedValues + * @phpstan-param array>> $candidateFlattenedValues + * + * @return BlockStateUpgradeSchemaFlattenedName[][] + * @phpstan-return array> + */ +function buildFlattenPropertyRules(array $candidateFlattenedValues) : array{ + $flattenPropertyRules = []; + foreach(Utils::stringifyKeys($candidateFlattenedValues) as $propertyName => $filters){ + foreach(Utils::stringifyKeys($filters) as $filter => $valueToId){ + $ids = array_values($valueToId); + + //TODO: this is a bit too enthusiastic. For example, when flattening the old "stone", it will see that + //"granite", "andesite", "stone" etc all have "e" as a common suffix, which works, but looks a bit daft. + //This also causes more remaps to be generated than necessary, since some of the values are already + //contained in the new ID. + $idPrefix = findCommonPrefix($ids); + $idSuffix = findCommonSuffix($ids); + if(strlen($idSuffix) < 2){ + $idSuffix = ""; + } + + $valueMap = []; + foreach(Utils::stringifyKeys($valueToId) as $value => $newId){ + $newValue = substr($newId, strlen($idPrefix), $idSuffix !== "" ? -strlen($idSuffix) : null); + if($newValue !== $value){ + $valueMap[$value] = $newValue; + } + } + + $flattenPropertyRules[$propertyName][$filter] = new BlockStateUpgradeSchemaFlattenedName( + $idPrefix, + $propertyName, + $idSuffix, + $valueMap + ); + } + } + ksort($flattenPropertyRules, SORT_STRING); + return $flattenPropertyRules; +} + /** * Attempts to compress a list of remapped states by looking at which state properties were consistently unchanged. * This significantly reduces the output size during flattening when the flattened block has many permutations @@ -327,9 +403,9 @@ function processRemappedStates(array $upgradeTable) : array{ $unchangedStatesByNewName[$newName] = $unchangedStates; } - $flattenedProperties = []; $notFlattenedProperties = []; - $notFlattenedPropertyValues = []; + + $candidateFlattenedValues = []; foreach($upgradeTable as $pair){ foreach(Utils::stringifyKeys($pair->old->getStates()) as $propertyName => $propertyValue){ if(isset($notFlattenedProperties[$propertyName])){ @@ -344,37 +420,41 @@ function processRemappedStates(array $upgradeTable) : array{ $notFlattenedProperties[$propertyName] = true; continue; } - $parts = explode($rawValue, $pair->new->getName(), 2); - if(count($parts) !== 2){ - //the new name does not contain the property value, but it may still be able to be flattened in other cases - $notFlattenedPropertyValues[$propertyName][$rawValue] = $rawValue; - continue; - } - [$prefix, $suffix] = $parts; $filter = $pair->old->getStates(); foreach($unchangedStatesByNewName[$pair->new->getName()] as $unchangedPropertyName){ unset($filter[$unchangedPropertyName]); } unset($filter[$propertyName]); + $rawFilter = encodeOrderedProperties($filter); - $flattenRule = new BlockStateUpgradeSchemaFlattenedName( - prefix: $prefix, - flattenedProperty: $propertyName, - suffix: $suffix - ); - if(!isset($flattenedProperties[$propertyName][$rawFilter])){ - $flattenedProperties[$propertyName][$rawFilter] = $flattenRule; - }elseif(!$flattenRule->equals($flattenedProperties[$propertyName][$rawFilter])){ - $notFlattenedProperties[$propertyName] = true; + if(isset($candidateFlattenedValues[$propertyName][$rawFilter])){ + $valuesToIds = $candidateFlattenedValues[$propertyName][$rawFilter]; + $existingNewId = $valuesToIds[$rawValue] ?? null; + if($existingNewId !== null && $existingNewId !== $pair->new->getName()){ + //this old value is associated with multiple new IDs - bad candidate for flattening + $notFlattenedProperties[$propertyName] = true; + continue; + } + foreach(Utils::stringifyKeys($valuesToIds) as $otherRawValue => $otherNewId){ + if($otherRawValue === $rawValue){ + continue; + } + if($otherNewId === $pair->new->getName()){ + //this old value maps to the same new ID as another old value - bad candidate for flattening + $notFlattenedProperties[$propertyName] = true; + continue 2; + } + } } + $candidateFlattenedValues[$propertyName][$rawFilter][$rawValue] = $pair->new->getName(); } } foreach(Utils::stringifyKeys($notFlattenedProperties) as $propertyName => $_){ - unset($flattenedProperties[$propertyName]); + unset($candidateFlattenedValues[$propertyName]); } - ksort($flattenedProperties, SORT_STRING); + $flattenedProperties = buildFlattenPropertyRules($candidateFlattenedValues); $flattenProperty = array_key_first($flattenedProperties); $list = []; @@ -393,19 +473,15 @@ function processRemappedStates(array $upgradeTable) : array{ } ksort($cleanedOldState); ksort($cleanedNewState); - $flattened = false; if($flattenProperty !== null){ $flattenedValue = $cleanedOldState[$flattenProperty] ?? null; if(!$flattenedValue instanceof StringTag){ - throw new AssumptionFailedError("This should always be a TAG_String"); - } - if(!isset($notFlattenedPropertyValues[$flattenProperty][$flattenedValue->getValue()])){ - unset($cleanedOldState[$flattenProperty]); - $flattened = true; + throw new AssumptionFailedError("This should always be a TAG_String ($newName $flattenProperty)"); } + unset($cleanedOldState[$flattenProperty]); } $rawOldState = encodeOrderedProperties($cleanedOldState); - $newNameRule = $flattenProperty !== null && $flattened ? + $newNameRule = $flattenProperty !== null ? $flattenedProperties[$flattenProperty][$rawOldState] ?? throw new AssumptionFailedError("This should always be set") : $newName;