fix: ensure chunk is loaded before placing death chest block - #101
Closed
wangzhizhou wants to merge 2 commits into
Closed
fix: ensure chunk is loaded before placing death chest block#101wangzhizhou wants to merge 2 commits into
wangzhizhou wants to merge 2 commits into
Conversation
Death chest block was placed on a possibly unloaded chunk when the player disconnected right after dying, silently discarding the block change and causing items (already cleared from the world) to be lost forever. Now we force-load the chunk (with retry up to 40 ticks) before setType(CHEST).
Author
|
Found a Bug And Fixed it, please review this PR, maybe this plugin can be publish on hangar or modrinth platform, and make more people can see it. |
During server startup, expired chests are loaded and their expiration tasks run before (or racing with) the model being added to the loaded cache, causing loadedChests.remove() to return null and throwing IllegalArgumentException 'Invalid model'. Now we return silently instead - destroying a chest is idempotent.
Author
Additional fix (commit 3572396): destroyChest idempotencySecond issue found during full regression: on server startup, expired chests get loaded and their expiration tasks run racing with the model being added to the loaded cache. Fix: return silently when the model is no longer in the cache — destroying a chest is idempotent. Verified: 2 consecutive restarts with 11 expired chests → 0 exceptions (was 1/1 before). |
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a player disconnects immediately after dying (e.g. server lag, accidental quit, or death while logging out), the death chest is never created and all items are lost forever.
Root cause
BlockCreationChestListener.onCreate()schedules the actualsetType(CHEST)call on the next tick viarunTask()(intentionally, to avoid the chest being destroyed by a delayed explosion when sleeping in the nether).Meanwhile,
SpawnChestListener.onDeath()clearsevent.getDrops()synchronously in the same death event.If the player disconnects between these two moments:
location.getBlock().setType(CHEST)writes to an unloaded chunk and is silently discardedFix
In
BlockCreationChestListener.onCreate(), before placing the chest block:world.getChunkAt(chunkX, chunkZ)This preserves the original next-tick delay (nether explosion protection) while guaranteeing the block lands on a loaded chunk.
Verification
On a Paper 26.2 test server, the repro is: give items →
/minecraft:kill→ disconnect within 2s → check chest at death location.8/8 repeated disconnect-on-death runs passed with the fix (100% chest creation, 0 item loss), vs 100% failure before.
Also added a debug log line with the chest location to confirm placement.