package com.nicewuerfel.blockown.event;
import com.google.common.base.Optional;
import com.nicewuerfel.blockown.InvalidWorldNameException;
import com.nicewuerfel.blockown.Message;
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.database.DatabaseAction;
import com.nicewuerfel.blockown.protection.Protection;
import com.nicewuerfel.blockown.protection.ProtectionCause;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockFadeEvent;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.LeavesDecayEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.hanging.HangingBreakEvent;
import java.util.Iterator;
public class L_BlockBreak extends Listener {
public L_BlockBreak(Setting setting, Database database, Protection protection) {
super(setting, database, protection);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) {
if (!setting.isEnabledIn(event.getBlock().getWorld())) {
return;
}
OwnedBlock block = OwnedBlock.newInstance(event.getBlock());
unown(block);
for (Block attachedBlock : getAttachedBlocks(event.getBlock())) {
unown(OwnedBlock.newInstance(attachedBlock));
}
}
/*
* Handle blocks that have a block on top which would get dropped if the block breaks
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockBreakBefore(BlockBreakEvent event) {
if (!setting.isEnabledIn(event.getBlock().getWorld())) {
return;
}
User user = User.getInstance(event.getPlayer().getUniqueId(), event.getPlayer());
for (Block block : getAttachedBlocks(event.getBlock())) {
OwnedBlock owned = OwnedBlock.newInstance(block);
Optional<User> owner = database.getOwner(owned);
if (!owner.isPresent()) {
continue;
}
try {
ProtectionCause cause = user.getAccess(owned.getMaterial(), owner.get());
if (cause != ProtectionCause.NONE) {
if (setting.PROTECTION.ENABLE_MESSAGES) {
event.getPlayer()
.sendMessage(cause.getMessage(Message.BLOCK.getMessage(), owner.get().getName()));
}
event.setCancelled(true);
return;
}
} catch (InvalidWorldNameException e) {
// can't happen, since the OwnedBlock is backed by a Bukkit Block
setting.getOutput().printError("This should never happen! L_BLOCKBREAK", e);
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onHangingBreak(HangingBreakEvent event) {
if (!setting.isEnabledIn(event.getEntity().getWorld())) {
return;
}
OwnedEntity entity = OwnedEntity.newInstance(event.getEntity());
unown(entity);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onDeath(EntityDeathEvent event) {
if (!setting.isEnabledIn(event.getEntity().getWorld())) {
return;
}
OwnedEntity entity = OwnedEntity.newInstance(event.getEntity());
unown(entity);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPhysics(BlockPhysicsEvent event) {
if (setting.isEnabledIn(event.getBlock().getWorld())) {
org.bukkit.Material material = event.getChangedType();
if (material == org.bukkit.Material.SAND || material == org.bukkit.Material.GRAVEL) {
OwnedBlock block = OwnedBlock.newInstance(event.getBlock());
unown(block);
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onFade(BlockFadeEvent event) {
if (!setting.isEnabledIn(event.getBlock().getWorld())) {
return;
}
OwnedBlock block = OwnedBlock.newInstance(event.getBlock());
unown(block);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onLeavesDecay(LeavesDecayEvent event) {
if (!setting.isEnabledIn(event.getBlock().getWorld())) {
return;
}
OwnedBlock block = OwnedBlock.newInstance(event.getBlock());
unown(block);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockBurn(BlockBurnEvent event) {
if (!setting.isEnabledIn(event.getBlock().getWorld())) {
return;
}
OwnedBlock block = OwnedBlock.newInstance(event.getBlock());
unown(block);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockExploded(EntityExplodeEvent event) {
if (!setting.isEnabledIn(event.getEntity().getWorld())) {
return;
}
Iterator<Block> iterator = event.blockList().iterator();
OwnedBlock block;
while (iterator.hasNext()) {
block = OwnedBlock.newInstance(iterator.next());
unown(block);
}
}
private void unown(Ownable ownable) {
DatabaseAction databaseAction = DatabaseAction.newUnownInstance(ownable);
database.enqueue(databaseAction);
}
}