Skip to content

Unlink a minion's container when it is destroyed - #2

Open
Crispi2k24 wants to merge 2 commits into
EternalCodeTeam:developfrom
Crispi2k24:fix/chest-link-cleanup
Open

Crispi2k24 wants to merge 2 commits into
EternalCodeTeam:developfrom
Crispi2k24:fix/chest-link-cleanup

Conversation

@Crispi2k24

Copy link
Copy Markdown

What changed

MinionRegistry keeps a second chunk index, this one keyed by the position of a minion's linked container, maintained in the same three places as the existing minion index (register, replace, remove). findLinkedToChest answers from that index instead of walking every minion.

A new MinionChestLinkController listens for a container being broken, burnt, or blown up and clears the link on every minion pointing at it, telling the owner when they are online.

Why

A chest link is stored as a position, and MinionContext#linkedChest accepts whatever Container currently sits there:

return block.getState(false) instanceof Container container ? container : null;

Nothing cleared the link when the container was destroyed, so the position outlived the chest it referred to. Break the linked chest, put a furnace in the same spot, and the minion happily starts filling the furnace - a container the owner never linked and may not even own the contents of. The same happens with a dropper, a hopper, or a shulker box placed by someone else entirely.

Checking the block type on every deposit would not fix it: a furnace is a Container too, so the deposit path cannot tell a replacement apart from the original. The link has to be dropped at the moment the container stops existing, which is what this does.

The lookup goes through an index rather than a scan because the check runs on every broken block. A server with thousands of minions would otherwise pay for a full pass each time anyone mines anything.

Testing / notes

./gradlew build passes. Verified on a Purpur 26.2 server: breaking a linked chest clears the link and notifies the owner, a container placed in the same spot afterwards is ignored, and blowing the chest up with a creeper behaves the same. Unlinking and relinking by hand through the panel still works, and links survive a restart.

Only the four events that actually remove a block are handled. A container taken out while its chunk is unloaded - a world edit, say - still leaves a stale position; catching that would need the link to remember what it pointed at, which felt like a separate change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant