diff --git a/README.md b/README.md index 278ea07..3134419 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,10 @@ This plugin will clear a player's items when they enter or leave, or teleport to This is mainly useful if players are able to temporarily go in creative mode in specific WorldGuard regions. A lot of additional things are blocked within clear regions in order to prevent creative mode abuse, such as: projectiles, XP bottle usage, spawn egg usage, changing the mob in a spawner, dropping items, picking up items, breaking, placing or -interacting with blocks across clear region borders, block drops, pistons pushing or pulling across clear region -borders, TNT priming and keeping any inventory items if dying within a clear area. This list might not be exhaustive. +interacting with blocks across clear region borders, block drops, mob drops, pistons pushing or pulling across clear +region borders, dispenser dispensers, droppers, armor dispensing, blocks burning, blocks igniting (except flint and +steel), creepers exploding, TNT priming and keeping any inventory items if dying within a clear area. This list might +not be exhaustive. ## Dependencies diff --git a/src/main/java/net/knarcraft/clearonworldguard/WorldGuardListener.java b/src/main/java/net/knarcraft/clearonworldguard/WorldGuardListener.java index 82af017..33a26ec 100644 --- a/src/main/java/net/knarcraft/clearonworldguard/WorldGuardListener.java +++ b/src/main/java/net/knarcraft/clearonworldguard/WorldGuardListener.java @@ -15,17 +15,32 @@ import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockDispenseArmorEvent; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.block.BlockDropItemEvent; +import org.bukkit.event.block.BlockExpEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockIgniteEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.BlockSpreadEvent; import org.bukkit.event.block.TNTPrimeEvent; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.player.PlayerDropItemEvent; @@ -187,10 +202,115 @@ public class WorldGuardListener implements Listener { } } - // TODO: Prevent creepers from blowing up - // TODO: Prevent ignition of anything except netherrack and soul sand/soil - // TODO: Prevent dispensers from dispensing - // TODO: Prevent droppers from dropping + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onExplosionPrime(@NotNull ExplosionPrimeEvent event) { + Location location = event.getEntity().getLocation(); + float radius = event.getRadius(); + if (isInClearRegion(location) || + isInClearRegion(location.clone().add(radius, radius, radius)) || + isInClearRegion(location.clone().add(-radius, radius, radius)) || + isInClearRegion(location.clone().add(-radius, radius, -radius)) || + isInClearRegion(location.clone().add(radius, radius, -radius)) || + isInClearRegion(location.clone().add(radius, -radius, radius)) || + isInClearRegion(location.clone().add(-radius, -radius, radius)) || + isInClearRegion(location.clone().add(-radius, -radius, -radius)) || + isInClearRegion(location.clone().add(radius, -radius, -radius))) { + event.setCancelled(true); + event.getEntity().remove(); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onEntityExplode(@NotNull EntityExplodeEvent event) { + // Prevent explosions in clear regions + if (isInClearRegion(event.getEntity())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onEntityChangeBlock(@NotNull EntityChangeBlockEvent event) { + // Prevent entities from changing blocks in clear regions + if (isInClearRegion(event.getBlock())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onCreatureSpawn(@NotNull CreatureSpawnEvent event) { + // Prevent creatures from spawning + if (isInClearRegion(event.getLocation()) && event.getEntityType() != EntityType.ARMOR_STAND) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockItemDrop(@NotNull BlockDropItemEvent event) { + // Block item drops for indirectly destroyed items + if (isInClearRegion(event.getBlock())) { + event.getItems().clear(); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onBlockXP(@NotNull BlockExpEvent event) { + // Prevent dropping XP in clear regions + if (isInClearRegion(event.getBlock())) { + event.setExpToDrop(0); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onEntityDamage(@NotNull EntityDamageEvent event) { + // Prevent entity damage in clear regions + if (isInClearRegion(event.getEntity())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onDeath(@NotNull EntityDeathEvent event) { + // Prevent mob loot and XP + if (isInClearRegion(event.getEntity())) { + event.setDroppedExp(0); + event.getDrops().clear(); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onDispense(@NotNull BlockDispenseEvent event) { + // Prevent dispensers from dispensing and droppers from dropping + if (isInClearRegion(event.getBlock())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onArmorDispense(@NotNull BlockDispenseArmorEvent event) { + // Prevent dispensers from dispensing armors in clear regions + if (isInClearRegion(event.getBlock())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBurn(@NotNull BlockBurnEvent event) { + // Prevent blocks from burning in clear areas + Block block = event.getBlock(); + if (isInClearRegion(block)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onIgnite(@NotNull BlockIgniteEvent event) { + // Prevent ignition in clear areas, unless done by flint and steel + Block block = event.getBlock(); + if (isInClearRegion(block) && event.getCause() != BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL) { + event.setCancelled(true); + } + } @EventHandler(priority = EventPriority.HIGHEST) public void onDeath(@NotNull PlayerDeathEvent event) { @@ -214,6 +334,22 @@ public class WorldGuardListener implements Listener { } } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockSpread(@NotNull BlockSpreadEvent event) { + // Prevent block spread in clear regions + if (isInClearRegion(event.getSource())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockForm(@NotNull BlockFormEvent event) { + // Prevent block forming in clear regions + if (isInClearRegion(event.getBlock())) { + event.setCancelled(true); + } + } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onPistonExtend(@NotNull BlockPistonExtendEvent event) { // Prevent pistons from pushing blocks across the clear region border