Skip to content

fix: item-drop rollback discards item instead of returning it to player#381

Open
netcrafts wants to merge 1 commit into
QuiltServerTools:masterfrom
netcrafts:fix/item-drop-rollback
Open

fix: item-drop rollback discards item instead of returning it to player#381
netcrafts wants to merge 1 commit into
QuiltServerTools:masterfrom
netcrafts:fix/item-drop-rollback

Conversation

@netcrafts

Copy link
Copy Markdown
Contributor

What does this change?

Fixes ItemDropActionType.rollback() so that rolling back an item-drop action correctly returns the item to the player in all cases — including when the dropped entity has already despawned.

Why?

When a player rolls back an item-drop action, the expected behaviour is that the drop is undone — the item should return to the dropping player's inventory. The previous implementation had two bugs:

  1. The rollback only called entity.remove(DISCARDED) on the dropped entity, removing the item from the world without placing it anywhere. The rollback reported success, but the item was gone.
  2. If the dropped entity was no longer present — either because it despawned after 5 minutes or was already picked up — the rollback failed entirely with no item restored. For an anti-griefing tool, rollbacks on despawned items must still succeed.

How?

The rollback now removes the dropped ItemEntity if it is still present (safe no-op if already gone), then always proceeds to restore the item:

  1. Reconstructs the ItemStack from the logged action data (via the existing getStack() helper).
  2. Looks up the source player by UUID via server.playerList.getPlayer().
  3. If the player is online and their inventory has space, adds the item directly to their inventory.
  4. If the player is offline or their inventory is full, spawns a fresh ItemEntity at the logged drop coordinates (Vec3.atCenterOf(pos)) — so the item is never lost. The fallback entity is created with a new UUID rather than restored from the original NBT, avoiding UUID collisions.

Note on duplication: if the item was picked up by another player and only the item-drop is rolled back (not the subsequent item-pick-up), this will duplicate the item. In practice, Ledger rollbacks are run with a player + time range which catches both actions; cross-referencing related actions is the operator's responsibility.

Testing

  1. Drop an item on a server with Ledger running and confirm the item-drop is logged.
  2. Run /ledger rollback immediately (item still on ground).
    • Before fix: item disappears, inventory unchanged — item lost.
    • After fix: item removed from ground, returned to player inventory.
  3. Drop an item, wait for it to despawn (5 min), then rollback.
    • Before fix: rollback fails — Failed to rollback item-drop.
    • After fix: item returned to player inventory.
  4. Drop an item, let another player pick it up, then rollback only the drop.
    • After fix: item is restored (operator should also roll back the pickup to avoid duplication).
  5. Drop an item with a full inventory, then rollback — item re-spawns at the original drop coordinates.

@netcrafts
netcrafts requested a review from a team as a code owner July 19, 2026 02:14
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