Item duplication via /give
How to reproduce
In creative mode with cheats enabled:
- Summon a hopper minecart at your position by using the command provided below.
/summon minecraft:hopper_minecart ~ ~1 ~ {NoGravity:1b} - Give yourself an apple by using the command provided below.
/give @s minecraft:apple
- Notice how there's an apple in your inventory and an apple inside the hopper minecart.
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay other than 32767 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
public boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(ei.getPickupDelay() != 32767) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }
public static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(entityitem.getPickupDelay() != 32767) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }
Linked Issues
is duplicated by3
Created Issue:
Item duplication via /give
Setup:
In creative mode with cheats enabled:
- use a piston to push a block into the block occupied by your feet
- place a minecart rail on the block occupied by your head
- place blocks on either side of the rail such that minecarts will not roll away
- place a hopper minecart on the rail
- run /give @s minecraft:apple (or any other valid /give command)
Expected result:
The player picks up the item, and the hopper minecart does not.Actual result:
Both the player and the hopper minecart pick up the item, duplicating it.Suggestions:
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Environment
– System Details –
Details:
Minecraft Version: 1.12.1
Operating System: Linux (amd64) version 4.10.0-32-generic
Java Version: 1.8.0_131, Oracle Corporation
Java VM Version: OpenJDK 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 189309304 bytes (180 MB) / 336322560 bytes (320 MB) up to 6429081600 bytes (6131 MB)
JVM Flags: 4 total; -Xmx6G -XX:+UseConcMarkSweepGC -XX:-UseAdaptiveSizePolicy -Xmn128M
IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
Launched Version: 1.12.1
LWJGL: 2.9.4
OpenGL: GeForce 940MX/PCIe/SSE2 GL version 4.5.0 NVIDIA 375.66, NVIDIA Corporation
GL Caps: Using GL 1.3 multitexturing.
Using GL 1.3 texture combiners.
Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported.
Shaders are available because OpenGL 2.1 is supported.
VBOs are available because OpenGL 1.5 is supported.
Setup:
In creative mode with cheats enabled:
use a piston to push a block into the block occupied by your feetplace a minecart rail on the block occupied by your headplace blocks on either side of the rail suchthat minecartswill not roll awayplace a hopper minecart on the rail- run /give @s minecraft:apple (or any other valid /give command)
Expected result:
The player picks up the item, and the hopper minecart does not.Actual result:
Both the player and the hopper minecart pick up the item, duplicating it.Suggestions:
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
How to reproduce
In creative mode with cheats enabled:
- Use a piston to push a block into the block occupied by your feet
- Place a minecart rail on the block occupied by your head
- Place blocks on either side of the rail so that the minecart will not roll away
- Place a hopper minecart on the rail
- Execute /give @s minecraft:apple (or any other valid /give command)
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay above 32000 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(!(ei.getPickupDelay() >= 32000)) { list2.add(ei); } } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(!(entityitem.getPickupDelay() >= 32000)) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }
How to reproduce
In creative mode with cheats enabled:
- Use a piston to push a block into the block occupied by your feet
- Place a minecart rail on the block occupied by your head
- Place blocks on either side of the rail so that the minecart will not roll away
- Place a hopper minecart on the rail
- Execute /give @s minecraft:apple (or any other valid /give command)
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay above 32000 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(!(ei.getPickupDelay() >= 32000)) { list2.add(ei); } }// ...}net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(!(entityitem.getPickupDelay() >= 32000)) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }How to reproduce
In creative mode with cheats enabled:
- Use a piston to push a block into the block occupied by your feet
- Place a minecart rail on the block occupied by your head
- Place blocks on either side of the rail so that the minecart will not roll away
- Place a hopper minecart on the rail
- Execute /give @s minecraft:apple (or any other valid /give command)
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay above 32000 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(!(ei.getPickupDelay() >= 32000)) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(!(entityitem.getPickupDelay() >= 32000)) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }
How to reproduce
In creative mode with cheats enabled:
- Use a piston to push a block into the block occupied by your feet
- Place a minecart rail on the block occupied by your head
- Place blocks on either side of the rail so that the minecart will not roll away
- Place a hopper minecart on the rail
- Execute /give @s minecraft:apple (or any other valid /give command)
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay above 32000 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(!(ei.getPickupDelay() >= 32000)) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(!(entityitem.getPickupDelay() >= 32000)) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }How to reproduce
In creative mode with cheats enabled:
- Use a piston to push a block into the block occupied by your feet
- Place a minecart rail on the block occupied by your head
- Place blocks on either side of the rail so that the minecart will not roll away
- Place a hopper minecart on the rail
- Execute /give @s minecraft:apple (or any other valid /give command)
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay above 32000 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(!(ei.getPickupDelay() >= 32000)) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(!(entityitem.getPickupDelay() >= 32000)) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }
relates to
How to reproduce
In creative mode with cheats enabled:
- Use a piston to push a block into the block occupied by your feet
- Place a minecart rail on the block occupied by your head
- Place blocks on either side of the rail so that the minecart will not roll away
- Place a hopper minecart on the rail
- Execute /give @s minecraft:apple (or any other valid /give command)
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /givecommand puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay
above 32000to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(!(ei.getPickupDelay()>= 32000)) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(!(entityitem.getPickupDelay()>= 32000)) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }How to reproduce
In creative mode with cheats enabled:
- Use a piston to push a block into the block occupied by your feet
- Place a minecart rail on the block occupied by your head
- Place blocks on either side of the rail so that the minecart will not roll away
- Place a hopper minecart on the rail
- Execute /give @s minecraft:apple (or any other valid /give command)
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay other than 32767 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(ei.getPickupDelay() != 32767) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(entityitem.getPickupDelay() != 32767) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }
relates to
– System Details –
Details:
Minecraft Version: 1.12.1
Operating System: Linux (amd64) version 4.10.0-32-generic
Java Version: 1.8.0_131, Oracle Corporation
Java VM Version: OpenJDK 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 189309304 bytes (180 MB) / 336322560 bytes (320 MB) up to 6429081600 bytes (6131 MB)
JVM Flags: 4 total; -Xmx6G -XX:+UseConcMarkSweepGC -XX:-UseAdaptiveSizePolicy -Xmn128M
IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
Launched Version: 1.12.1
LWJGL: 2.9.4
OpenGL: GeForce 940MX/PCIe/SSE2 GL version 4.5.0 NVIDIA 375.66, NVIDIA Corporation
GL Caps: Using GL 1.3 multitexturing.
Using GL 1.3 texture combiners.
Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported.
Shaders are available because OpenGL 2.1 is supported.
VBOs are available because OpenGL 1.5 is supported.
How to reproduce
In creative mode with cheats enabled:
Use a piston to push a blockinto the block occupied by your feet- Place a minecart rail on the block occupied by your head
- Place blocks on either side of the rail so that the minecart will not roll away
- Place a hopper minecart on the rail
- Execute /give @s minecraft:apple (or any other valid /give command)
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay other than 32767 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(ei.getPickupDelay() != 32767) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(entityitem.getPickupDelay() != 32767) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }How to reproduce
In creative mode with cheats enabled:
- Drop a falling block such as sand into the block occupied by your feet
- Place a minecart rail on the block occupied by your head
- Place blocks on either side of the rail so that the minecart will not roll away
- Place a hopper minecart on the rail
- Execute /give @s minecraft:apple (or any other valid /give command)
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay other than 32767 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(ei.getPickupDelay() != 32767) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(entityitem.getPickupDelay() != 32767) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }
relates to
is duplicated by
is duplicated by
How to reproduce
In creative mode with cheats enabled:
- Drop a falling block such as sand into the block occupied by your feet
- Place a minecart rail on the block occupied by your head
- Place blocks on either side of the rail so that the minecart will not roll away
- Place a hopper minecart on the rail
- Execute /give @s minecraft:apple (or any other valid /give command)
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay other than 32767 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(ei.getPickupDelay() != 32767) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(entityitem.getPickupDelay() != 32767) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }How to reproduce
In creative mode with cheats enabled:
- Summon a hopper minecart at your position by using the command provided below.
/summon minecraft:hopper_minecart ~ ~1 ~ {NoGravity:1b}
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay other than 32767 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(ei.getPickupDelay() != 32767) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(entityitem.getPickupDelay() != 32767) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }
How to reproduce
In creative mode with cheats enabled:
- Summon a hopper minecart at your position by using the command provided below.
/summon minecraft:hopper_minecart ~ ~1 ~ {NoGravity:1b}
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay other than 32767 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(ei.getPickupDelay() != 32767) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(entityitem.getPickupDelay() != 32767) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }How to reproduce
In creative mode with cheats enabled:
- Summon a hopper minecart at your position by using the command provided below.
/summon minecraft:hopper_minecart ~ ~1 ~ {NoGravity:1b}- Give yourself an apple by using the command provided below.
/give @s minecraft:apple- Notice how there's an apple in your inventory and an apple inside the hopper minecart.
Expected result
The player picks up the item, and the hopper minecart does not.
Actual result
Both the player and the hopper minecart pick up the item, duplicating it.
Suggestions
- Have the item entity determine when it can be picked up, and which entity/block entity to transfer its contents to
- When an entity/block entity attempts to pick up an item, make a temporary copy of the item stack, attempt to delete the item entity, and give up if the item entity is already deleted
- When any entity/block entity attempts to take an item from an item entity, make the operation atomic - do not allow any other attempts to interact with the item entity until the first attempt is complete
Unlisted video demonstrating the bug
Code analysis
The following is based on a decompiled version of Minecraft 1.12 using MCP 9.40pre-1. – [Mod] bemoty
The /give command puts the item specified in the second argument of the command into the inventory of the player specified in the first argument of the command. With that, it also summons a so called "fake item" with an infinite pickup delay (32767) and an age of 5999 at the position of the player. The issue here is that net.minecraft.tileentity.TileEntityHopper and net.minecraft.entity.item.EntityMinecartHopper don't check an item for its pickup delay, the Minecart with a hopper at the position of the player's head therefore captures the fake item, which it obviously shouldn't.
I managed to fix this bug by creating a public getter for the delayBeforeCanPickup field in the net.minecraft.entity.item.EntityItem class, adding a for-loop to check if the picked up item has a pickup delay other than 32767 to the captureDroppedItems() method of net.minecraft.entity.item.EntityMinecartHopper, and adding a simple if-statement to the already existing for-loop in the captureDroppedItems() method of net.minecraft.tileentity.TileEntityHopper.
net.minecraft.entity.item.EntityMinecartHopperpublic boolean captureDroppedItems() { // ... List<EntityItem> list = this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), EntitySelectors.IS_ALIVE); List<EntityItem> list2 = new ArrayList<EntityItem>(); for(EntityItem ei : list) { if(ei.getPickupDelay() != 32767) { list2.add(ei); } } if (!list2.isEmpty()) { TileEntityHopper.putDropInInventoryAllSlots((IInventory)null, this, list2.get(0)); } // ... }net.minecraft.tileentity.TileEntityHopperpublic static boolean captureDroppedItems(IHopper hopper) { // ... for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos())) { if(entityitem.getPickupDelay() != 32767) { if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem)) { return true; } } } // ... }
duplicates
is duplicated by
duplicates
is duplicated by
is duplicated by
For future reference: Duplicates MC-120507
But report will not be re-resolved
Thank you for your report!
We're tracking this issue in MC-120507, so this ticket is being resolved and linked as a duplicate.
If you would like to add a vote and any extra information to the main ticket it would be appreciated.
If you haven't already, you might like to make use of the search feature to see if the issue has already been mentioned.
Quick Links:
📓 Bug Tracker Guidelines – 💬 Community Support – 📧 Mojang Support
📓 Project Summary – ✍️ Feedback and Suggestions – 📖 Game Wiki
– I am a bot. This action was performed automatically! The ticket was resolved by one of our moderators, and I left this message to give more information to you.
Duplicate of MC-120507
Does MC-120507 describe your issue?


This doesn't need to be private as you need permissions to use this.
It isn't a problem for normal worlds, but it is a problem for mapmakers using /give.
Confirmed for 20w06a, please update the reproduce steps to use sand instead of pistons as that pushes you up a block.
Can confirm that this is still an issue in 20w51a.
Can confirm in 21w03a.
Can confirm in 21w03a.
Can confirm in 21w03a.
Can confirm in 21w05b.
Can confirm in 21w06a.
Can confirm in 1.16.5 and 21w08b.
Can confirm in 21w11a. Relates to MC-135354.
Can confirm in 1.17.1. Video attached.
Can confirm in 1.18.1.
Can confirm in 1.18.2. For ease and convenience of reproducing this, you can simply execute the following commands and observe how you can duplicate items using the "/give" command.
/summon minecraft:hopper_minecart ~ ~1 ~ {NoGravity:1b}Can confirm in 1.19.
Can confirm in 1.19.2.