[SPIGOT-1235] CraftWorld#playEffect incorrectly validates MaterialData Created: 16/Oct/15  Updated: 27/Mar/16  Resolved: 27/Mar/16

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

Type: Bug Priority: Minor
Reporter: Jikoo Assignee: md_5
Resolution: Fixed Votes: 1
Labels: Craftbukkit, bug


 Description   

When validating data provided in World#playEffect(Location loc, Effect effect, T data), CraftBukkit checks if the required Class of data equals the provided one. This is incorrect, as the provided class may extend the required Class.

The line in question:

Validate.isTrue(data.getClass().equals(effect.getData()), "Wrong kind of data for this effect!");

The fix:

Validate.isTrue(effect.getData().isAssignableFrom(data.getClass()), "Wrong kind of data for this effect!");

To replicate this issue, the following listener can be used.

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        if (!event.hasBlock()) {
            return;
        }
        Block clicked = event.getClickedBlock();
        MaterialData data = clicked.getState().getData();
        Bukkit.broadcastMessage("Comparing " + Effect.TILE_BREAK.getData() + " and " + data.getClass());
        Bukkit.broadcastMessage("Assignable: " + TILE_BREAK.getData().isAssignableFrom(data.getClass()));
        Bukkit.broadcastMessage("Equal: " + Effect.TILE_BREAK.getData().equals(state.getData().getClass()));
        clicked.getWorld().playEffect(clicked.getLocation(), Effect.TILE_BREAK, data);
    }

When clicking a Block with a special MaterialData, such as wheat, an IllegalArgumentException is thrown.

Technically this is a Spigot bug as Craftbukkit does not provide any particles which accept a MaterialData, but I believe it would be better to fix it on the Craftbukkit side as it is a Craftbukkit shortcoming.



 Comments   
Comment by Jikoo [ 27/Mar/16 ]

This is fixed with the changes made to the particle API in 1.9.

Comment by Jikoo [ 18/Oct/15 ]

I noticed that the CraftBukkit fix was applied, however, the Spigot fix I realized was needed about an hour after opening this ticket was not. That will cause data for any class extending MaterialData to always be 0. Sorry about that, it's my fault for not reading enough before posting the ticket.

Comment by Jikoo [ 16/Oct/15 ]

Whoops, messed up my snippet a bit, that's what I get for adapting it from existing code in the editor. Fixed below.

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        if (!event.hasBlock()) {
            return;
        }
        Block clicked = event.getClickedBlock();
        MaterialData data = clicked.getState().getData();
        Bukkit.broadcastMessage("Comparing " + Effect.TILE_BREAK.getData() + " and " + data.getClass());
        Bukkit.broadcastMessage("Assignable: " + Effect.TILE_BREAK.getData().isAssignableFrom(data.getClass()));
        Bukkit.broadcastMessage("Equal: " + Effect.TILE_BREAK.getData().equals(data.getClass()));
        clicked.getWorld().playEffect(clicked.getLocation(), Effect.TILE_BREAK, data);
    }

Edit:
After further reading, another .equals needs to be replaced with .isAssignableFrom on the Spigot side in the Craftbukkit particle API patch.

if (data != null && data.getClass().equals( org.bukkit.material.MaterialData.class )) {

needs to become

if (data != null && org.bukkit.material.MaterialData.class.isAssignableFrom( data.getClass() )) {
Generated at Tue Apr 15 09:26:02 UTC 2025 using Jira 10.3.3#10030003-sha1:d220e3fefc8dfc6d47f522d3b9a20c1455e12b7b.