[SPIGOT-4162] BlockDispenseEvent triggers after dispenser inventory changed Created: 27/Jul/18  Updated: 05/Jul/20  Resolved: 27/Jul/18

Status: Resolved
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Intelli Assignee: Unassigned
Resolution: Duplicate Votes: 1
Labels: 1.13

Issue Links:
Relates
relates to SPIGOT-2869 Summary Closed
Version: This server is running CraftBukkit version git-Spigot-f68f5a8-e70d864 (MC: 1.13) (Implementing API version 1.13-R0.1-SNAPSHOT)
Guidelines Read: Yes

 Description   

When BlockDispenseEvent triggers, it appears that the dispenser inventory has already changed, even though BlockDispenseEvent is a cancellable event.

For example:

protected void onBlockDispense(BlockDispenseEvent event) {
BlockData blockData = event.getBlock().getBlockData();
ItemStack item = event.getItem();
  if (item != null && blockData instanceof Dispenser) {
    Location location = event.getBlock().getLocation();
    InventoryHolder inventoryHolder = (InventoryHolder) location.getBlock().getState();
    for (ItemStack item : inventoryHolder.getInventory().getContents()) {
      System.out.println(item.getType().name());
    }
  }
}

With that code, the dispensed item won't be displayed in the output. There is one exception though, being that if a water bucket or lava bucket is being dispensed, it still shows as being in the dispenser. I assume this is because the item is being changed from, for example, a water bucket to a regular bucket. However, it still shows the original item (e.g. a water bucket).

Expected behaviour is that all items should still show up as being in the dispenser for the event, not just water and lava buckets.



 Comments   
Comment by Madeline Miller [ 05/Jul/20 ]

Actually, after testing the demo code you've used, it appears that while it still occurs after the item has been removed in 1.8.8, the items are not set to air and rather keep their original type - as mentioned in the other ticket.

I see why this is considered a duplicate now, I will move to that issue now.

Comment by Madeline Miller [ 05/Jul/20 ]

Okay, so 1.13 may not have been the version that broke it. That was just the first version that I started receiving reports about it being broken.

I've just tested this on 1.8.8 (as it's a version where I knew for a fact it worked), and it appears to be working correctly there. So the break occurred sometime between 1.8.8 and 1.12.2

Comment by md_5 [ 05/Jul/20 ]

Running the sample code on 1.12.2:

    @EventHandler
    protected void onBlockDispense(BlockDispenseEvent event)
    {
        BlockState blockData = event.getBlock().getState();
        ItemStack item = event.getItem();
        if ( item != null && blockData instanceof Dispenser )
        {
            Location location = event.getBlock().getLocation();
            InventoryHolder inventoryHolder = (InventoryHolder) location.getBlock().getState();
            for ( ItemStack i : inventoryHolder.getInventory().getContents() )
            {
                System.out.println( i );
            }
        }
    }
 

Single item in dispenser:

[17:06:39 INFO]: null
[17:06:39 INFO]: null
[17:06:39 INFO]: null
[17:06:39 INFO]: null
[17:06:39 INFO]: null
[17:06:39 INFO]: null
[17:06:39 INFO]: null
[17:06:39 INFO]: null
[17:06:39 INFO]: null 

Two items in dispenser:

[17:07:29 INFO]: ItemStack{STONE x 1}
[17:07:29 INFO]: null
[17:07:29 INFO]: null
[17:07:29 INFO]: null
[17:07:29 INFO]: null
[17:07:29 INFO]: null
[17:07:29 INFO]: null
[17:07:29 INFO]: null
[17:07:29 INFO]: null
 

 

Conclusion: The behaviour described in the ticket also occurred on 1.12.2.

If you think there was a change in behaviour between 1.12.2 and 1.13 please create a minimal reproduction plugin showing it.

Comment by Madeline Miller [ 05/Jul/20 ]

I disagree that this is a duplicate issue, the other issue appears to be somewhat different. 

 

Also, this definitely worked differently prior to 1.13. CraftBook used the state of the dispenser's inventory prior to the item being removed fine up until 1.13 - https://github.com/EngineHub/CraftBook/blob/master/src/main/java/com/sk89q/craftbook/mechanics/dispenser/DispenserRecipes.java#L77

 

This code broke upon 1.13 being released. I complained about it on the Spigot IRC back then and was told it wouldn't be fixed. I'm looking into it again now, and wondering if there is a way this behaviour can either be reverted or another method added that grabs a snapshot of the inventory from before the change was made.

However, a new method wouldn't solve the issue of cancelling the event not removing the item.

 

Comment by md_5 [ 27/Jul/18 ]

This is the same as 1.12.2?

There’s another ticket about the similar thing for the dispense event.
There is no consistency within bukkit about events reflecting state before or after, only that cancelling it will leave the thing in the same state as if the event never happened.

Generated at Sat Dec 13 15:19:15 UTC 2025 using Jira 10.3.13#10030013-sha1:56dd970ae30ebfeda3a697d25be1f6388b68a422.