Dylan T. 644f73aa84 Separate inventory holder info from container & player inventories (#6533)
This PR breaks the cyclic dependency between `Inventory` and its holder, which unblocks a lot of new developments.

### Related issues & PRs
- Fixes #5033
- Removes a blocker for #6147 (which in turn means that async tasks will eventually be able to work with tiles)
- Removes a blocker for #2684

## Changes
### API changes
- `Player->getCurrentWindow()` now returns `?InventoryWindow` instead of `?Inventory`
- `Player->setCurrentWindow()` now accepts `?InventoryWindow` instead of `?Inventory`
- `InventoryWindow` introduced, which is created for each player viewing the inventory, provides decorative information like holder info for `InventoryTransactionEvent`, and is destroyed when the window is closed, eliminating cyclic references
- Added:
  - `player\InventoryWindow`
  - `player\PlayerInventoryWindow` - wraps all permanent inventories of Player with type info for transactions
  - `inventory\Hotbar` - replaces all hotbar usages in `PlayerInventory`
  - `Human->getHotbar()`
  - `Human->getMainHandItem()`, `Human->setMainHandItem()`, `Human->getOffHandItem()`, `Human->setOffHandItem()`
  - `block\utils\AnimatedContainerLike` & `block\utils\AnimatedContainerLikeTrait` (for chests, shulkerboxes, etc)
  - `block\utils\Container` & `block\utils\ContainerTrait` for blocks containing items (chests, etc)
  - `block\utils\MenuAccessor` implemented by all blocks that can open inventory menus
  - `block\utils\MenuAccessorTrait` used by blocks with menus but without inventories (anvils, crafting tables etc)
- Removed:
  - `inventory\DelegateInventory` (only used for ender chests)
  - `inventory\PlayerInventory`,
  - `inventory\PlayerOffHandInventory`,
  - `inventory\PlayerCraftingInventory`,
  - `inventory\PlayerCursorInventory` - these have all been internally replaced by `SimpleInventory` & they will appear as `PlayerInventoryWindow` in transactions (check `getType()` against the `PlayerInventoryWindow::TYPE_*` constants to identify them)
  - `block\inventory\AnimatedBlockInventoryTrait`, (blocks now handle this logic directly using `AnimatedContainer` and `AnimatedContainerTrait`)
  - `block\inventory\BlockInventoryTrait`,
  - `block\inventory\BlockInventory`
- Most `BlockInventory` classes have been transitioned to `InventoryWindow` wrappers
- Tiles now all use `SimpleInventory` internally (no cyclic references) except for `Chest` (which uses `CombinedInventory`, without holder info)
- `InventoryOpenEvent` and `InventoryCloseEvent` now provide `InventoryWindow` instead of `Inventory` (to provide type information)
- `InventoryTransaction` and `SlotChangeAction` now provide `InventoryWindow` instead of `Inventory`
- Renamed `TransactionBuilderInventory` to `SlotChangeActionBuilder`
- `TransactionBuilderInventory->getBuilder()` now accepts `InventoryWindow` instead of `Inventory`
- `DoubleChestInventory` superseded by `CombinedInventory` - this new class allows combining any number of inventories behind a single object; mainly used for double chests but plugins could use it to do lots of fun things

### Impacts to plugins
Plugins can now do the following:
```php
$block = $world->getBlockAt($x, $y, $z);
if($block instanceof MenuAccessor){
    $block->openToUnchecked($player);
}
```
As compared to the old way:
```php
$tile = $world->getTileAt($x, $y, $z);
if($tile instanceof Container){
    $player->setCurrentWindow($tile->getInventory());
}
```

#### Advantages
- No tile access needed
- Works for menu blocks without inventories as well as container blocks
- Less code

### Behavioural changes
Inventories no longer keep permanent cyclic references to their holders.

## Backwards compatibility
This makes significant BC breaks. However, all changes are able to be adapted to and the same amount of information is present on all APIs and events.

## Follow-up
- Implement #6147 
- Support inventory inheritance when copying blocks from one position to another
2025-09-02 19:23:16 +01:00
2022-03-09 16:28:38 +00:00
2021-11-30 01:16:28 +00:00
2025-08-30 19:23:38 +01:00
2025-08-30 19:23:38 +01:00
2024-12-02 00:40:55 +00:00
2012-12-07 02:24:55 +01:00
2022-08-16 17:22:22 +01:00


A highly customisable, open source server software for Minecraft: Bedrock Edition written in PHP

CI GitHub release (latest SemVer) Discord
GitHub all releases GitHub release (latest by SemVer)

What is this?

PocketMine-MP is a highly customisable server software for Minecraft: Bedrock Edition, built from scratch in PHP, with over 10 years of history.

If you're looking to create a Minecraft: Bedrock server with custom functionality, look no further.

  • 🧩 Powerful plugin API - extend and customise gameplay as you see fit
  • 🗺️ Rich ecosystem and large developer community - find plugins easily and learn to develop your own
  • 🌐 Multi-world support - offer a more varied game experience to players without transferring them to other server nodes
  • 🏎️ Performance - get 100+ players onto one server (depending on hardware and plugins)
  • ⤴️ Continuously updated - new Minecraft versions are usually supported within days

PocketMine-MP is NOT a vanilla Minecraft server software.

It is poorly suited to hosting vanilla survival servers. It doesn't have many features from the vanilla game, such as vanilla world generation, redstone, mob AI, and various other things.

If you just want to play vanilla survival multiplayer, consider using the official Minecraft: Bedrock server software instead of PocketMine-MP.

If that's not an option for you, you may be able to add some of PocketMine-MP's missing features using plugins from Poggit, or write plugins to implement them yourself.

Getting Started

Community & Support

Join our Discord server to chat with other users and developers.

You can also post questions on StackOverflow under the tag pocketmine.

Developing Plugins

If you want to write your own plugins, the following resources may be useful. Don't forget you can always ask our community if you need help.

Contributing to PocketMine-MP

PocketMine-MP accepts community contributions! The following resources will be useful if you want to contribute to PocketMine-MP.

New here? Check out issues with the "Easy task" label for things you could work to familiarise yourself with the codebase.

Donate

PocketMine-MP is free, but it requires a lot of time and effort from unpaid volunteers to develop. Donations enable us to keep delivering support for new versions and adding features your players love.

You can support development using the following methods:

  • Patreon
  • Bitcoin (BTC): 171u8K9e4FtU6j3e5sqNoxKUgEw9qWQdRV
  • Stellar Lumens (XLM): GAAC5WZ33HCTE3BFJFZJXONMEIBNHFLBXM2HJVAZHXXPYA3HP5XPPS7T

Thanks for your support!

Licensing information

This project is licensed under LGPL-3.0. Please see the LICENSE file for details.

pmmp/PocketMine are not affiliated with Mojang. All brands and trademarks belong to their respective owners. PocketMine-MP is not a Mojang-approved software, nor is it associated with Mojang.

Languages
PHP 99.9%