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);
}
}