package com.nicewuerfel.blockown.event; import com.google.common.base.Optional; import com.nicewuerfel.blockown.InvalidWorldNameException; import com.nicewuerfel.blockown.Ownable; import com.nicewuerfel.blockown.OwnedBlock; import com.nicewuerfel.blockown.OwnedEntity; import com.nicewuerfel.blockown.Setting; import com.nicewuerfel.blockown.User; import com.nicewuerfel.blockown.database.Database; import com.nicewuerfel.blockown.protection.Protection; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.HumanEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.block.BlockIgniteEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.weather.LightningStrikeEvent; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import javax.annotation.Nonnull; public class L_EnvironmentDamage extends Listener { private static final Set<DamageCause> ENVIRONMENT_DAMAGES; private static final Set<BlockFace> FIRE_RELEVANT_BLOCK_FACES; static { Set<DamageCause> envDmg = new HashSet<>(8, 1); envDmg.addAll(Arrays.asList(DamageCause.BLOCK_EXPLOSION, DamageCause.ENTITY_EXPLOSION, DamageCause.FALL, DamageCause.FALLING_BLOCK, DamageCause.FIRE, DamageCause.FIRE_TICK, DamageCause.LIGHTNING, DamageCause.PROJECTILE)); ENVIRONMENT_DAMAGES = Collections.unmodifiableSet(envDmg); Set<BlockFace> blockFaces = new HashSet<>(6, 1); blockFaces.addAll(Arrays.asList(BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, BlockFace.EAST, BlockFace.DOWN)); FIRE_RELEVANT_BLOCK_FACES = Collections.unmodifiableSet(blockFaces); } public L_EnvironmentDamage(Setting setting, Database database, Protection protection) { super(setting, database, protection); } @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onBlockBurn(BlockBurnEvent event) { if (!setting.PROTECTION.PROTECT_AGAINST_ENVIRONMENT) { return; } if (!setting.isEnabledIn(event.getBlock().getWorld())) { return; } OwnedBlock block = OwnedBlock.newInstance(event.getBlock()); try { if (invalidAccess(block)) { event.setCancelled(true); // extinguishSurroundingFires(event.getBlock()); } } catch (InvalidWorldNameException e) { // can't happen, since the OwnedBlock is backed by a bukkit Block getOutput().printError("This should never happen! L_ENVDAM", e); } } private void extinguishSurroundingFires(Block block) { for (BlockFace face : FIRE_RELEVANT_BLOCK_FACES) { Block relative = block.getRelative(face); if (relative.getType() == org.bukkit.Material.FIRE) { relative.setType(org.bukkit.Material.AIR);// CHECK FOR OWNER FIRST } } } // @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onBlockIgnite(BlockIgniteEvent event) { if (!setting.PROTECTION.PROTECT_AGAINST_ENVIRONMENT) { return; } if (!setting.isEnabledIn(event.getBlock().getWorld())) { return; } OwnedBlock block = OwnedBlock.newInstance(event.getBlock()); try { if (invalidAccess(block)) { event.setCancelled(true); } } catch (InvalidWorldNameException e) { // can't happen, since the OwnedBlock is backed by a bukkit Block getOutput().printError("This should never happen! L_ENVDAM", e); } } // @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onLightningStrike(LightningStrikeEvent event) { } @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onEntityDamage(EntityDamageEvent event) { if (!setting.PROTECTION.PROTECT_AGAINST_ENVIRONMENT) { return; } if (!setting.isEnabledIn(event.getEntity().getWorld())) { return; } if (!isProtectedDamageCause(event.getCause())) { return; } OwnedEntity entity = OwnedEntity.newInstance(event.getEntity()); try { if (invalidAccess(entity)) { event.setCancelled(true); } } catch (InvalidWorldNameException e) { // can't happen, since the OwnedEntity is backed by a bukkit Entity getOutput().printError("This should never happen! L_ENVDAM", e); } } @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onWaterBreak(BlockFromToEvent event) { if (!setting.PROTECTION.PROTECT_AGAINST_ENVIRONMENT) { return; } if (!setting.isEnabledIn(event.getBlock().getWorld())) { return; } OwnedBlock block = OwnedBlock.newInstance(event.getToBlock()); try { if (invalidAccess(block)) { event.setCancelled(true); } } catch (InvalidWorldNameException e) { // can't happen, since the OwnedBlock is backed by a bukkit Block getOutput().printError("This should never happen! L_ENVDAM", e); } } @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onPistonExtend(BlockPistonExtendEvent event) { if (!setting.PROTECTION.PROTECT_AGAINST_ENVIRONMENT) { return; } if (!setting.isEnabledIn(event.getBlock().getWorld())) { return; } OwnedBlock block; for (Block nativeBlock : event.getBlocks()) { block = OwnedBlock.newInstance(nativeBlock); try { if (invalidAccess(block)) { event.setCancelled(true); return; } } catch (InvalidWorldNameException e) { // can't happen, since the OwnedBlock is backed by a bukkit Block getOutput().printError("This should never happen! L_ENVDAM", e); } } } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onBlockExploded(EntityExplodeEvent event) { if (!setting.PROTECTION.PROTECT_AGAINST_ENVIRONMENT) { return; } if (!setting.isEnabledIn(event.getEntity().getWorld())) { return; } Iterator<Block> iterator = event.blockList().iterator(); OwnedBlock block; while (iterator.hasNext()) { block = OwnedBlock.newInstance(iterator.next()); try { if (invalidAccess(block)) { iterator.remove(); } } catch (InvalidWorldNameException e) { // can't happen, since the OwnedBlock is backed by a bukkit Block getOutput().printError("This should never happen! L_ENVDAM", e); } } } @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onEntityTrample(EntityChangeBlockEvent event) { if (!setting.PROTECTION.PROTECT_AGAINST_ENVIRONMENT) { return; } if (!setting.isEnabledIn(event.getEntity().getWorld())) { return; } if (!(event.getEntity() instanceof HumanEntity)) { OwnedBlock block = OwnedBlock.newInstance(event.getBlock()); try { if (invalidAccess(block)) { event.setCancelled(true); } } catch (InvalidWorldNameException e) { // can't happen, since the OwnedBlock is backed by a bukkit Block getOutput().printError("This should never happen! L_ENVDAM", e); } } } private boolean invalidAccess(@Nonnull Ownable ownable) throws InvalidWorldNameException { if (setting.isOwnEnabled(ownable.getMaterial())) { Optional<User> owner = database.getOwner(ownable); if (owner.isPresent()) { if (protection.isListed(owner.get(), ownable.getMaterial())) { return true; } } } if (ownable instanceof OwnedBlock) { Block block = ((OwnedBlock) ownable).getBlock(); for (Block attachedBlock : getAttachedBlocks(block)) { OwnedBlock attachedOwned = OwnedBlock.newInstance(attachedBlock); Optional<User> attachedOwner = database.getOwner(attachedOwned); if (!attachedOwner.isPresent()) { continue; } if (protection.isListed(attachedOwner.get(), attachedOwned.getMaterial())) { return true; } } } return false; } private boolean isProtectedDamageCause(DamageCause cause) { return ENVIRONMENT_DAMAGES.contains(cause); } }