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 c0a76c8232..82dc220bf2 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/BlockEventListener.java @@ -152,6 +152,11 @@ public void blockCreate(BlockPlaceEvent event) { BukkitPlayer pp = BukkitUtil.adapt(player); Plot plot = area.getPlot(location); if (plot != null) { + // Prevent block placement during pending deletion + if (plot.getMeta("pendingDelete") != null) { + event.setCancelled(true); + return; + } if (area.notifyIfOutsideBuildArea(pp, location.getY())) { event.setCancelled(true); return; @@ -230,6 +235,11 @@ public void blockDestroy(BlockBreakEvent event) { Plot plot = area.getPlot(location); if (plot != null) { BukkitPlayer plotPlayer = BukkitUtil.adapt(player); + // Prevent block breaking during pending deletion + if (plot.getMeta("pendingDelete") != null) { + event.setCancelled(true); + return; + } // == rather than <= as we only care about the "ground level" not being destroyed if (event.getBlock().getY() == area.getMinGenHeight()) { if (!plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL)) { diff --git a/Core/src/main/java/com/plotsquared/core/command/Delete.java b/Core/src/main/java/com/plotsquared/core/command/Delete.java index d7f6c6ab9a..ef5823223a 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Delete.java +++ b/Core/src/main/java/com/plotsquared/core/command/Delete.java @@ -91,11 +91,19 @@ public boolean onCommand(final PlotPlayer player, String[] args) { final int currentPlots = Settings.Limit.GLOBAL ? player.getPlotCount() : player.getPlotCount(plot.getWorldName()); + Runnable run = () -> { if (plot.getRunning() > 0) { + for (Plot connectedPlot : plots) { + connectedPlot.deleteMeta("pendingDelete"); + } player.sendMessage(TranslatableCaption.of("errors.wait_for_timer")); return; } + + for (Plot connectedPlot : plots) { + connectedPlot.setMeta("pendingDelete", true); + } final long start = System.currentTimeMillis(); if (Settings.Teleport.ON_DELETE) { plot.getPlayersInPlot().forEach(playerInPlot -> plot.teleportPlayer(playerInPlot, TeleportCause.COMMAND_DELETE, @@ -104,32 +112,47 @@ public boolean onCommand(final PlotPlayer player, String[] args) { )); } boolean result = plot.getPlotModificationManager().deletePlot(player, () -> { - plot.removeRunning(); - if (this.econHandler.isEnabled(plotArea)) { - PlotExpression valueExr = plotArea.getPrices().get("sell"); - double value = plots.size() * valueExr.evaluate(currentPlots); - if (value > 0d) { - this.econHandler.depositMoney(player, value); - player.sendMessage( - TranslatableCaption.of("economy.added_balance"), - TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(value)))) - ); + try { + // Clear pending delete metadata now that deletion is actually starting + for (Plot connectedPlot : plots) { + connectedPlot.deleteMeta("pendingDelete"); } + plot.removeRunning(); + if (this.econHandler.isEnabled(plotArea)) { + PlotExpression valueExr = plotArea.getPrices().get("sell"); + double value = plots.size() * valueExr.evaluate(currentPlots); + if (value > 0d) { + this.econHandler.depositMoney(player, value); + player.sendMessage( + TranslatableCaption.of("economy.added_balance"), + TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(value)))) + ); + } + } + player.sendMessage( + TranslatableCaption.of("working.deleting_done"), + TagResolver.resolver( + "amount", + Tag.inserting(Component.text(String.valueOf(System.currentTimeMillis() - start))) + ), + TagResolver.resolver("world", Tag.inserting(Component.text(plotArea.getWorldName()))), + TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString()))) + ); + eventDispatcher.callPostDelete(plot); + } catch (Throwable e) { + // ... or if something went wrong + for (Plot connectedPlot : plots) { + connectedPlot.deleteMeta("pendingDelete"); + } + throw e; } - player.sendMessage( - TranslatableCaption.of("working.deleting_done"), - TagResolver.resolver( - "amount", - Tag.inserting(Component.text(String.valueOf(System.currentTimeMillis() - start))) - ), - TagResolver.resolver("world", Tag.inserting(Component.text(plotArea.getWorldName()))), - TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString()))) - ); - eventDispatcher.callPostDelete(plot); }); if (result) { plot.addRunning(); } else { + for (Plot connectedPlot : plots) { + connectedPlot.deleteMeta("pendingDelete"); + } player.sendMessage(TranslatableCaption.of("errors.wait_for_timer")); } };