|
| 1 | +# 5.41.0 |
| 2 | +Released 15th February 2026. |
| 3 | + |
| 4 | +This is a minor feature release, including new gameplay and API features, performance improvements and network security improvements. |
| 5 | + |
| 6 | +**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. |
| 7 | +Do not update plugin minimum API versions unless you need new features added in this release. |
| 8 | + |
| 9 | +**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.** |
| 10 | +Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly. |
| 11 | + |
| 12 | +## General |
| 13 | +- The supported world format version has been bumped to 1.26.0 (display version 26.0). (@dktapps) |
| 14 | +- Introduced a new filtering system for game network packets to avoid decoding packets that aren't handled by the session's current handler. (@dktapps) |
| 15 | + - This substantially reduces the server's attack surface, and may also improve performance in some cases. |
| 16 | + - :warning: **IMPORTANT!** This will affect plugins using `DataPacketReceiveEvent` to handle packets. See the API section for notes on `DataPacketReceiveEvent`'s changed behaviour. |
| 17 | + - While this change does negatively affect plugins, the tradeoff was deemed worth it for the major improvement in server security that this feature provides. |
| 18 | + |
| 19 | +## Gameplay |
| 20 | +- The following items have been added: |
| 21 | + - Music Disc - Lava Chicken (@dktapps) |
| 22 | +- The following blocks have been added: |
| 23 | + - Azalea and Flowering Azalea, along with the corresponding Azalea Tree (@Azvyl) |
| 24 | + - Block of Bamboo (+ stripped) |
| 25 | + - Bamboo buttons, hanging signs, doors, fences, fence gates, planks, pressure plates, signs, slabs, stairs, and trapdoors |
| 26 | + - Bamboo mosaic planks, stairs, and slabs |
| 27 | +- Fixed various blocks not dropping as items when destroyed by explosions. (@dktapps) |
| 28 | + |
| 29 | +## API |
| 30 | +### `pocketmine\block` |
| 31 | +- The following methods have signature changes: |
| 32 | + - `BlockBreakInfo::__construct()` now accepts an optional `?bool $explosionHarvestable` parameter. If null, the block will be harvestable by explosions if it has `BlockToolType::PICKAXE` in the `$toolType` flags. (@dktapps) |
| 33 | +- The following methods have been added: |
| 34 | + - `public BlockBreakInfo->isExplosionHarvestable() : bool` (@dktapps) |
| 35 | + - Various `public static` generated methods added to `VanillaBlocks` for newly added blocks (see the Gameplay section) |
| 36 | + |
| 37 | +### `pocketmine\event\player` |
| 38 | +- The following methods have been added: |
| 39 | + - `public PlayerItemConsumeEvent->getResidue() : list<Item>` - returns leftover items, if any (@Wraith0x10, @dktapps) |
| 40 | + - `public PlayerItemConsumeEvent->setResidue(list<Item> $items) : void` - sets the leftover items to be returned to the player (@Wraith0x10, @dktapps) |
| 41 | + |
| 42 | +### `pocketmine\event\server` |
| 43 | +- `DataPacketReceiveEvent` will no longer receive all packets by default, as the server may discard packets that aren't handled by the session's current packet handler. (@dktapps) |
| 44 | + - If your plugin needs to handle packets that are filtered, handle `DataPacketDecodeEvent` with a `@handleCancelled` annotation on your handler, and use `uncancel()`. This will allow the packet to be decoded and proceed to `DataPacketReceiveEvent`. |
| 45 | + |
| 46 | +### `pocketmine\item` |
| 47 | +- The following methods have been added: |
| 48 | + - `public VanillaItems::RECORD_LAVA_CHICKEN() : Record` |
| 49 | + |
| 50 | +### `pocketmine\utils` |
| 51 | +- The following classes have been deprecated: |
| 52 | + - `RegistryTrait` - superseded by `RegistrySource` |
| 53 | + - `CloningRegistryTrait` - superseded by `RegistrySource` (override `RegistrySource->cloneResults()`) |
| 54 | + |
| 55 | +### `pocketmine\world\generator\object` |
| 56 | +- The following classes have been added: |
| 57 | + - `AzaleaTree` |
| 58 | +- The following enum cases have been added: |
| 59 | + - `TreeType::AZALEA` |
| 60 | + |
| 61 | +## Internals |
| 62 | +- The internal workings of `VanillaBlocks`, `VanillaItems` etc. have been overhauled. (@dktapps) |
| 63 | + - These registry classes are now fully generated. |
| 64 | + - When adding new members (or changing existing ones), their source classes (e.g. `VanillaBlocksInputs`) should be modified instead, and then `composer update-codegen` (or the `build/codegen/registry-interface.php` script) should be used to update the generated code. |
| 65 | + - Outwardly the API of these classes remains the same, so plugins are not affected (unless they use reflection on them, which is not an officially supported use case). |
| 66 | + - This new approach is significantly more performant, as well as being much more robust internally. |
| 67 | + - This also removes codegen-time dependencies between registries, allowing each class to be individually regenerated in any order, and permitting the deletion of the `generated` folder and running `composer update-codegen` to regenerate code from scratch. |
| 68 | + - `registerDelayed` may be used for cases that require interdependencies (to allow declaring the type for codegen without actually needing both registries to be present). This is needed to avoid dependencies for e.g. sign blocks & items. |
| 69 | +- All generated code files are now placed into the `generated` directory of the repo instead of `src`. (@dktapps) |
| 70 | +- All codegen-related build scripts have been moved to the `build/codegen` subdirectory and their `generate-` prefixes removed. (@dktapps) |
| 71 | +- Added `build/codegen/check-file-collisions.php` script to ensure that code files can't exist in both `src` and `generated`. (@dktapps) |
| 72 | +- The header for generated code files has been moved to `build/codegen/templates/header.php`. This avoids copy pasting it into every codegen script, as well as allowing it to be automatically kept up to date by PHP-CS-Fixer. (@dktapps) |
| 73 | +- Updated the NBT used for skull rotation saving. (@remminiscent) |
| 74 | +- `NetworkSession` now discards packets without decoding if the currently-assigned `PacketHandler` doesn't handle them, and if `DataPacketDecodeEvent` was not un-cancelled. |
| 75 | + - This significantly reduces the server's attack surface. |
| 76 | + - Un-cancelling `DataPacketDecodeEvent` will disable this behaviour, allowing plugins to receive unhandled packets in `DataPacketReceiveEvent` as before. |
| 77 | + - While we could disable this behaviour entirely if handlers for `DataPacketReceiveEvent` are detected, doing so would make the feature useless for a large number of servers, as many servers use plugins which use `DataPacketReceiveEvent` (e.g. anti cheats). |
| 78 | + - It may be worth allowing `NetworkSession` to have multiple `PacketHandler`s set in the future rather than doing this, but that's a debate for another time. |
| 79 | + - `#[SilentDiscard]` annotation may be used on `PacketHandler` classes to suppress debug messages about unhandled packets, without being forced to decode them. |
| 80 | + - `PacketHandlerInspector` class contains the logic used to examine `PacketHandler`s to decide if they will accept a packet. |
| 81 | + |
| 82 | + |
0 commit comments