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 <mc.cache@web.de>

* 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 <mc.cache@web.de>
This commit is contained in:
Patrick "IPat" Hein 2021-05-18 21:23:22 +02:00 committed by GitHub
parent 94ba90d694
commit 7c4a85325c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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) {