package com.nicewuerfel.blockown.event;
import com.google.common.base.Optional;
import com.nicewuerfel.blockown.InvalidWorldNameException;
import com.nicewuerfel.blockown.OwnedBlock;
import com.nicewuerfel.blockown.OwnedEntity;
import com.nicewuerfel.blockown.Permission;
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 org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockGrowEvent;
import org.bukkit.event.block.BlockMultiPlaceEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.world.StructureGrowEvent;
public class L_BlockPlace extends Listener {
public L_BlockPlace(Setting setting, Database database, Protection protection) {
super(setting, database, protection);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent event) {
Player player = event.getPlayer();
if (setting.isEnabledIn(player.getWorld())) {
if (player.hasPermission(Permission.OWN_PLACE.toString())) {
User user = User.getInstance(player.getUniqueId());
if (!setting.isOwning(user)) {
return;
}
OwnedBlock block = OwnedBlock.newInstance(event.getBlock());
try {
if (setting.isOwnEnabled(block.getMaterial())) {
DatabaseAction databaseAction = DatabaseAction.newOwnInstance(block, user);
database.enqueue(databaseAction);
}
} catch (InvalidWorldNameException e) {
// can't happen, since the OwnedBlock is backed by a bukkit Block
getOutput().printError("This should never happen! L_BLOCKPLACE", e);
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onHangingPlace(HangingPlaceEvent event) {
if (setting.isEnabledIn(event.getBlock().getWorld())) {
if (event.getPlayer().hasPermission(Permission.OWN_PLACE.toString())) {
User owner = User.getInstance(event.getPlayer().getUniqueId());
if (!setting.isOwning(owner)) {
return;
}
OwnedEntity entity = OwnedEntity.newInstance(event.getEntity());
try {
if (setting.isOwnEnabled(entity.getMaterial())) {
DatabaseAction databaseAction = DatabaseAction.newOwnInstance(entity, owner);
database.enqueue(databaseAction);
}
} catch (InvalidWorldNameException e) {
// can't happen, since the OwnedEntity is backed by a bukkit Entity
getOutput().printError("This should never happen! L_BLOCKPLACE", e);
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockMultiPlace(BlockMultiPlaceEvent event) {
Player player = event.getPlayer();
if (setting.isEnabledIn(player.getWorld())) {
if (player.hasPermission(Permission.OWN_PLACE.toString())) {
User user = User.getInstance(player.getUniqueId());
if (!setting.isOwning(user)) {
return;
}
OwnedBlock block;
DatabaseAction databaseAction;
for (BlockState state : event.getReplacedBlockStates()) {
block = OwnedBlock.newInstance(state.getBlock());
try {
if (setting.isOwnEnabled(block.getMaterial())) {
databaseAction = DatabaseAction.newOwnInstance(block, user);
database.enqueue(databaseAction);
}
} catch (InvalidWorldNameException e) {
// can't happen, since the OwnedBlock is backed by a bukkit Block
setting.getOutput().printError("This should never happen! L_BLOCKPLACE", e);
}
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onStructureGrow(StructureGrowEvent event) {
if (setting.isEnabledIn(event.getWorld())) {
OwnedBlock block = OwnedBlock.newInstance(event.getLocation().getBlock());
Optional<User> owner = database.getOwner(block);
if (!owner.isPresent()) {
return;
}
DatabaseAction databaseAction;
for (BlockState state : event.getBlocks()) {
block = OwnedBlock.newInstance(state.getBlock());
databaseAction = DatabaseAction.newOwnInstance(block, owner.get());
database.enqueue(databaseAction);
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockGrow(BlockGrowEvent event) {
if (setting.isEnabledIn(event.getBlock().getWorld())) {
Material material = event.getNewState().getType();
if (material == Material.SUGAR_CANE_BLOCK || material == Material.CACTUS) {
Block lowerBlock = event.getBlock().getRelative(BlockFace.DOWN);
OwnedBlock lowerOwned = OwnedBlock.newInstance(lowerBlock);
Optional<User> owner = database.getOwner(lowerOwned);
if (owner.isPresent()) {
OwnedBlock owned = OwnedBlock.newInstance(event.getBlock());
DatabaseAction databaseAction = DatabaseAction.newOwnInstance(owned, owner.get());
database.enqueue(databaseAction);
}
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockPlaceNearChest(BlockPlaceEvent event) {
Player player = event.getPlayer();
Block block = event.getBlock();
if (setting.isEnabledIn(player.getWorld())) {
if (block.getType() != org.bukkit.Material.CHEST
&& block.getType() != org.bukkit.Material.HOPPER) {
return;
}
User user = User.getInstance(event.getPlayer().getUniqueId());
Block blockEast = block.getRelative(BlockFace.EAST);
if (blockEast.getType() == org.bukkit.Material.CHEST) {
if (invalidPlacement(blockEast, user)) {
event.setCancelled(true);
return;
}
}
Block blockWest = block.getRelative(BlockFace.WEST);
if (blockWest.getType() == org.bukkit.Material.CHEST) {
if (invalidPlacement(blockWest, user)) {
event.setCancelled(true);
return;
}
}
Block blockNorth = block.getRelative(BlockFace.NORTH);
if (blockNorth.getType() == org.bukkit.Material.CHEST) {
if (invalidPlacement(blockNorth, user)) {
event.setCancelled(true);
return;
}
}
Block blockSouth = block.getRelative(BlockFace.SOUTH);
if (blockSouth.getType() == org.bukkit.Material.CHEST) {
if (invalidPlacement(blockSouth, user)) {
event.setCancelled(true);
return;
}
}
if (block.getType() == org.bukkit.Material.HOPPER) {
Block blockBelow = block.getRelative(BlockFace.DOWN);
if (blockBelow.getType() == org.bukkit.Material.CHEST) {
if (invalidPlacement(blockBelow, user)) {
event.setCancelled(true);
return;
}
}
Block blockAbove = block.getRelative(BlockFace.UP);
if (blockAbove.getType() == org.bukkit.Material.CHEST) {
if (invalidPlacement(blockAbove, user)) {
event.setCancelled(true);
return;
}
}
}
}
}
/**
* Checks whether a user is allowed to place a block near the given block
*
* @param nativeBlock the block
* @param user the user
* @return whether the placement is invalid
*/
private boolean invalidPlacement(Block nativeBlock, User user) {
OwnedBlock block = OwnedBlock.newInstance(nativeBlock);
Optional<User> owner = database.getOwner(block);
if (!owner.isPresent()) {
return false;
}
if (owner.get().equals(user)) {
return false;
}
try {
boolean result;
result = protection.isListed(owner.get(), block.getMaterial());
return result;
} catch (InvalidWorldNameException e) {
// can't happen, since the OwnedBlock is backed by a bukkit Block
setting.getOutput().printError("This should never happen! L_BLOCKPLACE", e);
return true;
}
}
}