Skip to content
This repository has been archived by the owner on Jun 23, 2023. It is now read-only.

Commit

Permalink
Blocks moved by pistons don't get broadcasted twice
Browse files Browse the repository at this point in the history
Fixes #18
  • Loading branch information
bendem committed Aug 5, 2014
1 parent 274ba12 commit 893484e
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 2 deletions.
22 changes: 22 additions & 0 deletions src/main/java/be/bendem/bukkit/orebroadcast/OreBroadcast.java
Expand Up @@ -4,8 +4,10 @@
import be.bendem.bukkit.orebroadcast.commands.CommandHandler;
import be.bendem.bukkit.orebroadcast.handlers.BlockBreakListener;
import be.bendem.bukkit.orebroadcast.handlers.BlockPlaceListener;
import be.bendem.bukkit.orebroadcast.handlers.PistonListener;
import net.gravitydevelopment.updater.Updater;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;
Expand Down Expand Up @@ -61,6 +63,7 @@ public void onEnable() {

getServer().getPluginManager().registerEvents(new BlockBreakListener(this), this);
getServer().getPluginManager().registerEvents(new BlockPlaceListener(this), this);
getServer().getPluginManager().registerEvents(new PistonListener(this), this);

CommandHandler commandHandler = new CommandHandler(this, "ob");
commandHandler.register(new Command("clear", "ob.commands.clear") {
Expand Down Expand Up @@ -149,6 +152,15 @@ public void unBlackList(Block block) {
broadcastBlacklist.remove(block);
}

/**
* Unblacklist multiple blocks.
*
* @param blocks the blocks to unblacklist
*/
public void unBlackList(Collection<Block> blocks) {
broadcastBlacklist.removeAll(blocks);
}

/**
* Clear the blacklist.
*
Expand Down Expand Up @@ -181,6 +193,16 @@ public boolean isWhitelisted(Material material) {
return blocksToBroadcast.contains(material);
}

/**
* Check if OreBroadcast is active in a world
*
* @param world the world to check if OreBroadcast is active in
* @return true if OreBroadcast is active in the world
*/
public boolean isWorldWhitelisted(World world) {
return isWorldWhitelisted(world.getName());
}

/**
* Check if OreBroadcast is active in a world
*
Expand Down
59 changes: 59 additions & 0 deletions src/main/java/be/bendem/bukkit/orebroadcast/SafeBlock.java
@@ -0,0 +1,59 @@
package be.bendem.bukkit.orebroadcast;

import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;

/**
* SafeBlock contains informations about a block but doesn't prevents world
* unloading (it doesn't contain informations about the server's worlds)
* @author bendem
*/
public class SafeBlock {

public final int x;
public final int y;
public final int z;
public final String world;

public SafeBlock(Block block) {
this(block.getX(), block.getY(), block.getZ(), block.getWorld().getName());
}

public SafeBlock(int x, int y, int z, String world) {
Validate.notNull(world);
this.x = x;
this.y = y;
this.z = z;
this.world = world;
}

public Block getBlock() {
return Bukkit.getWorld(world).getBlockAt(x, y, z);
}

@Override
public boolean equals(Object o) {
if(this == o) {
return true;
}
if(!(o instanceof SafeBlock)) {
return false;
}
SafeBlock safeBlock = (SafeBlock) o;
return x == safeBlock.x
&& y == safeBlock.y
&& z == safeBlock.z
&& world.equals(safeBlock.world);
}

@Override
public int hashCode() {
int result = x;
result = 31 * result + y;
result = 31 * result + z;
result = 31 * result + world.hashCode();
return result;
}

}
Expand Up @@ -23,7 +23,7 @@ public BlockBreakListener(OreBroadcast plugin) {
this.plugin = plugin;
}

@EventHandler
@EventHandler(ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) {
Player player = event.getPlayer();
// Reject
Expand Down
Expand Up @@ -15,7 +15,7 @@ public BlockPlaceListener(OreBroadcast plugin) {
this.plugin = plugin;
}

@EventHandler
@EventHandler(ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent e) {
Block block = e.getBlock();
if(plugin.isWhitelisted(block.getType()) && plugin.isWorldWhitelisted(block.getWorld().getName()) && !plugin.isBlackListed(block)
Expand Down
@@ -0,0 +1,116 @@
package be.bendem.bukkit.orebroadcast.handlers;

import be.bendem.bukkit.orebroadcast.OreBroadcast;
import be.bendem.bukkit.orebroadcast.SafeBlock;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;

import java.util.HashMap;
import java.util.Map;

/**
* This is necessary because people are dumb enough to use pistons to
* change block position and retrigger a broadcast
*
* @author bendem
*/
public class PistonListener implements Listener {

private final OreBroadcast plugin;
private final PistonUtil pistonUtil;

public PistonListener(OreBroadcast plugin) {
this.plugin = plugin;
pistonUtil = new PistonUtil();
}

@EventHandler(ignoreCancelled = true)
public void onPistonRetract(BlockPistonRetractEvent e) {
// Workaround start - BlockPistonEvent's are sometime called multiple times
if(!pistonUtil.canRetract(e.getBlock())) {
return;
}
pistonUtil.retract(e.getBlock());
// Workaround end

Block blockMoving = e.getRetractLocation().getBlock();
if(!e.isSticky() || !plugin.isWhitelisted(blockMoving.getType()) || !plugin.isWorldWhitelisted(e.getBlock().getWorld())) {
return;
}

plugin.unBlackList(blockMoving);
plugin.blackList(blockMoving.getRelative(e.getDirection().getOppositeFace()));
}

@EventHandler(ignoreCancelled = true)
public void onPistonExtend(BlockPistonExtendEvent e) {
// Workaround start - BlockPistonEvent's are sometime called multiple times
if(!pistonUtil.canExtend(e.getBlock())) {
return;
}
pistonUtil.extend(e.getBlock());
// Workaround end

if(!plugin.isWorldWhitelisted(e.getBlock().getWorld())
|| e.getBlock().getRelative(e.getDirection()).getType() == Material.AIR) {
return;
}

plugin.getLogger().info("----");
java.util.List<Block> blocks = e.getBlocks();
for(int i = blocks.size() - 1; i >= 0; i--) {
Block block = blocks.get(i);
if(plugin.isWhitelisted(block.getType()) && plugin.isBlackListed(block)) {
plugin.unBlackList(block);
plugin.blackList(block.getRelative(e.getDirection()));
plugin.getLogger().info("Blacklisting next block: " + block.getRelative(e.getDirection()).getType().name());
}
plugin.getLogger().info(block.getType().name());
}
}

@EventHandler(ignoreCancelled = true)
public void onPistonBreak(BlockBreakEvent e) {
if(e.getBlock().getType() == Material.PISTON_BASE || e.getBlock().getType() == Material.PISTON_STICKY_BASE) {
pistonUtil.remove(e.getBlock());
}
}

private class PistonUtil {

// Contains Map<piston, is extended>
private final Map<SafeBlock, Boolean> pistons;

private PistonUtil() {
pistons = new HashMap<>();
}

public void retract(Block block) {
pistons.put(new SafeBlock(block), false);
}

public void extend(Block block) {
pistons.put(new SafeBlock(block), true);
}

public void remove(Block block) {
pistons.remove(new SafeBlock(block));
}

public boolean canRetract(Block block) {
SafeBlock safeBlock = new SafeBlock(block);
return pistons.get(safeBlock) == null || pistons.get(safeBlock);
}

public boolean canExtend(Block block) {
SafeBlock safeBlock = new SafeBlock(block);
return pistons.get(safeBlock) == null || !pistons.get(safeBlock);
}
}

}

0 comments on commit 893484e

Please sign in to comment.