/* ChunkClaim Plugin for Minecraft Bukkit Servers Copyright (C) 2012 Felix Schmidt This file is part of ChunkClaim. ChunkClaim is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ChunkClaim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with ChunkClaim. If not, see <http://www.gnu.org/licenses/>. */ package com.github.schmidtbochum.chunkclaim; import java.util.List; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Arrow; import org.bukkit.entity.Creature; import org.bukkit.entity.Enderman; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Item; import org.bukkit.entity.Monster; import org.bukkit.entity.Player; import org.bukkit.entity.ThrownPotion; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.event.entity.EntityBreakDoorEvent; import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityInteractEvent; import org.bukkit.event.entity.ExpBottleEvent; import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.entity.PotionSplashEvent; import org.bukkit.event.painting.PaintingBreakByEntityEvent; import org.bukkit.event.painting.PaintingBreakEvent; import org.bukkit.event.painting.PaintingPlaceEvent; import org.bukkit.event.vehicle.VehicleDamageEvent; public class EntityEventHandler implements Listener { private DataStore dataStore; public EntityEventHandler(DataStore dataStore) { this.dataStore = dataStore; } //don't allow endermen to change blocks @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onEntityChangeBLock(EntityChangeBlockEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getBlock().getWorld().getName())) return; if(event.getEntityType() == EntityType.ENDERMAN) event.setCancelled(true); } //don't allow zombies to break down doors @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onZombieBreakDoor(EntityBreakDoorEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getBlock().getWorld().getName())) return; event.setCancelled(true); } //don't allow entities to trample crops @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onEntityInteract(EntityInteractEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getBlock().getWorld().getName())) return; if(event.getBlock().getType() == Material.SOIL) event.setCancelled(true); } //when an entity explodes... @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onEntityExplode(EntityExplodeEvent explodeEvent) { if(!ChunkClaim.plugin.config_worlds.contains(explodeEvent.getLocation().getWorld().getName())) return; List<Block> blocks = explodeEvent.blockList(); for(int i = 0; i < blocks.size(); i++) { blocks.remove(i--); } } //when an item spawns... @EventHandler(priority = EventPriority.LOWEST) public void onItemSpawn(ItemSpawnEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getEntity().getWorld().getName())) return; Entity entity = event.getEntity(); Item item = (Item) entity; Material material = item.getItemStack().getType(); //allow dropping books. levers for chairs plugin if(material == Material.WRITTEN_BOOK || material == Material.BOOK_AND_QUILL || material == Material.LEVER){ return; } else { //ChunkClaim.addLogEntry("Item spawn cancelled."); event.setCancelled(true); } } //when an experience bottle explodes... @EventHandler(priority = EventPriority.LOWEST) public void onExpBottle(ExpBottleEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getEntity().getWorld().getName())) return; event.setExperience(0); } //when a creature spawns... @EventHandler(priority = EventPriority.LOWEST) public void onEntitySpawn(CreatureSpawnEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getEntity().getWorld().getName())) return; SpawnReason reason = event.getSpawnReason(); if(reason != SpawnReason.SPAWNER_EGG) event.setCancelled(true); } //when an entity dies... @EventHandler public void onEntityDeath(EntityDeathEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getEntity().getWorld().getName())) return; event.setDroppedExp(0); event.getDrops().clear(); } /* //when an entity picks up an item @EventHandler(priority = EventPriority.LOWEST) public void onEntityPickup(EntityChangeBlockEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getEntity().getWorld().getName())) return; if(event.getEntity() instanceof Enderman) { event.setCancelled(true); } } */ //when a painting is broken @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPaintingBreak(PaintingBreakEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getPainting().getWorld().getName())) return; if(!(event instanceof PaintingBreakByEntityEvent)) { event.setCancelled(true); return; } PaintingBreakByEntityEvent entityEvent = (PaintingBreakByEntityEvent)event; //who is removing it? Entity remover = entityEvent.getRemover(); //again, making sure the breaker is a player if(!(remover instanceof Player)) { event.setCancelled(true); return; } Chunk chunk = this.dataStore.getChunkAt(event.getPainting().getLocation(), null); if(chunk==null) { event.setCancelled(true); return; } if(!chunk.isTrusted(((Player) remover).getName())) { event.setCancelled(true); ChunkClaim.plugin.sendMsg(((Player) remover),"You don't have " + chunk.ownerName + "'s permission to build here."); return; } } //when a painting is placed @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPaintingPlace(PaintingPlaceEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getPlayer().getWorld().getName())) return; Player player = event.getPlayer(); Chunk chunk = this.dataStore.getChunkAt(event.getPainting().getLocation(), null); if(chunk==null) { event.setCancelled(true); return; } if(!chunk.isTrusted(player.getName())) { event.setCancelled(true); ChunkClaim.plugin.sendMsg(player,"You don't have " + chunk.ownerName + "'s permission to build here."); return; } } //when an entity is damaged @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onEntityDamage (EntityDamageEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getEntity().getWorld().getName())) return; //only actually interested in entities damaging entities (ignoring environmental damage) if(!(event instanceof EntityDamageByEntityEvent)) return; //monsters are never protected if(event.getEntity() instanceof Monster) return; EntityDamageByEntityEvent subEvent = (EntityDamageByEntityEvent) event; //determine which player is attacking, if any Player attacker = null; Arrow arrow = null; Entity damageSource = subEvent.getDamager(); if(damageSource instanceof Player) { attacker = (Player)damageSource; } else if(damageSource instanceof Arrow) { arrow = (Arrow)damageSource; if(arrow.getShooter() instanceof Player) { attacker = (Player)arrow.getShooter(); } } else if(damageSource instanceof ThrownPotion) { ThrownPotion potion = (ThrownPotion)damageSource; if(potion.getShooter() instanceof Player) { attacker = (Player)potion.getShooter(); } } //FEATURE: protect claimed animals, boats, minecarts if(event instanceof EntityDamageByEntityEvent) { //if the entity is an non-monster creature (remember monsters disqualified above), or a vehicle if ((subEvent.getEntity() instanceof Creature)) { Chunk cachedChunk = null; PlayerData playerData = null; if(attacker != null) { playerData = this.dataStore.getPlayerData(attacker.getName()); cachedChunk = playerData.lastChunk; } Chunk chunk = dataStore.getChunkAt(event.getEntity().getLocation(), cachedChunk); //if it's claimed if(chunk != null) { if(attacker == null) { event.setCancelled(true); } else { if(!chunk.isTrusted(attacker.getName())) { event.setCancelled(true); ChunkClaim.plugin.sendMsg(attacker,"Not permitted."); } //cache claim for later if(playerData != null) { playerData.lastChunk = chunk; } } } } } } //when an entity is damaged @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onPotionSplash (PotionSplashEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getEntity().getWorld().getName())) return; event.setCancelled(true); } //when a vehicle is damaged @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onVehicleDamage (VehicleDamageEvent event) { if(!ChunkClaim.plugin.config_worlds.contains(event.getVehicle().getWorld().getName())) return; //determine which player is attacking, if any Player attacker = null; Arrow arrow = null; Entity damageSource = event.getAttacker(); if(damageSource instanceof Player) { attacker = (Player)damageSource; } else if(damageSource instanceof Arrow) { arrow = (Arrow)damageSource; if(arrow.getShooter() instanceof Player) { attacker = (Player)arrow.getShooter(); } } else if(damageSource instanceof ThrownPotion) { ThrownPotion potion = (ThrownPotion)damageSource; if(potion.getShooter() instanceof Player) { attacker = (Player)potion.getShooter(); } } Chunk cachedChunk = null; PlayerData playerData = null; if(attacker != null) { playerData = this.dataStore.getPlayerData(attacker.getName()); cachedChunk = playerData.lastChunk; } Chunk chunk = dataStore.getChunkAt(event.getVehicle().getLocation(), cachedChunk); //if it's claimed if(chunk != null) { if(attacker == null) { event.setCancelled(true); } else { if(!chunk.isTrusted(attacker.getName())) { event.setCancelled(true); ChunkClaim.plugin.sendMsg(attacker,"Not permitted."); } //cache claim for later if(playerData != null) { playerData.lastChunk = chunk; } } } } }