diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..2e16cba --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,33 @@ +pipeline { + agent any + tools { + jdk 'JDK17' + } + stages { + stage('Build') { + steps { + echo 'Building...' + sh 'mvn clean & mvn validate & mvn compile' + } + } + stage('Test') { + steps { + echo 'Testing...' + sh 'mvn test' + } + } + stage('Verify') { + steps { + echo 'Verifying...' + sh 'mvn verify -Dmaven.test.skip=true' + } + } + stage('Deploy') { + steps { + echo 'Deploying...' + sh 'mvn deploy -Dmaven.install.skip=true -Dmaven.test.skip=true' + archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true + } + } + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index dd8e4bc..8cafa86 100644 --- a/pom.xml +++ b/pom.xml @@ -65,13 +65,27 @@ sk89q-repo https://maven.enginehub.org/repo/ + + knarcraft-repo + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + + + + knarcraft-repo + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + + + knarcraft-repo + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + + org.spigotmc spigot-api - 1.20.1-R0.1-SNAPSHOT + 1.21.10-R0.1-SNAPSHOT provided @@ -86,5 +100,11 @@ 24.0.1 compile + + net.knarcraft + knarlib + 1.2.3 + compile + diff --git a/src/main/java/net/knarcraft/clearonworldguard/ClearOnWorldGuard.java b/src/main/java/net/knarcraft/clearonworldguard/ClearOnWorldGuard.java index 9448e81..f47d79a 100644 --- a/src/main/java/net/knarcraft/clearonworldguard/ClearOnWorldGuard.java +++ b/src/main/java/net/knarcraft/clearonworldguard/ClearOnWorldGuard.java @@ -1,6 +1,7 @@ package net.knarcraft.clearonworldguard; import net.knarcraft.clearonworldguard.config.Configuration; +import net.knarcraft.clearonworldguard.config.ProtectionManager; import net.knarcraft.clearonworldguard.listener.BlockListener; import net.knarcraft.clearonworldguard.listener.ClearRegionListener; import net.knarcraft.clearonworldguard.listener.EntityListener; @@ -20,6 +21,7 @@ import java.util.logging.Logger; public final class ClearOnWorldGuard extends JavaPlugin { private static ClearOnWorldGuard instance; + private ProtectionManager protectionManager; private boolean debugMode; @Override @@ -28,13 +30,15 @@ public final class ClearOnWorldGuard extends JavaPlugin { this.saveDefaultConfig(); this.reloadConfig(); FileConfiguration fileConfiguration = this.getConfig(); + protectionManager = new ProtectionManager("protection"); + protectionManager.load(fileConfiguration); // Register the WorldGuard listener Configuration configuration = new Configuration(fileConfiguration); - Bukkit.getPluginManager().registerEvents(new PlayerListener(configuration), this); - Bukkit.getPluginManager().registerEvents(new EntityListener(configuration), this); - Bukkit.getPluginManager().registerEvents(new BlockListener(configuration), this); - Bukkit.getPluginManager().registerEvents(new ClearRegionListener(configuration), this); + Bukkit.getPluginManager().registerEvents(new PlayerListener(configuration, protectionManager), this); + Bukkit.getPluginManager().registerEvents(new EntityListener(configuration, protectionManager), this); + Bukkit.getPluginManager().registerEvents(new BlockListener(configuration, protectionManager), this); + Bukkit.getPluginManager().registerEvents(new ClearRegionListener(configuration, protectionManager), this); this.debugMode = configuration.debugEnabled(); } @@ -69,4 +73,13 @@ public final class ClearOnWorldGuard extends JavaPlugin { return instance; } + /** + * Gets the protection manager + * + * @return

The protection manager

+ */ + public ProtectionManager getProtectionManager() { + return protectionManager; + } + } diff --git a/src/main/java/net/knarcraft/clearonworldguard/config/BlockIgniteProtection.java b/src/main/java/net/knarcraft/clearonworldguard/config/BlockIgniteProtection.java new file mode 100644 index 0000000..46ee6fd --- /dev/null +++ b/src/main/java/net/knarcraft/clearonworldguard/config/BlockIgniteProtection.java @@ -0,0 +1,24 @@ +package net.knarcraft.clearonworldguard.config; + +import net.knarcraft.clearonworldguard.ClearOnWorldGuard; +import org.bukkit.Material; +import org.bukkit.event.block.BlockIgniteEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; + +public class BlockIgniteProtection { + + private Set exemptIgniteCauses; + private Set exemptMaterials; + + public BlockIgniteProtection() { + + } + + + +} diff --git a/src/main/java/net/knarcraft/clearonworldguard/config/EnvironmentProtection.java b/src/main/java/net/knarcraft/clearonworldguard/config/EnvironmentProtection.java new file mode 100644 index 0000000..8006bfd --- /dev/null +++ b/src/main/java/net/knarcraft/clearonworldguard/config/EnvironmentProtection.java @@ -0,0 +1,130 @@ +package net.knarcraft.clearonworldguard.config; + +import org.jetbrains.annotations.NotNull; + +/** + * Protections that don't directly involve a player, but protects everything in clear region areas + */ +public enum EnvironmentProtection implements Protection { + + /** + * Prevents creatures from spawning in clear regions + */ + CREATURE_SPAWN("creatureSpawning", true), + + /** + * Prevents droppers or dispensers from dispensing an item + */ + DISPENSE_ITEM("dispenseItem", true), + + /** + * Prevents dispensers from dispensing armor + */ + DISPENSE_ARMOR("dispenseArmor", true), + + /** + * Prevents blocks from burning + */ + BLOCK_BURN("blockBurn", true), + + /** + * Prevents blocks from dropping xp + */ + BLOCK_XP("blockXp", true), + + /** + * Prevents blocks from spreading + */ + BLOCK_SPREAD("blockSpread", false), + + /** + * Prevents blocks from forming + */ + BLOCK_FORM("entityBlockForm", true), + + /** + * Prevents pistons from extending across clear region borders + */ + PISTON_EXTEND_BORDER("pistonExtendBorder", true), + + /** + * Prevents pistons from retracting across clear region borders + */ + PISTON_RETRACT_BORDER("pistonRetractBorder", true), + + /** + * Prevents block from exploding + */ + BLOCK_EXPLODE("blockExplode", true), + + /** + * Prevents entities from priming + */ + EXPLOSION_PRIME("explosionPrime", true), + + /** + * Prevents entities from exploding + */ + ENTITY_EXPLODE("entityExplode", true), + + /** + * Prevents entities from dropping items on death + */ + ENTITY_DEATH_DROPS("entityDeathDrops", true), + + /** + * Prevents projectiles from being launched + */ + PROJECTILE_LAUNCH("projectileLaunch", true), + + /** + * Prevents entities from combusting + */ + ENTITY_COMBUST("entityCombust", false), + + /** + * Prevents entities from spawning + */ + ENTITY_SPAWN("entitySpawn", false), + + /** + * Prevents spawners from spawning creatures + */ + SPAWNER_SPAWN("spawnerSpawn", false), + + /** + * Prevents dropped items from spawning + */ + ITEM_SPAWN("itemSpawn", true), + ; + + private final String path; + private final boolean defaultEnabled; + + /** + * Instantiates a new area protection + * + * @param path

The relative path of this protection in the configuration file

+ * @param defaultEnabled

Whether this protection is enabled by default

+ */ + EnvironmentProtection(@NotNull String path, boolean defaultEnabled) { + this.path = path; + this.defaultEnabled = defaultEnabled; + } + + @Override + public @NotNull String getPath() { + return this.path; + } + + @Override + public boolean isDefaultEnabled() { + return this.defaultEnabled; + } + + @Override + public @NotNull String getRootNode() { + return "environment"; + } + +} diff --git a/src/main/java/net/knarcraft/clearonworldguard/config/PlayerProtection.java b/src/main/java/net/knarcraft/clearonworldguard/config/PlayerProtection.java new file mode 100644 index 0000000..93ca757 --- /dev/null +++ b/src/main/java/net/knarcraft/clearonworldguard/config/PlayerProtection.java @@ -0,0 +1,151 @@ +package net.knarcraft.clearonworldguard.config; + +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +/** + * Protections that might involve a player, and can be bypassed with a permission + */ +public enum PlayerProtection implements Protection { + + /** + * Prevents creature leashing in clear regions + */ + LEASHING("leashing", true), + + /** + * Prevents players from picking up items in clear regions + */ + ITEM_PICKUP("itemPickup", true), + + /** + * Prevent players from dropping items in clear regions + */ + ITEM_DROP("itemDrop", true), + + /** + * Prevents players from accessing ender chests in clear regions + */ + ENDER_CHEST("enderChest", true), + + /** + * Prevents usage of spawn eggs in clear regions + */ + SPAWN_EGG("spawnEgg", true), + + /** + * Prevents blocks from being ignited in clear regions + */ + BLOCK_IGNITE("blockIgnite", true), + + /** + * Prevents blocks from forming in clear regions + */ + ENTITY_BLOCK_FORM("blockForm", false), + + /** + * Prevents placement of blocks across a clear region border + */ + BLOCK_PLACE_BORDER("blockPlaceBorder", true), + + /** + * Prevents breaking of blocks across a clear region border + */ + BLOCK_BREAK_BORDER("blockBreakBorder", true), + + /** + * Prevents a block from dropping as an item in clear regions + */ + BLOCK_DROP_ITEM("blockDropItem", true), + + /** + * Prevents TNT from priming in clear regions + */ + TNT_PRIME("tntPrime", true), + + /** + * Prevents an entity from mounting another entity in clear regions + */ + ENTITY_MOUNT("entityMount", true), + + /** + * Prevents an entity from changing a block in clear regions + */ + ENTITY_CHANGE_BLOCK("entityChangeBlock", true), + + /** + * Prevents entities from damaging entities across clear region borders + */ + ENTITY_DAMAGE_ENTITY_BORDER("entityDamageBorder", true), + + /** + * Prevents entities from damaging other entities in clear regions + */ + ENTITY_DAMAGE_ENTITY("entityDamage", true), + + /** + * Prevents entities from being damaged by blocks in clear regions + */ + ENTITY_DAMAGE_BLOCK("entityDamageBlock", true), + + /** + * Deletes vehicles destroyed in clear regions + */ + VEHICLE_DESTROY_DELETE("vehicleDestroyDelete", true), + + /** + * Deletes vehicles leaving a clear region + */ + VEHICLE_BORDER_DELETE("vehicleBorderDelete", true), + + /** + * Clears a player's inventory, and makes players keep their XP when dying in a clear region + */ + PLAYER_DEATH_CLEAR("playerDeathClear", true), + + /** + * Prevents players from dropping items in creative mode + */ + CREATIVE_DROP("creativeItemDrop", true), + ; + + private final String path; + private final boolean defaultEnabled; + + /** + * Instantiates a new player protection + * + * @param path

The relative path of this protection in the configuration file

+ * @param defaultEnabled

Whether this protection is enabled by default

+ */ + PlayerProtection(@NotNull String path, boolean defaultEnabled) { + this.path = path; + this.defaultEnabled = defaultEnabled; + } + + @Override + public @NotNull String getPath() { + return this.path; + } + + @Override + public boolean isDefaultEnabled() { + return this.defaultEnabled; + } + + @Override + public @NotNull String getRootNode() { + return "player"; + } + + /** + * Checks whether the given player has the permission to bypass this protection + * + * @param player

The player to check

+ * @return

True if the player can bypass this protection

+ */ + public boolean hasBypassPermission(@NotNull Player player) { + return player.hasPermission("clearonworldguard.bypass." + getPath()); + } + +} diff --git a/src/main/java/net/knarcraft/clearonworldguard/config/Protection.java b/src/main/java/net/knarcraft/clearonworldguard/config/Protection.java new file mode 100644 index 0000000..fb21080 --- /dev/null +++ b/src/main/java/net/knarcraft/clearonworldguard/config/Protection.java @@ -0,0 +1,31 @@ +package net.knarcraft.clearonworldguard.config; + +import org.jetbrains.annotations.NotNull; + +/** + * A protection option + */ +public interface Protection { + + /** + * Gets the relative path of this protection's configuration key + * + * @return

The relative configuration path

+ */ + @NotNull String getPath(); + + /** + * Gets whether this protection is enabled by default + * + * @return

True if this protection is enabled by default

+ */ + boolean isDefaultEnabled(); + + /** + * Gets the configuration file root node used for all protections of this type + * + * @return

The configuration file root node

+ */ + @NotNull String getRootNode(); + +} diff --git a/src/main/java/net/knarcraft/clearonworldguard/config/ProtectionManager.java b/src/main/java/net/knarcraft/clearonworldguard/config/ProtectionManager.java new file mode 100644 index 0000000..a340305 --- /dev/null +++ b/src/main/java/net/knarcraft/clearonworldguard/config/ProtectionManager.java @@ -0,0 +1,99 @@ +package net.knarcraft.clearonworldguard.config; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * A manager that keeps track of protections + */ +public class ProtectionManager { + + private final Map protectionStatus = new HashMap<>(); + private final String enabledKey = ".enabled"; + private final String rootNode; + + /** + * Instantiates a new protection manager + * + * @param rootNode

The root node to load protections from

+ */ + public ProtectionManager(@NotNull String rootNode) { + this.rootNode = rootNode; + } + + /** + * Loads the given file configuration + * + * @param configuration

The file configuration to load

+ */ + public void load(@NotNull FileConfiguration configuration) { + this.protectionStatus.clear(); + + load(configuration, PlayerProtection.values()); + load(configuration, EnvironmentProtection.values()); + + //TODO: Load specific clear region overrides as well + } + + /** + * Loads the given protection values + * + * @param configuration

The configuration file to load protections from

+ * @param protections

The protections to load

+ */ + private void load(@NotNull FileConfiguration configuration, @NotNull Protection[] protections) { + for (Protection playerProtection : protections) { + protectionStatus.put(playerProtection, configuration.getBoolean(getEnabledNode(playerProtection), + playerProtection.isDefaultEnabled())); + } + } + + /** + * Saves to the given file configuration + * + * @param configuration

The file configuration to save to

+ */ + public void save(@NotNull FileConfiguration configuration) { + for (Map.Entry protectionEntry : protectionStatus.entrySet()) { + Protection protection = protectionEntry.getKey(); + configuration.set(getEnabledNode(protection), protectionStatus.get(protection)); + } + } + + /** + * Checks whether the given protection is currently enabled + * + * @param protection

The protection to check

+ * @return

True if the protection is enabled

+ */ + public boolean isEnabled(@NotNull Protection protection) { + Boolean status = protectionStatus.get(protection); + return status != null && status; + } + + /** + * Gets whether the given player can bypass the given permission + * + * @param player

The player to check

+ * @param playerProtection

The player protection to check

+ * @return

True if the player is able to bypass the protection

+ */ + public boolean canBypass(@NotNull Player player, @NotNull PlayerProtection playerProtection) { + return playerProtection.hasBypassPermission(player); + } + + /** + * Gets the configuration node required to check the enabled state of the given protection + * + * @param protection

The protection to get the configuration node for

+ * @return

The string path of the configuration node

+ */ + private @NotNull String getEnabledNode(@NotNull Protection protection) { + return rootNode + "." + protection.getRootNode() + "." + protection.getPath() + enabledKey; + } + +} diff --git a/src/main/java/net/knarcraft/clearonworldguard/listener/BlockListener.java b/src/main/java/net/knarcraft/clearonworldguard/listener/BlockListener.java index 91cf782..02673e2 100644 --- a/src/main/java/net/knarcraft/clearonworldguard/listener/BlockListener.java +++ b/src/main/java/net/knarcraft/clearonworldguard/listener/BlockListener.java @@ -2,6 +2,7 @@ package net.knarcraft.clearonworldguard.listener; import net.knarcraft.clearonworldguard.ClearOnWorldGuard; import net.knarcraft.clearonworldguard.config.Configuration; +import net.knarcraft.clearonworldguard.config.ProtectionManager; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.event.EventHandler; @@ -12,12 +13,14 @@ 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.BlockExplodeEvent; 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.EntityBlockFormEvent; import org.bukkit.event.block.TNTPrimeEvent; import org.jetbrains.annotations.NotNull; @@ -31,10 +34,11 @@ public class BlockListener extends WorldGuardListener { /** * Instantiates a new WorldGuard listener * - * @param configuration

The configuration to get regions and settings from

+ * @param configuration

The configuration to get regions and settings from

+ * @param protectionManager

The protection manager to use for checking enabled protections

*/ - public BlockListener(@NotNull Configuration configuration) { - super(configuration); + public BlockListener(@NotNull Configuration configuration, @NotNull ProtectionManager protectionManager) { + super(configuration, protectionManager); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -180,4 +184,21 @@ public class BlockListener extends WorldGuardListener { } } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onEntityBlockForm(@NotNull EntityBlockFormEvent event) { + // Prevent blocks from forming + if (isInClearRegion(event.getBlock())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockExplode(@NotNull BlockExplodeEvent event) { + // Prevent explosions in clear regions + if (isInClearRegion(event.getBlock()) || isInClearRegion(event.blockList())) { + ClearOnWorldGuard.logDebugMessage("Prevented block " + event.getBlock() + " from exploding"); + event.setCancelled(true); + } + } + } diff --git a/src/main/java/net/knarcraft/clearonworldguard/listener/ClearRegionListener.java b/src/main/java/net/knarcraft/clearonworldguard/listener/ClearRegionListener.java index ddb1136..5b3a37b 100644 --- a/src/main/java/net/knarcraft/clearonworldguard/listener/ClearRegionListener.java +++ b/src/main/java/net/knarcraft/clearonworldguard/listener/ClearRegionListener.java @@ -3,6 +3,7 @@ package net.knarcraft.clearonworldguard.listener; import com.sk89q.worldguard.protection.regions.ProtectedRegion; import net.knarcraft.clearonworldguard.ClearOnWorldGuard; import net.knarcraft.clearonworldguard.config.Configuration; +import net.knarcraft.clearonworldguard.config.ProtectionManager; import net.knarcraft.clearonworldguard.event.EnterClearRegionEvent; import net.knarcraft.clearonworldguard.event.ExitClearRegionEvent; import net.knarcraft.clearonworldguard.manager.PlayerRegionTracker; @@ -22,9 +23,10 @@ public class ClearRegionListener extends WorldGuardListener { * Instantiates a new WorldGuard listener * * @param configuration

The configuration to get regions and settings from

+ * @param protectionManager

The protection manager for protection management

*/ - public ClearRegionListener(@NotNull Configuration configuration) { - super(configuration); + public ClearRegionListener(@NotNull Configuration configuration, @NotNull ProtectionManager protectionManager) { + super(configuration, protectionManager); } @EventHandler(priority = EventPriority.MONITOR) diff --git a/src/main/java/net/knarcraft/clearonworldguard/listener/EntityListener.java b/src/main/java/net/knarcraft/clearonworldguard/listener/EntityListener.java index 6b99e27..ae887b3 100644 --- a/src/main/java/net/knarcraft/clearonworldguard/listener/EntityListener.java +++ b/src/main/java/net/knarcraft/clearonworldguard/listener/EntityListener.java @@ -2,6 +2,7 @@ package net.knarcraft.clearonworldguard.listener; import net.knarcraft.clearonworldguard.ClearOnWorldGuard; import net.knarcraft.clearonworldguard.config.Configuration; +import net.knarcraft.clearonworldguard.config.ProtectionManager; import net.knarcraft.clearonworldguard.manager.PlayerRegionTracker; import net.knarcraft.clearonworldguard.property.Permission; import org.bukkit.Location; @@ -15,16 +16,20 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageByBlockEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityMountEvent; import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.entity.EntitySpawnEvent; import org.bukkit.event.entity.ExplosionPrimeEvent; +import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.event.entity.SpawnerSpawnEvent; import org.bukkit.event.vehicle.VehicleDestroyEvent; import org.bukkit.event.vehicle.VehicleMoveEvent; import org.jetbrains.annotations.NotNull; -import org.spigotmc.event.entity.EntityMountEvent; /** * Listeners for entity events @@ -34,16 +39,17 @@ public class EntityListener extends WorldGuardListener { /** * Instantiates a new WorldGuard listener * - * @param configuration

The configuration to get regions and settings from

+ * @param configuration

The configuration to get regions and settings from

+ * @param protectionManager

The protection manager to use for checking enabled protections

*/ - public EntityListener(@NotNull Configuration configuration) { - super(configuration); + public EntityListener(@NotNull Configuration configuration, @NotNull ProtectionManager protectionManager) { + super(configuration, protectionManager); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onEntityExplode(@NotNull EntityExplodeEvent event) { // Prevent explosions in clear regions - if (isInClearRegion(event.getEntity())) { + if (isInClearRegion(event.getEntity()) || isInClearRegion(event.blockList())) { ClearOnWorldGuard.logDebugMessage("Prevented entity " + event.getEntity() + " from exploding"); event.setCancelled(true); } @@ -96,12 +102,19 @@ public class EntityListener extends WorldGuardListener { } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onEntityDamage(@NotNull EntityDamageByEntityEvent event) { - // Prevent entity damage from players in clear regions + public void onEntityDamageEntity(@NotNull EntityDamageByEntityEvent event) { + // Prevent entities from damaging each-other across clear regions + if (isInDifferentClearRegions(event.getDamager().getLocation(), event.getEntity().getLocation())) { + event.setCancelled(true); + return; + } + + // Only prevent entity damage from players in clear regions if (!(event.getDamager() instanceof Player player)) { return; } + // Prevent the damage, unless the if ((isInClearRegion(event.getEntity()) || PlayerRegionTracker.isInClearRegion(player)) && !player.hasPermission(Permission.BYPASS_ENTITY_INTERACTION.toString())) { ClearOnWorldGuard.logDebugMessage("Prevented entity " + event.getEntity() + " from being damaged"); @@ -109,6 +122,13 @@ public class EntityListener extends WorldGuardListener { } } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onEntityDamageBlock(@NotNull EntityDamageByBlockEvent event) { + if (isInClearRegion(event.getEntity())) { + event.setCancelled(true); + } + } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onEntityDeath(@NotNull EntityDeathEvent event) { // Prevent mob loot and XP @@ -200,4 +220,29 @@ public class EntityListener extends WorldGuardListener { } } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onItemSpawn(@NotNull EntitySpawnEvent event) { + // Prevent entities from spawning in clear regions + if (isInClearRegion(event.getLocation())) { + ClearOnWorldGuard.logDebugMessage("Prevented " + event.getEntity() + " from spawning"); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onSpawnerSpawn(@NotNull SpawnerSpawnEvent event) { + if (isInClearRegion(event.getLocation())) { + ClearOnWorldGuard.logDebugMessage("Prevented " + event.getEntity() + " from spawning from spawner"); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onItemSpawn(@NotNull ItemSpawnEvent event) { + if (isInClearRegion(event.getLocation())) { + ClearOnWorldGuard.logDebugMessage("Prevented item " + event.getEntity() + " from spawning"); + event.setCancelled(true); + } + } + } diff --git a/src/main/java/net/knarcraft/clearonworldguard/listener/PlayerListener.java b/src/main/java/net/knarcraft/clearonworldguard/listener/PlayerListener.java index 2c90931..cc76ed8 100644 --- a/src/main/java/net/knarcraft/clearonworldguard/listener/PlayerListener.java +++ b/src/main/java/net/knarcraft/clearonworldguard/listener/PlayerListener.java @@ -3,6 +3,8 @@ package net.knarcraft.clearonworldguard.listener; import com.sk89q.worldguard.protection.regions.ProtectedRegion; import net.knarcraft.clearonworldguard.ClearOnWorldGuard; import net.knarcraft.clearonworldguard.config.Configuration; +import net.knarcraft.clearonworldguard.config.PlayerProtection; +import net.knarcraft.clearonworldguard.config.ProtectionManager; import net.knarcraft.clearonworldguard.event.EnterClearRegionEvent; import net.knarcraft.clearonworldguard.event.ExitClearRegionEvent; import net.knarcraft.clearonworldguard.manager.PlayerRegionTracker; @@ -13,11 +15,15 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.Action; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerLeashEntityEvent; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryCreativeEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerDropItemEvent; @@ -31,7 +37,9 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SpawnEggMeta; import org.jetbrains.annotations.NotNull; +import java.util.List; import java.util.Set; +import java.util.function.Consumer; /** * Listeners for player events @@ -41,19 +49,107 @@ public class PlayerListener extends WorldGuardListener { /** * Instantiates a new WorldGuard listener * - * @param configuration

The configuration to get regions and settings from

+ * @param configuration

The configuration to get regions and settings from

+ * @param protectionManager

The protection manager to use for checking enabled protections

*/ - public PlayerListener(@NotNull Configuration configuration) { - super(configuration); + public PlayerListener(@NotNull Configuration configuration, @NotNull ProtectionManager protectionManager) { + super(configuration, protectionManager); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onLeash(@NotNull PlayerLeashEntityEvent event) { - // Prevent leashing of entities while in a clear region - if (PlayerRegionTracker.isInClearRegion(event.getPlayer()) && + checkEvent(event, PlayerProtection.LEASHING, event.getPlayer()); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onItemDrop(@NotNull PlayerDropItemEvent event) { + checkEvent(event, PlayerProtection.ITEM_DROP, event.getPlayer()); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerDeath(@NotNull PlayerDeathEvent event) { + Player player = event.getEntity().getPlayer(); + if (player == null) { + return; + } + + checkEvent(PlayerProtection.PLAYER_DEATH_CLEAR, player, (ignored) -> { + event.setKeepInventory(false); + event.setKeepLevel(true); + event.getEntity().getInventory().clear(); + }); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onInteract(@NotNull PlayerInteractEvent event) { + // Prevent interacting with blocks outside the clear region, such as chests + Player player = event.getPlayer(); + Block clicked = event.getClickedBlock(); + if (clicked != null && isInDifferentClearRegions(player.getLocation(), clicked.getLocation())) { + ClearOnWorldGuard.logDebugMessage("Prevented player " + player + " from interacting across a clear" + + " region border"); + event.setCancelled(true); + return; + } + + // Block changing the creature in a spawner + if (event.getAction() == Action.RIGHT_CLICK_BLOCK && clicked != null && clicked.getType() == Material.SPAWNER && + isInClearRegion(clicked) && !player.hasPermission(Permission.BYPASS_MOB_SPAWNING.toString())) { + ClearOnWorldGuard.logDebugMessage("Prevented player " + player + " from interacting with mob spawner " + + clicked); + event.setCancelled(true); + return; + } + + // Block usage of spawn eggs + ItemStack item = event.getItem(); + if (item != null && PlayerRegionTracker.isInClearRegion(player)) { + ItemMeta meta = item.getItemMeta(); + if (meta instanceof SpawnEggMeta && !player.hasPermission(Permission.BYPASS_MOB_SPAWNING.toString())) { + ClearOnWorldGuard.logDebugMessage("Prevented player " + player + " from using the spawn egg " + item); + event.setCancelled(true); + return; + } + } + + /* Block usage of ender chests while in a clear region (the first check is this method takes care of the case + where the chest is outside the clear region) */ + if (clicked != null && PlayerRegionTracker.isInClearRegion(player) && + event.getAction() != Action.LEFT_CLICK_BLOCK && clicked.getType() == Material.ENDER_CHEST) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onEntityInteract(@NotNull PlayerInteractEntityEvent event) { + // Allow interactions with human NPCs + if (event.getRightClicked() instanceof HumanEntity && !(event.getRightClicked() instanceof Player)) { + return; + } + + // Prevent entity interaction, such as trading or putting chests on donkeys + if ((PlayerRegionTracker.isInClearRegion(event.getPlayer()) || isInClearRegion(event.getRightClicked())) && !event.getPlayer().hasPermission(Permission.BYPASS_ENTITY_INTERACTION.toString())) { - ClearOnWorldGuard.logDebugMessage("Prevented " + event.getEntity() + " from being leashed by " + - event.getPlayer()); + ClearOnWorldGuard.logDebugMessage("Prevented player " + event.getPlayer() + + " from interacting with entity " + event.getRightClicked()); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBucketEmpty(@NotNull PlayerBucketEmptyEvent event) { + if (PlayerRegionTracker.isInClearRegion(event.getPlayer())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onCreativeDrop(@NotNull InventoryCreativeEvent event) { + List relevantActions = List.of(InventoryAction.DROP_ALL_CURSOR, InventoryAction.DROP_ALL_SLOT, + InventoryAction.DROP_ONE_CURSOR, InventoryAction.DROP_ONE_SLOT); + HumanEntity entity = event.getWhoClicked(); + if (entity instanceof Player player && PlayerRegionTracker.isInClearRegion(player) && + relevantActions.contains(event.getAction())) { event.setCancelled(true); } } @@ -129,88 +225,41 @@ public class PlayerListener extends WorldGuardListener { return false; } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onItemDrop(@NotNull PlayerDropItemEvent event) { - // Prevent a player from dropping an item while inside a clear region - if (PlayerRegionTracker.isInClearRegion(event.getPlayer())) { - ClearOnWorldGuard.logDebugMessage("Prevented player " + event.getPlayer() + " from dropping an item"); - event.setCancelled(true); + /** + * Checks and cancels the given event if necessary + * + * @param event

The triggered event

+ * @param protection

The protection the event relates to

+ * @param player

The player that triggered the event

+ */ + private void checkEvent(@NotNull Event event, @NotNull PlayerProtection protection, @NotNull Player player) { + if (event instanceof Cancellable cancellable) { + checkEvent(protection, player, (ignored) -> cancellable.setCancelled(true)); + } else { + throw new IllegalArgumentException("Event cannot be cancelled!"); } } - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerDeath(@NotNull PlayerDeathEvent event) { - // Prevent deaths in clear regions from causing items to be kept or dropped - if (PlayerRegionTracker.isInClearRegion(event.getEntity())) { - ClearOnWorldGuard.logDebugMessage("Prevented player " + event.getEntity() + " from dropping or keeping " + - "items on death"); - event.setKeepInventory(false); - event.setKeepLevel(true); - event.getEntity().getInventory().clear(); - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onInteract(@NotNull PlayerInteractEvent event) { - // Prevent interacting with blocks outside the clear region, such as chests - Player player = event.getPlayer(); - Block clicked = event.getClickedBlock(); - if (clicked != null && isInDifferentClearRegions(player.getLocation(), clicked.getLocation())) { - ClearOnWorldGuard.logDebugMessage("Prevented player " + player + " from interacting across a clear" + - " region border"); - event.setCancelled(true); + /** + * Checks and cancels the given event if necessary + * + * @param protection

The protection the event relates to

+ * @param player

The player that triggered the event

+ * @param callback

The callback to trigger to apply the protection

+ */ + private void checkEvent(@NotNull PlayerProtection protection, @NotNull Player player, + @NotNull Consumer callback) { + if (!isEnabled(protection, player)) { return; } - // Block changing the creature in a spawner - if (event.getAction() == Action.RIGHT_CLICK_BLOCK && clicked != null && clicked.getType() == Material.SPAWNER && - isInClearRegion(clicked) && !player.hasPermission(Permission.BYPASS_MOB_SPAWNING.toString())) { - ClearOnWorldGuard.logDebugMessage("Prevented player " + player + " from interacting with mob spawner " + - clicked); - event.setCancelled(true); + // Ignore if outside a clear region + if (!PlayerRegionTracker.isInClearRegion(player)) { return; } - // Block usage of spawn eggs - ItemStack item = event.getItem(); - if (item != null && PlayerRegionTracker.isInClearRegion(player)) { - ItemMeta meta = item.getItemMeta(); - if (meta instanceof SpawnEggMeta && !player.hasPermission(Permission.BYPASS_MOB_SPAWNING.toString())) { - ClearOnWorldGuard.logDebugMessage("Prevented player " + player + " from using the spawn egg " + item); - event.setCancelled(true); - return; - } - } - - /* Block usage of ender chests while in a clear region (the first check is this method takes care of the case - where the chest is outside the clear region) */ - if (clicked != null && PlayerRegionTracker.isInClearRegion(player) && - event.getAction() != Action.LEFT_CLICK_BLOCK && clicked.getType() == Material.ENDER_CHEST) { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onEntityInteract(@NotNull PlayerInteractEntityEvent event) { - // Allow interactions with human NPCs - if (event.getRightClicked() instanceof HumanEntity && !(event.getRightClicked() instanceof Player)) { - return; - } - - // Prevent entity interaction, such as trading or putting chests on donkeys - if ((PlayerRegionTracker.isInClearRegion(event.getPlayer()) || isInClearRegion(event.getRightClicked())) && - !event.getPlayer().hasPermission(Permission.BYPASS_ENTITY_INTERACTION.toString())) { - ClearOnWorldGuard.logDebugMessage("Prevented player " + event.getPlayer() + - " from interacting with entity " + event.getRightClicked()); - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onBucketEmpty(@NotNull PlayerBucketEmptyEvent event) { - if (PlayerRegionTracker.isInClearRegion(event.getPlayer())) { - event.setCancelled(true); - } + ClearOnWorldGuard.logDebugMessage("Protected against " + protection.getPath() + " by " + player.getName()); + callback.accept(null); } } diff --git a/src/main/java/net/knarcraft/clearonworldguard/listener/WorldGuardListener.java b/src/main/java/net/knarcraft/clearonworldguard/listener/WorldGuardListener.java index d91af18..76f541b 100644 --- a/src/main/java/net/knarcraft/clearonworldguard/listener/WorldGuardListener.java +++ b/src/main/java/net/knarcraft/clearonworldguard/listener/WorldGuardListener.java @@ -4,6 +4,9 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldguard.protection.regions.ProtectedRegion; import net.knarcraft.clearonworldguard.ClearOnWorldGuard; import net.knarcraft.clearonworldguard.config.Configuration; +import net.knarcraft.clearonworldguard.config.PlayerProtection; +import net.knarcraft.clearonworldguard.config.Protection; +import net.knarcraft.clearonworldguard.config.ProtectionManager; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Block; @@ -29,14 +32,17 @@ import java.util.logging.Level; public abstract class WorldGuardListener implements Listener { private final Configuration configuration; + private final ProtectionManager protectionManager; /** * Instantiates a new WorldGuard listener * - * @param configuration

The configuration to get regions and settings from

+ * @param configuration

The configuration to get regions and settings from

+ * @param protectionManager

The protection manager to use for checking enabled protections

*/ - public WorldGuardListener(@NotNull Configuration configuration) { + public WorldGuardListener(@NotNull Configuration configuration, @NotNull ProtectionManager protectionManager) { this.configuration = configuration; + this.protectionManager = protectionManager; } /** @@ -160,6 +166,21 @@ public abstract class WorldGuardListener implements Listener { return isInClearRegion(block.getLocation()); } + /** + * Checks whether any of the given blocks are in a clear region + * + * @param blocks

The blocks to check

+ * @return

True if any of the given blocks are in a clear region

+ */ + protected boolean isInClearRegion(@NotNull List blocks) { + for (Block block : blocks) { + if (isInClearRegion(block)) { + return true; + } + } + return false; + } + /** * Checks whether the given location is in a clear region * @@ -200,4 +221,26 @@ public abstract class WorldGuardListener implements Listener { return configuration.getRegionQuery().getApplicableRegions(BukkitAdapter.adapt(location)).getRegions(); } + /** + * Checks whether the given protection is enabled + * + * @param protection

The protection to check

+ * @return

True if the protection is enabled

+ */ + protected boolean isEnabled(@NotNull Protection protection) { + return protectionManager.isEnabled(protection); + } + + /** + * Checks whether the given player protection is enabled + * + * @param protection

The protection to check

+ * @param player

The player involved

+ * @return

True if the protection is enabled

+ */ + protected boolean isEnabled(@NotNull PlayerProtection protection, @NotNull Player player) { + return protectionManager.isEnabled(protection) && + !protectionManager.canBypass(player, protection); + } + } diff --git a/src/main/java/net/knarcraft/clearonworldguard/util/ListParser.java b/src/main/java/net/knarcraft/clearonworldguard/util/ListParser.java new file mode 100644 index 0000000..dc96363 --- /dev/null +++ b/src/main/java/net/knarcraft/clearonworldguard/util/ListParser.java @@ -0,0 +1,36 @@ +package net.knarcraft.clearonworldguard.util; + +import net.knarcraft.clearonworldguard.ClearOnWorldGuard; +import org.bukkit.event.block.BlockIgniteEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; + +/** + * A helper class for parsing list of strings into their proper type + */ +public class ListParser { + + /** + * Parses a list of strings into a list of ignite causes + * + * @param igniteCauseNames

The names of ignite causes

+ * @return

A list of ignite causes

+ */ + private @NotNull Set parseIgniteCauses(@NotNull List igniteCauseNames) { + Set igniteCauseExemptions = new HashSet<>(); + for (String igniteCauseName : igniteCauseNames) { + try { + igniteCauseExemptions.add(BlockIgniteEvent.IgniteCause.valueOf( + igniteCauseName.toUpperCase().replace("-", "_"))); + } catch (IllegalArgumentException exception) { + ClearOnWorldGuard.logger().log(Level.WARNING, "Invalid ignite cause exception " + igniteCauseName); + } + } + return igniteCauseExemptions; + } + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index ca1f72a..eda7aee 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,10 +1,267 @@ # The regions for each world that should clearRegions: - # The name or UUID of a world. Add any regions that should force inventory clearing as a comma-separated list inside - # the square parentheses. + # The name or UUID of a world. Add any clear regions as a comma-separated list inside the square parentheses. world: [ ] world_nether: [ ] world_the_end: [ ] +# Behavior for when players try to enter or exit a clear region +behavior: + # Whether to clear a player's current items when they enter a clear region + clearInventoryOnEntry: false + # Whether to clear a player current items when they exit a clear region + clearInventoryOnExit: true + # Whether to clear XP when a player enters a clear region + clearXPOnEntry: false + # Whether to clear XP when a player exits a clear region + clearXPOnExit: false + # Whether to require a player to have an empty inventory before entering a clear region + requireEmptyInventoryToEnter: true + # Whether to require a player to have no XP before entering a clear region + requireNoXPToEnter: false + +# Protection overrides for specific regions +regionProtection: +# Example region protection +# world: # The world the region is in +# example: # The name of a clear region +# player: # Player protection section +# leashing: # The protection to override +# enabled: false ¤ The override itself +# environment: # Environment protection section +# dispenseItem: # The protection to override +# enabled: false ¤ The override itself + +# Protection settings for all clear regions all protections have a description describing why they might be needed +protection: + # Protections that might involve a player, and that can be bypassed using clearonworldguard.bypass.name (e.x. clearonworldguard.bypass.itemPickup) + player: + # Prevents player from attaching leashes to mobs + # (leashing entities could be used to export spawned creatures and any items they carry) + leashing: + enabled: true + # Prevents player from picking up items + # (the player could end up with items belonging to a player outside the clear region) + itemPickup: + enabled: true + # Prevents player from dropping items' + # (items could be thrown outside the clear region) + itemDrop: + enabled: true + # Prevents player from accessing ender chests + # (ender chests can be used to store creative items) + enderChest: + enabled: true + # Prevents player from using spawn eggs, unless they've got the bypass permission "mobspawning" + # (spawn eggs can be used to crash the server, or get rare creatures) + spawnEgg: + enabled: true + # Prevent blocks from igniting + # (fire can be used to grief buildings if blockBurn protection is disabled) + blockIgnite: + enabled: true + # Ignite causes that should be allowed + igniteCauseExempt: [ + #- ARROW + #- ENDER_CRYSTAL + #- EXPLOSION + #- FIREBALL + #- FLINT_AND_STEEL + #- LAVA + #- LIGHTNING + #- SPREAD + ] + # Materials (https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Material.html) players are allowed to ignite. + # A "+" in front of the name specifies a material tag (https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Tag.html). + materialExempt: + - +CANDLES + - +CAMPFIRES + - NETHERRACK + - SOUL_SAND + - SOUL_SOIL + # Prevents entities (like snowmen, or players with frost walker) from forming blocks + # (if snowmen can spawn, they might end up spawning snow everywhere) + entityBlockForm: + enabled: true + # Prevents placement of blocks across clear region borders + # (blocks placed outside clear regions might be valuable, and blocks placed from outside will be lost) + blockPlaceBorder: + enabled: true + # Prevents breaking of blocks across clear region borders + # (blocks broken from outside clear regions won't produce the expected drop, and blocks broken from the inside might + # not normally be destroyable, e.g. bedrock) + blockBreakBorder: + enabled: true + # Blocks any blocks in clear regions from dropping as an item + # (item drops could be picked up by someone outside the clear region) + blockDropItem: + enabled: true + # Prevents TNT from being primed + # (if TNT isn't blocked by other means, TNT could be used to massively grief the clear region) + tntPrime: + enabled: true + # Prevents an entity from mounting another entity + # (mounting an entity could in some cases be used to aid in creature smuggling) + entityMount: + enabled: true + # Prevents an entity from changing a block + # (mobs can grief by changing blocks, or players can crash the server by making sand into falling sand) + entityChangeBlock: + enabled: true + # Prevents entities from damaging each-other across clear region borders + # (entities, including players, could be killed with enchantments the player has spawned in) + entityDamageBorder: + enabled: true + # Prevents entities from damaging other entities in clear regions + # (it might be undesirable to allow players to kill every living creature in a clear region) + entityDamage: + enabled: true + # Whether to only block players from damaging entities + ignoreNonPlayers: true + # Prevents entities from taking damage from blocks + # (blocks can be placed that damage and kill entities, which might not be wanted) + entityDamageBlock: + enabled: true + # Deletes destroyed vehicles to prevent the vehicle or the contents from dropping as items + # (vehicles could potentially drop valuable items when destroyed) + vehicleDestroyDelete: + enabled: true + # Deletes a vehicle leaving a clear region + # (vehicles could potentially be used to transport valuable items out of a clear region) + vehicleBorderDelete: + enabled: true + # Prevents player from dropping items or XP on death, and prevents the player from keeping their inventory + # (if some method allows the player to die, it might drop items that can be picked up by players outside the region) + playerDeathClear: + enabled: true + # Environment protections that cannot be bypassed by individual players + environment: + # Prevents creatures from spawning in a clear regions + # (creature spawning can be used to crash the server) + creatureSpawning: + enabled: true + # Any spawn reasons (https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/CreatureSpawnEvent.SpawnReason.html) + # that should be exempt from this protection + spawnReasonExempt: + - BEEHIVE + #- BREEDING + #- BUILD_IRONGOLEM + #- BUILD_SNOWMAN + #- BUILD_WITHER + - COMMAND # Any players with access to the summon command should probably be allowed to + #- CURED + - CUSTOM + #- DEFAULT + #- DISPENSE_EGG + - DROWNED + #- DUPLICATION + #- EGG + #- ENDER_PEARL + #- EXPLOSION + #- FROZEN + #- INFECTION + #- JOCKEY + #- LIGHTNING + #- METAMORPHOSIS + #- MOUNT + - NATURAL + #- NETHER_PORTAL + #- OCELOT_BABY + #- PATROL + #- PIGLIN_ZOMBIFIED + #- RAID + #- REINFORCEMENTS + #- SHEARED + #- SHOULDER_ENTITY + #- SILVERFISH_BLOCK + #- SLIME_SPLIT + #- SPAWNER + - SPAWNER_EGG # This is already restricted with spawnEgg, so any use can be seen as intentional + #- SPELL + #- TRAP + #- VILLAGE_DEFENSE + #- VILLAGE_INVASION + # Any entity types (https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/EntityType.html) that should be + # exempt from this protection + entityTypeExempt: [ ] + # Prevents blocks in clear regions from producing xp + # (block xp could be used for farming undeserved experience levels) + blockXp: + enabled: true + # Prevents items from being dispensed in clear regions + # (items could be dispensed outside the region, allowing illegal item export) + dispenseItem: + enabled: true + # Prevent armor from being dispensed in clear regions + # (armor could be dispensed outside the region, allowing illegal item export) + dispenseArmor: + enabled: true + # Prevent blocks from burning and disappearing in clear regions + # (fire can be used to grief buildings) + blockBurn: + enabled: true + # Prevent blocks from spreading in a clear region + # (for example fire spreading can be bad if other fire-related protections are disabled) + blockSpread: + enabled: false + # A more generic event than blockSpread and entityBlockForm, which cancels both + # (lots of blocks forming at once could potentially cause lag, or be used to lava-grief) + blockForm: + enabled: false + # Prevents pistons from extending across clear region borders + # (pistons can push valuable blocks, like netherite blocks, outside the clear region) + pistonExtendBorder: + enabled: true + # Prevents pistons from retracting across clear region borders + # (pistons can pull valuable blocks from a clear region) + pistonRetractBorder: + enabled: true + # Prevents blocks from exploding + # (explosions can be used to grief, and could potentially create item drops) + blockExplode: + enabled: true + # Prevents an entity from being primed + # (entities, like creepers could potentially be used to grief clear regions) + explosionPrime: + enabled: true + # Whether the primed entity should be removed from the game + removeEntity: true + # Prevents an entity from exploding (this might be redundant if explosionPrime protection is enabled) + # (entities, like creepers could potentially be used to grief clear regions) + entityExplode: + enabled: true + # Prevents entities from dropping items or xp on death + # (items dropping outside of clear regions can potentially be picked up, and xp can be farmed) + entityDeathDrops: + enabled: true + # Whether entities should be prevented from dropping xp + preventXP: true + # Whether entities should be prevented from dropping items + preventItems: true + # Prevents players from launching projectiles + # (as launched projectiles might end up outside clear regions, they can potentially damage entities or blocks) + projectileLaunch: + enabled: true + # Prevents entities from combusting + # (combustion could potentially be used to kill entities) + entityCombust: + enabled: false + # Prevents all entity spawning + # (entities spawning can cause lag, and some entities may be used to damage blocks or other entities) + entitySpawn: + enabled: false + # Prevents entities from spawning from spawners + # (if other protection is disabled, spawners might be used to farm XP or specific items) + spawnerSpawn: + enabled: false + # Prevents dropped items from spawning + # (items spawning could cause lag, or could be transported out of the clear region using water) + itemSpawn: + enabled: true + # Prevents players from dropping items from their creative inventory + # (Items dropped by creative players can potentially be picked up by survival players) + creativeItemDrop: + enabled: true + # Whether to enable debug mode, which spams debug messages at log level INFO, rather than log level FINEST debug: false \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 28be972..1545628 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -17,4 +17,7 @@ permissions: description: Allows a player to spawn mobs in clear regions clearonworldguard.bypass.entityinteraction: default: false - description: Allows a player to interact with mobs in a clear region \ No newline at end of file + description: Allows a player to interact with mobs in a clear region + children: + - clearonworldguard.bypass.leashing + - clearonworldguard.bypass. \ No newline at end of file