diff --git a/src/main/java/com/griefprevention/protection/ProtectionHelper.java b/src/main/java/com/griefprevention/protection/ProtectionHelper.java new file mode 100644 index 0000000..f34f1ec --- /dev/null +++ b/src/main/java/com/griefprevention/protection/ProtectionHelper.java @@ -0,0 +1,87 @@ +package com.griefprevention.protection; + +import me.ryanhamshire.GriefPrevention.Claim; +import me.ryanhamshire.GriefPrevention.ClaimPermission; +import me.ryanhamshire.GriefPrevention.ClaimsMode; +import me.ryanhamshire.GriefPrevention.DataStore; +import me.ryanhamshire.GriefPrevention.GriefPrevention; +import me.ryanhamshire.GriefPrevention.Messages; +import me.ryanhamshire.GriefPrevention.PlayerData; +import me.ryanhamshire.GriefPrevention.events.PreventBlockBreakEvent; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Supplier; + +/** + * A utility used to simplify various protection-related checks. + */ +public final class ProtectionHelper +{ + + private ProtectionHelper() {} + + /** + * Check the {@link ClaimPermission} state for a {@link Player} at a particular {@link Location}. + * + *

This respects ignoring claims, wilderness rules, etc.

+ * + * @param player the person performing the action + * @param location the affected {@link Location} + * @param permission the required permission + * @param trigger the triggering {@link Event}, if any + * @return the denial message supplier, or {@code null} if the action is not denied + */ + public static @Nullable Supplier checkPermission( + @NotNull Player player, + @NotNull Location location, + @NotNull ClaimPermission permission, + @Nullable Event trigger) + { + World world = location.getWorld(); + if (world == null || !GriefPrevention.instance.claimsEnabledForWorld(world)) return null; + + PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId()); + + // Administrators ignoring claims always have permission. + if (playerData.ignoreClaims) return null; + + Claim claim = GriefPrevention.instance.dataStore.getClaimAt(location, false, playerData.lastClaim); + + + // If there is no claim here, use wilderness rules. + if (claim == null) + { + // If claims are not required, then the player has permission. + return null; + } + + // Update cached claim. + playerData.lastClaim = claim; + + // Apply claim rules. + Supplier cancel = claim.checkPermission(player, permission, trigger); + + // Apply additional specific rules. + if (cancel != null && trigger instanceof BlockBreakEvent breakEvent) + { + PreventBlockBreakEvent preventionEvent = new PreventBlockBreakEvent(breakEvent); + Bukkit.getPluginManager().callEvent(preventionEvent); + if (preventionEvent.isCancelled()) + { + cancel = null; + } + } + + return cancel; + } + +} diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/BlockEventHandler.java b/src/main/java/me/ryanhamshire/GriefPrevention/BlockEventHandler.java index 786e3d6..1edae7f 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/BlockEventHandler.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/BlockEventHandler.java @@ -18,6 +18,7 @@ package me.ryanhamshire.GriefPrevention; +import com.griefprevention.protection.ProtectionHelper; import me.ryanhamshire.GriefPrevention.util.BoundingBox; import org.bukkit.ChatColor; import org.bukkit.GameMode; @@ -118,10 +119,10 @@ public class BlockEventHandler implements Listener Block block = breakEvent.getBlock(); //make sure the player is allowed to break at the location - String noBuildReason = GriefPrevention.instance.allowBreak(player, block, block.getLocation(), breakEvent); + Supplier noBuildReason = ProtectionHelper.checkPermission(player, block.getLocation(), ClaimPermission.Build, breakEvent); if (noBuildReason != null) { - GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); + GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason.get()); breakEvent.setCancelled(true); return; } @@ -136,10 +137,10 @@ public class BlockEventHandler implements Listener if (player == null || sign == null) return; - String noBuildReason = GriefPrevention.instance.allowBuild(player, sign.getLocation(), sign.getType()); + Supplier noBuildReason = ProtectionHelper.checkPermission(player, sign.getLocation(), ClaimPermission.Build, event); if (noBuildReason != null) { - GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); + GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason.get()); event.setCancelled(true); return; } @@ -205,10 +206,10 @@ public class BlockEventHandler implements Listener //make sure the player is allowed to build at the location for (BlockState block : placeEvent.getReplacedBlockStates()) { - String noBuildReason = GriefPrevention.instance.allowBuild(player, block.getLocation(), block.getType()); + Supplier noBuildReason = ProtectionHelper.checkPermission(player, block.getLocation(), ClaimPermission.Build, placeEvent); if (noBuildReason != null) { - GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); + GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason.get()); placeEvent.setCancelled(true); return; } @@ -239,7 +240,7 @@ public class BlockEventHandler implements Listener if (!GriefPrevention.instance.claimsEnabledForWorld(placeEvent.getBlock().getWorld())) return; //make sure the player is allowed to build at the location - String noBuildReason = GriefPrevention.instance.allowBuild(player, block.getLocation(), block.getType()); + Supplier noBuildReason = ProtectionHelper.checkPermission(player, block.getLocation(), ClaimPermission.Build, placeEvent); if (noBuildReason != null) { // Allow players with container trust to place books in lecterns @@ -259,7 +260,7 @@ public class BlockEventHandler implements Listener return; } } - GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); + GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason.get()); placeEvent.setCancelled(true); return; } diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/EntityEventHandler.java b/src/main/java/me/ryanhamshire/GriefPrevention/EntityEventHandler.java index 019724b..76443fb 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/EntityEventHandler.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/EntityEventHandler.java @@ -18,10 +18,12 @@ package me.ryanhamshire.GriefPrevention; +import com.griefprevention.protection.ProtectionHelper; import de.Keyle.MyPet.api.entity.MyPetBukkitEntity; import me.ryanhamshire.GriefPrevention.events.PreventPvPEvent; import me.ryanhamshire.GriefPrevention.events.ProtectDeathDropsEvent; import org.bukkit.Bukkit; +import org.bukkit.ExplosionResult; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -58,6 +60,7 @@ import org.bukkit.entity.WaterMob; import org.bukkit.entity.Wolf; import org.bukkit.entity.Zombie; import org.bukkit.entity.minecart.ExplosiveMinecart; +import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -100,6 +103,8 @@ import org.bukkit.potion.PotionEffectTypeCategory; import org.bukkit.projectiles.BlockProjectileSource; import org.bukkit.projectiles.ProjectileSource; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; @@ -129,14 +134,10 @@ public class EntityEventHandler implements Listener public void onEntityFormBlock(EntityBlockFormEvent event) { Entity entity = event.getEntity(); - if (entity.getType() == EntityType.PLAYER) + if (entity instanceof Player player + && ProtectionHelper.checkPermission(player, event.getBlock().getLocation(), ClaimPermission.Build, event) != null) { - Player player = (Player) event.getEntity(); - String noBuildReason = GriefPrevention.instance.allowBuild(player, event.getBlock().getLocation(), event.getNewState().getType()); - if (noBuildReason != null) - { - event.setCancelled(true); - } + event.setCancelled(true); } } @@ -183,15 +184,14 @@ public class EntityEventHandler implements Listener //don't allow crops to be trampled, except by a player with build permission else if (event.getTo() == Material.DIRT && event.getBlock().getType() == Material.FARMLAND) { - if (event.getEntityType() != EntityType.PLAYER) + if (!(event.getEntity() instanceof Player player)) { event.setCancelled(true); } else { - Player player = (Player) event.getEntity(); Block block = event.getBlock(); - if (GriefPrevention.instance.allowBreak(player, block, block.getLocation()) != null) + if (ProtectionHelper.checkPermission(player, block.getLocation(), ClaimPermission.Build, event) != null) { event.setCancelled(true); } @@ -202,10 +202,10 @@ public class EntityEventHandler implements Listener else if (event.getEntity() instanceof Vehicle && !event.getEntity().getPassengers().isEmpty()) { Entity driver = event.getEntity().getPassengers().get(0); - if (driver instanceof Player) + if (driver instanceof Player player) { Block block = event.getBlock(); - if (GriefPrevention.instance.allowBreak((Player) driver, block, block.getLocation()) != null) + if (ProtectionHelper.checkPermission(player, block.getLocation(), ClaimPermission.Build, event) != null) { event.setCancelled(true); } @@ -377,23 +377,99 @@ public class EntityEventHandler implements Listener @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onEntityExplode(EntityExplodeEvent explodeEvent) { - this.handleExplosion(explodeEvent.getLocation(), explodeEvent.getEntity(), explodeEvent.blockList()); + // If there aren't any affected blocks, there's nothing to do. Vanilla mob griefing rule causes this. + if (explodeEvent.blockList().isEmpty()) return; + + // Explosion causes interactable blocks (levers, buttons, etc.) to change state. + if (explodeEvent.getExplosionResult() == ExplosionResult.TRIGGER_BLOCK) + { + handleExplodeInteract(explodeEvent.getLocation(), explodeEvent.getEntity(), explodeEvent.blockList(), explodeEvent); + } + // Explosion damages world. + else + { + handleExplosion(explodeEvent.getLocation(), explodeEvent.getEntity(), explodeEvent.blockList()); + } } //when a block explodes... @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onBlockExplode(BlockExplodeEvent explodeEvent) { - this.handleExplosion(explodeEvent.getBlock().getLocation(), null, explodeEvent.blockList()); + // If there aren't any affected blocks, there's nothing to do. Vanilla mob griefing rule causes this. + if (explodeEvent.blockList().isEmpty()) return; + + // Explosion causes interactable blocks (levers, buttons, etc.) to change state. + if (explodeEvent.getExplosionResult() == ExplosionResult.TRIGGER_BLOCK) + { + handleExplodeInteract(explodeEvent.getBlock().getLocation(), null, explodeEvent.blockList(), explodeEvent); + } + // Explosion damages world. + else + { + handleExplosion(explodeEvent.getBlock().getLocation(), null, explodeEvent.blockList()); + } } + void handleExplodeInteract(@NotNull Location location, @Nullable Entity entity, @NotNull List blocks, @NotNull Event event) + { + World world = location.getWorld(); - void handleExplosion(Location location, Entity entity, List blocks) + if (world == null || !GriefPrevention.instance.claimsEnabledForWorld(world)) return; + + Player player = null; + PlayerData playerData = null; + ProjectileSource source = null; + if (entity instanceof Projectile projectile) + { + source = projectile.getShooter(); + if (source instanceof Player) + { + player = (Player) source; + playerData = dataStore.getPlayerData(player.getUniqueId()); + } + } + + List removed = new ArrayList<>(); + Claim cachedClaim = playerData != null ? playerData.lastClaim : null; + + for (Block block : blocks) + { + // Always ignore air blocks. + if (block.getType().isAir()) continue; + + Claim claim = this.dataStore.getClaimAt(block.getLocation(), false, cachedClaim); + + // Is it in a land claim? + if (claim == null) continue; + + cachedClaim = claim; + + if (player == null) + { + // If the source is not part of the claim, prevent interaction. + if (!isBlockSourceInClaim(source, claim)) + removed.add(block); + continue; + } + + // If the player is not allowed to interact with blocks, prevent interaction. + if (claim.checkPermission(player, ClaimPermission.Access, event) != null) + removed.add(block); + } + + if (playerData != null && cachedClaim != null) + playerData.lastClaim = cachedClaim; + + blocks.removeAll(removed); + } + + void handleExplosion(@NotNull Location location, @Nullable Entity entity, @NotNull List blocks) { //only applies to claims-enabled worlds World world = location.getWorld(); - if (!GriefPrevention.instance.claimsEnabledForWorld(world)) return; + if (world == null || !GriefPrevention.instance.claimsEnabledForWorld(world)) return; //FEATURE: explosions don't destroy surface blocks by default boolean isCreeper = (entity != null && entity.getType() == EntityType.CREEPER); @@ -406,7 +482,7 @@ public class EntityEventHandler implements Listener for (Block block : blocks) { //always ignore air blocks - if (block.getType() == Material.AIR) continue; + if (block.getType().isAir()) continue; //is it in a land claim? Claim claim = this.dataStore.getClaimAt(block.getLocation(), false, cachedClaim); @@ -589,19 +665,18 @@ public class EntityEventHandler implements Listener Entity remover = entityEvent.getRemover(); //again, making sure the breaker is a player - if (remover.getType() != EntityType.PLAYER) + if (!(remover instanceof Player playerRemover)) { event.setCancelled(true); return; } //if the player doesn't have build permission, don't allow the breakage - Player playerRemover = (Player) entityEvent.getRemover(); - String noBuildReason = GriefPrevention.instance.allowBuild(playerRemover, event.getEntity().getLocation(), Material.AIR); + Supplier noBuildReason = ProtectionHelper.checkPermission(playerRemover, event.getEntity().getLocation(), ClaimPermission.Build, event); if (noBuildReason != null) { event.setCancelled(true); - GriefPrevention.sendMessage(playerRemover, TextMode.Err, noBuildReason); + GriefPrevention.sendMessage(playerRemover, TextMode.Err, noBuildReason.get()); } } @@ -611,15 +686,16 @@ public class EntityEventHandler implements Listener { //don't track in worlds where claims are not enabled if (!GriefPrevention.instance.claimsEnabledForWorld(event.getBlock().getWorld())) return; + if (event.getPlayer() == null) return; //FEATURE: similar to above, placing a painting requires build permission in the claim //if the player doesn't have permission, don't allow the placement - String noBuildReason = GriefPrevention.instance.allowBuild(event.getPlayer(), event.getEntity().getLocation(), Material.PAINTING); + Supplier noBuildReason = ProtectionHelper.checkPermission(event.getPlayer(), event.getEntity().getLocation(), ClaimPermission.Build, event); if (noBuildReason != null) { event.setCancelled(true); - GriefPrevention.sendMessage(event.getPlayer(), TextMode.Err, noBuildReason); + GriefPrevention.sendMessage(event.getPlayer(), TextMode.Err, noBuildReason.get()); return; } diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java b/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java index 032d9ec..31213c8 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java @@ -18,6 +18,7 @@ package me.ryanhamshire.GriefPrevention; +import com.griefprevention.protection.ProtectionHelper; import me.ryanhamshire.GriefPrevention.DataStore.NoTransferException; import me.ryanhamshire.GriefPrevention.alttd.config.Config; import me.ryanhamshire.GriefPrevention.alttd.database.DatabaseConnection; @@ -3050,89 +3051,68 @@ public class GriefPrevention extends JavaPlugin return mode != null && mode != ClaimsMode.Disabled; } + /** + * @deprecated use {@link ProtectionHelper#checkPermission(Player, Location, ClaimPermission, org.bukkit.event.Event)} + */ + @Deprecated(forRemoval = true, since = "17.0.0") public String allowBuild(Player player, Location location) { - // TODO check all derivatives and rework API return this.allowBuild(player, location, location.getBlock().getType()); } + /** + * @deprecated use {@link ProtectionHelper#checkPermission(Player, Location, ClaimPermission, org.bukkit.event.Event)} + */ + @Deprecated(forRemoval = true, since = "17.0.0") public String allowBuild(Player player, Location location, Material material) { if (!GriefPrevention.instance.claimsEnabledForWorld(location.getWorld())) return null; - PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId()); - Claim claim = this.dataStore.getClaimAt(location, false, playerData.lastClaim); - - //exception: administrators in ignore claims mode - if (playerData.ignoreClaims) return null; - - //wilderness rules - if (claim == null) + ItemStack placed; + if (material.isItem()) { - return null; + placed = new ItemStack(material); } - - //if not in the wilderness, then apply claim rules (permissions, etc) else { - //cache the claim for later reference - playerData.lastClaim = claim; - Block block = location.getBlock(); - - Supplier supplier = claim.checkPermission(player, ClaimPermission.Build, new BlockPlaceEvent(block, block.getState(), block, new ItemStack(material), player, true, EquipmentSlot.HAND)); - - if (supplier == null) return null; - - return supplier.get(); + var blockType = material.asBlockType(); + if (blockType != null && blockType.hasItemType()) + placed = blockType.getItemType().createItemStack(); + else + placed = new ItemStack(Material.DIRT); } + + Block block = location.getBlock(); + Supplier result = ProtectionHelper.checkPermission(player, location, ClaimPermission.Build, new BlockPlaceEvent(block, block.getState(), block, placed, player, true, EquipmentSlot.HAND)); + return result == null ? null : result.get(); } + /** + * @deprecated use {@link ProtectionHelper#checkPermission(Player, Location, ClaimPermission, org.bukkit.event.Event)} + */ + @Deprecated(forRemoval = true, since = "17.0.0") public String allowBreak(Player player, Block block, Location location) { return this.allowBreak(player, block, location, new BlockBreakEvent(block, player)); } + /** + * @deprecated use {@link ProtectionHelper#checkPermission(Player, Location, ClaimPermission, org.bukkit.event.Event)} + */ + @Deprecated(forRemoval = true, since = "17.0.0") public String allowBreak(Player player, Material material, Location location, BlockBreakEvent breakEvent) { return this.allowBreak(player, location.getBlock(), location, breakEvent); } + /** + * @deprecated use {@link ProtectionHelper#checkPermission(Player, Location, ClaimPermission, org.bukkit.event.Event)} + */ + @Deprecated(forRemoval = true, since = "17.0.0") public String allowBreak(Player player, Block block, Location location, BlockBreakEvent breakEvent) { - if (!GriefPrevention.instance.claimsEnabledForWorld(location.getWorld())) return null; - - PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId()); - Claim claim = this.dataStore.getClaimAt(location, false, playerData.lastClaim); - - //exception: administrators in ignore claims mode - if (playerData.ignoreClaims) return null; - - //wilderness rules - if (claim == null) - { - return null; - } - else - { - //cache the claim for later reference - playerData.lastClaim = claim; - - //if not in the wilderness, then apply claim rules (permissions, etc) - Supplier cancel = claim.checkPermission(player, ClaimPermission.Build, breakEvent); - if (cancel != null && breakEvent != null) - { - PreventBlockBreakEvent preventionEvent = new PreventBlockBreakEvent(breakEvent); - Bukkit.getPluginManager().callEvent(preventionEvent); - if (preventionEvent.isCancelled()) - { - cancel = null; - } - } - - if (cancel == null) return null; - - return cancel.get(); - } + Supplier result = ProtectionHelper.checkPermission(player, location, ClaimPermission.Build, breakEvent); + return result == null ? null : result.get(); } public void restoreChunk(Chunk chunk, int miny, boolean aggressiveMode, long delayInTicks, Player playerReceivingVisualization) diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java b/src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java index ffcb7ce..e138875 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java @@ -19,9 +19,9 @@ package me.ryanhamshire.GriefPrevention; import com.destroystokyo.paper.loottable.LootableBlockInventory; +import com.griefprevention.protection.ProtectionHelper; import me.ryanhamshire.GriefPrevention.events.ClaimInspectionEvent; import me.ryanhamshire.GriefPrevention.events.VisualizationEvent; -import org.bukkit.BanList; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Chunk; @@ -38,7 +38,6 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Levelled; import org.bukkit.block.data.Waterlogged; -import org.bukkit.command.Command; import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Animals; import org.bukkit.entity.Creature; @@ -47,7 +46,6 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Fish; import org.bukkit.entity.Hanging; -import org.bukkit.entity.Item; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Llama; import org.bukkit.entity.Mule; @@ -63,8 +61,6 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.CauldronLevelChangeEvent; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerBucketFillEvent; @@ -89,10 +85,7 @@ import org.bukkit.event.raid.RaidTriggerEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; -import org.bukkit.loot.Lootable; import org.bukkit.metadata.MetadataValue; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.BlockIterator; @@ -626,10 +619,10 @@ class PlayerEventHandler implements Listener //don't allow interaction with item frames or armor stands in claimed areas without build permission if (entity.getType() == EntityType.ARMOR_STAND || entity instanceof Hanging && !(entity instanceof ItemFrame)) { - String noBuildReason = instance.allowBuild(player, entity.getLocation(), Material.ITEM_FRAME); + Supplier noBuildReason = ProtectionHelper.checkPermission(player, entity.getLocation(), ClaimPermission.Build, event); if (noBuildReason != null) { - GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); + GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason.get()); event.setCancelled(true); return; } @@ -886,10 +879,10 @@ class PlayerEventHandler implements Listener } //make sure the player is allowed to build at the location - String noBuildReason = instance.allowBuild(player, block.getLocation(), Material.WATER); + Supplier noBuildReason = ProtectionHelper.checkPermission(player, block.getLocation(), ClaimPermission.Build, bucketEvent); if (noBuildReason != null) { - GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); + GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason.get()); bucketEvent.setCancelled(true); return; } @@ -972,24 +965,24 @@ class PlayerEventHandler implements Listener if (!instance.claimsEnabledForWorld(block.getWorld())) return; - //make sure the player is allowed to build at the location - String noBuildReason = instance.allowBuild(player, block.getLocation(), Material.AIR); - if (noBuildReason != null) - { - //exemption for cow milking (permissions will be handled by player interact with entity event instead) - Material blockType = block.getType(); - if (blockType == Material.AIR) - return; - if (blockType.isSolid()) - { - BlockData blockData = block.getBlockData(); - if (!(blockData instanceof Waterlogged) || !((Waterlogged) blockData).isWaterlogged()) - return; - } - - GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); - bucketEvent.setCancelled(true); + //exemption for cow milking (permissions will be handled by player interact with entity event instead) + Material blockType = block.getType(); + if (blockType == Material.AIR) return; + if (blockType.isSolid()) + { + BlockData blockData = block.getBlockData(); + if (!(blockData instanceof Waterlogged) || !((Waterlogged) blockData).isWaterlogged()) + return; + + //make sure the player is allowed to build at the location + Supplier noBuildReason = ProtectionHelper.checkPermission(player, block.getLocation(), ClaimPermission.Build, bucketEvent); + if (noBuildReason != null) + { + GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason.get()); + bucketEvent.setCancelled(true); + return; + } } } @@ -1305,15 +1298,13 @@ class PlayerEventHandler implements Listener || materialInHand == Material.FLINT_AND_STEEL || materialInHand == Material.INK_SAC || materialInHand == Material.GLOW_INK_SAC + || materialInHand == Material.HONEYCOMB || dyes.contains(materialInHand))) { - String noBuildReason = instance - .allowBuild(player, clickedBlock - .getLocation(), - clickedBlockType); + Supplier noBuildReason = ProtectionHelper.checkPermission(player, event.getClickedBlock().getLocation(), ClaimPermission.Build, event); if (noBuildReason != null) { - GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); + GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason.get()); event.setCancelled(true); } diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/events/PreventBlockBreakEvent.java b/src/main/java/me/ryanhamshire/GriefPrevention/events/PreventBlockBreakEvent.java index fee8190..03e4c72 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/events/PreventBlockBreakEvent.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/events/PreventBlockBreakEvent.java @@ -7,9 +7,10 @@ import org.bukkit.event.block.BlockBreakEvent; import org.jetbrains.annotations.NotNull; /** - * An {@link Event} called when GriefPrevention prevents a {@link BlockBreakEvent}. - * If cancelled, GriefPrevention will allow the event to complete normally. + * @deprecated Listen to {@link ClaimPermissionCheckEvent} and check if + * {@link ClaimPermissionCheckEvent#getTriggeringEvent()} {@code instanceof} {@link BlockBreakEvent}. */ +@Deprecated(forRemoval = true, since = "17.0.0") public class PreventBlockBreakEvent extends Event implements Cancellable { private final @NotNull BlockBreakEvent innerEvent;