From 7c4a85325c6781cce503c6f7a67b40dbd6b3fd94 Mon Sep 17 00:00:00 2001 From: "Patrick \"IPat\" Hein" Date: Tue, 18 May 2021 21:23:22 +0200 Subject: [PATCH] Added event handler for cauldron water level modification to prevent untrusted players interacting with a plot (#3035) * Added check for burning players using non-trusted plots cauldrons to extinguish themselves, causing the cauldron level to decrease * Cancelling burning of players without downscaling water instead of ignoring their burn status * Using Java 14 JEP 305 enhanced instanceOf Co-authored-by: NotMyFault * Players without permissions may not wash banners or armor now either. Rain modification is now permitted. * Extinguishing is now explicitly handled so that event handling for other plugins has the actual information of the new cauldron water level * Un-nestified the if-condition :) * Properly cancelled the event (since it is semantically cancelled) * (Actually) properly cancelled the event (since it is semantically cancelled) Co-authored-by: NotMyFault --- .../bukkit/listener/BlockEventListener.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java index af5de4247..3cd5df861 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java @@ -98,6 +98,7 @@ import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockRedstoneEvent; import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.event.block.CauldronLevelChangeEvent; import org.bukkit.event.block.EntityBlockFormEvent; import org.bukkit.event.block.LeavesDecayEvent; import org.bukkit.event.world.StructureGrowEvent; @@ -471,6 +472,58 @@ public class BlockEventListener implements Listener { } } + @EventHandler(priority = EventPriority.HIGHEST) + public void onCauldronEmpty(CauldronLevelChangeEvent event) { + Entity entity = event.getEntity(); + Location location = BukkitUtil.adapt(event.getBlock().getLocation()); + PlotArea area = location.getPlotArea(); + if (area == null) { + return; + } + Plot plot = area.getPlot(location); + // TODO Add flags for specific control over cauldron changes (rain, dripstone...) + switch (event.getReason()) { + case BANNER_WASH, ARMOR_WASH, EXTINGUISH -> { + if (entity instanceof Player player) { + BukkitPlayer plotPlayer = BukkitUtil.adapt(player); + if (plot != null) { + if (!plot.hasOwner()) { + if (Permissions.hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_INTERACT_UNOWNED)) { + return; + } + } else if (!plot.isAdded(plotPlayer.getUUID())) { + if (Permissions.hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_INTERACT_OTHER)) { + return; + } + } else { + return; + } + } else { + if (Permissions.hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_INTERACT_ROAD)) { + return; + } + if (this.worldEdit != null && plotPlayer.getAttribute("worldedit")) { + if (player.getInventory().getItemInMainHand().getType() == Material + .getMaterial(this.worldEdit.getConfiguration().wandItem)) { + return; + } + } + } + } + if (event.getReason() == CauldronLevelChangeEvent.ChangeReason.EXTINGUISH && event.getEntity() != null) { + event.getEntity().setFireTicks(0); + } + // Though the players fire ticks are modified, + // the cauldron water level change is cancelled and the event should represent that. + event.setCancelled(true); + } + default -> { + // Bucket empty, Bucket fill, Bottle empty, Bottle fill are already handled in PlayerInteract event + // Evaporation or Unknown reasons do not need to be cancelled as they are considered natural causes + } + } + } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBlockForm(BlockFormEvent event) { if (event instanceof EntityBlockFormEvent) {