Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-120507

Item duplication via /give

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • Minecraft 1.12, Minecraft 1.12.1 Pre-Release 1, Minecraft 1.12.1, Minecraft 1.13, Minecraft 1.13.1, Minecraft 1.13.2, Minecraft 1.14 Pre-Release 2, Minecraft 1.14 Pre-Release 3, 1.15.2, 20w06a, 20w17a, 20w19a, 20w21a, 1.16 Pre-release 2, 1.16.1, 20w29a, 20w51a, 21w03a, 1.16.5, 21w05b, 21w06a, 21w08b, 21w11a, 1.17 Release Candidate 1, 1.17, 1.17.1, 1.18.1, 22w03a, 1.18.2, 1.19, 1.19.2, 1.19.3, 1.20.1, 1.20.5 Pre-Release 4
    • Confirmed
    • Commands, Data Packs
    • Normal
    • Platform

      How to reproduce

      In creative mode with cheats enabled:

      1. Summon a hopper minecart at your position by using the command provided below.
        /summon minecraft:hopper_minecart ~ ~1 ~ {NoGravity:1b}
      2. Give yourself an apple by using the command provided below.
        /give @s minecraft:apple
      3. 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. – 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.EntityMinecartHopper
      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));
      	}
      	// ...
      }
      
      net.minecraft.tileentity.TileEntityHopper
      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;
      			}
      		}
      	}
      	// ...
      }
      

        1. MC-120507.png
          MC-120507.png
          597 kB
        2. MC-120507.mp4
          5.75 MB

            Unassigned Unassigned
            NickNackGus Timothy Southwick
            Votes:
            17 Vote for this issue
            Watchers:
            15 Start watching this issue

              Created:
              Updated:
              CHK: