[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: 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() )) { |