OpenInv doesn't remove players from container transaction list
Kadeluxe opened this issue ยท 1 comments
Quick explanation
- Open any chest while having SilentContainer enabled
- Teleport anywhere and open another container
- Watch how inventory will get closed within 5 seconds (when previous chunk you teleported from unloads).
Video: https://imgur.com/a/5IPkOUG
NOTE: anvil menu closed on its own after nether chunk unloaded. Items got lost.
NOTE: this also happens if you have SilentContainer enabled but currently do not have permission to use it. Basically container opens normally (because you don't have permission) but bug still occurs because SilentContainer is enabled for you.
Reason why
InventoryListener::onInventoryClose
calls IAnySilentContainer::deactivateContainer
which calls ServerPlayer::doCloseContainer
.
ServerPlayer::doCloseContainer
does the following:
public void doCloseContainer() {
this.containerMenu.removed(this);
this.inventoryMenu.transferState(this.containerMenu);
this.containerMenu = this.inventoryMenu;
}
But it means that
human.containerMenu.transferTo(human.inventoryMenu, human.getBukkitEntity());
which server calls internally after InventoryCloseEvent dispatching will never get called on the correct containerMenu
.
This leads to the problem of ChestBlockEntity::transaction
list being in the wrong state because container's ChestBlockEntity::onClose
method will never get called.
When server unloads a chunk it gets a list of container viewers (this is what transaction
list stores) and closes viewers inventories.
Ultimately, this leads to the bug.
I open a container, close it but container entity still counts me as a viewer.
I teleport, open another container, server unloads chunk where I have been, sees me as a container viewer (which is not the case anymore) and closes my inventory menu (if I have any menu open). If I use anvil, items get lost. Maybe there are another consequences with other container types.
This is observed on Paper 1.18.1.