Skip to content

Conversation

456dev
Copy link
Contributor

@456dev 456dev commented Aug 22, 2025

Fixes a bug where Items with a negative pickup delay can be picked up, which doesn't match vanilla behaviour, where any value != 0 is unable to be picked up

this is most noticable with summon commands, where high values (exceeding max short) of pickupdelay can overflow into the negatives:
ie /summon item ~ ~1 ~5 {Item:{id:"minecraft:mace",count:1},PickupDelay:60000}
(test item with /data get entity @e[type=minecraft:item, distance=..4, limit=1] PickupDelay)
-> -5536s

vanilla: unable to be picked up
paper main: able to be picked up
paper after patch: unable to be picked up

as all the changes were within existing bukkit / paper code, no new comments were added.
its possibly worth discussing the last change

-                this.pickupDelay = -1;
+                return;

the behaviour is effectively the same, skipping the if statement after, but I'm wondering if modifying pickupdelay had any deeper meaning / avoiding that early return, in-case behaviour changes in the future.

This doesn't match current vanilla behaviour, and vanilla overflows short values
ie `/summon item ~ ~1 ~5 {Item:{id:"minecraft:mace",count:1},PickupDelay:60000}`
wraps to a pickup delay of `-5536`, which vanilla treats as infinitely un-pickupable.
@456dev 456dev requested a review from a team as a code owner August 22, 2025 17:36
@github-project-automation github-project-automation bot moved this to Awaiting review in Paper PR Queue Aug 22, 2025
@Doc94
Copy link
Contributor

Doc94 commented Aug 22, 2025

Can be good mention this behaviour in docs for the method in Item?

@lynxplay
Copy link
Contributor

Should be fine as paper moved off of wall-time for items.

CB commit 029ca3e introduced this change initially to compensate for wall time potentially jumping into negative values.

@@ -41,7 +41,7 @@ public int getPickupDelay() {

@Override
public void setPickupDelay(int delay) {
this.getHandle().pickupDelay = Math.min(delay, Short.MAX_VALUE);
this.getHandle().pickupDelay = Math.clamp(Short.MIN_VALUE, delay, Short.MAX_VALUE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not the right way to clamp, did you look at the parameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, not sure what i was thinking here, i must have misread this locally.
funny this, this still works for values -inf to Short.MAX_VALUE, but nothing greater

@@ -27,14 +27,22 @@ public interface Item extends Entity, io.papermc.paper.entity.Frictional { // Pa

/**
* Gets the delay before this Item is available to be picked up by players
* <p>
* If the value is 0, the item can be picked up immediately.
* If the value is negative or {@link Short#MAX_VALUE} (32767), the item cannot be picked up at all.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this part is needed.
Not sure about explicitly show the magic value when setCanPlayerPickup exists, maybe instead just use a Range/IntRange annotation since it's an integer on 16 bits. The negative value doesn't make sense in that context too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to confirm, i should annotate this param to 0 to Short.MAX_VALUE? or 1 to short.max_value -1 (just actually functional "delay")? or smth else?

Copy link
Contributor Author

@456dev 456dev Aug 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, if we prevent players from passing a negative number here, should the get method translate negative numbers to NO_PICKUP_TIME, so api users dont get a value they cannot restore later?

@Lulu13022002
Copy link
Contributor

Item#canPlayerPickup should be updated too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Awaiting review
Development

Successfully merging this pull request may close these issues.

4 participants