From 906609696ba9474feaea2fb501e669f69f8cbdba Mon Sep 17 00:00:00 2001 From: TfT_02 Date: Sun, 15 Jun 2014 01:47:31 +0200 Subject: [PATCH] Workaround a CB bug by tracking piston events There is a bug in Craftbukkit that causes piston events to fire multiple times. We need to keep track of the extend and retract events to see which piston events should be processed. --- .../nossr50/listeners/BlockListener.java | 8 +++++++ src/main/java/com/gmail/nossr50/mcMMO.java | 1 + .../com/gmail/nossr50/util/EventUtils.java | 23 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java index 9802de1b5..8503f521c 100644 --- a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java @@ -63,6 +63,10 @@ public class BlockListener implements Listener { */ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockPistonExtend(BlockPistonExtendEvent event) { + if (!EventUtils.shouldProcessEvent(event.getBlock(), true)) { + return; + } + List blocks = event.getBlocks(); BlockFace direction = event.getDirection(); Block futureEmptyBlock = event.getBlock().getRelative(direction); // Block that would be air after piston is finished @@ -93,6 +97,10 @@ public class BlockListener implements Listener { */ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockPistonRetract(BlockPistonRetractEvent event) { + if (!EventUtils.shouldProcessEvent(event.getBlock(), false)) { + return; + } + if (!event.isSticky()) { return; } diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 8e88cf21b..5f0e7a071 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -112,6 +112,7 @@ public class mcMMO extends JavaPlugin { public final static String disarmedItemKey = "mcMMO: Disarmed Item"; public final static String playerDataKey = "mcMMO: Player Data"; public final static String greenThumbDataKey = "mcMMO: Green Thumb"; + public final static String pistonDataKey = "mcMMO: Piston State"; public static FixedMetadataValue metadataValue; diff --git a/src/main/java/com/gmail/nossr50/util/EventUtils.java b/src/main/java/com/gmail/nossr50/util/EventUtils.java index 97ed41201..535214f79 100644 --- a/src/main/java/com/gmail/nossr50/util/EventUtils.java +++ b/src/main/java/com/gmail/nossr50/util/EventUtils.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Fish; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.plugin.PluginManager; import com.gmail.nossr50.mcMMO; @@ -194,4 +195,26 @@ public class EventUtils { return event; } + + /** + * There is a bug in CraftBukkit that causes piston events to + * fire multiple times. Check this method to see if the piston event + * should be processed. + * + * @param block Block object of the piston block + * @param isExtendEvent should be true when called from BlockPistonExtendEvent + * + * @return true if the PistonEvent should be processed, false otherwise + */ + public static boolean shouldProcessEvent(Block block, boolean isExtendEvent) { + String pistonAction = isExtendEvent ? "EXTEND" : "RETRACT"; + String lastAction = block.hasMetadata(mcMMO.pistonDataKey) ? block.getMetadata(mcMMO.pistonDataKey).get(0).asString() : ""; + + if (!lastAction.equals(pistonAction)) { + block.setMetadata(mcMMO.pistonDataKey, new FixedMetadataValue(mcMMO.p, pistonAction)); + return true; + } + + return false; + } }