001/* 002 * PlotSquared, a land and world management plugin for Minecraft. 003 * Copyright (C) IntellectualSites <https://intellectualsites.com> 004 * Copyright (C) IntellectualSites team and contributors 005 * 006 * This program is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <https://www.gnu.org/licenses/>. 018 */ 019package com.plotsquared.core.command; 020 021import com.google.inject.Inject; 022import com.plotsquared.core.backup.BackupManager; 023import com.plotsquared.core.configuration.Settings; 024import com.plotsquared.core.configuration.caption.TranslatableCaption; 025import com.plotsquared.core.events.PlotFlagRemoveEvent; 026import com.plotsquared.core.events.Result; 027import com.plotsquared.core.events.TeleportCause; 028import com.plotsquared.core.player.PlotPlayer; 029import com.plotsquared.core.plot.Plot; 030import com.plotsquared.core.plot.flag.PlotFlag; 031import com.plotsquared.core.plot.flag.implementations.AnalysisFlag; 032import com.plotsquared.core.plot.flag.implementations.DoneFlag; 033import com.plotsquared.core.queue.GlobalBlockQueue; 034import com.plotsquared.core.util.EventDispatcher; 035import com.plotsquared.core.util.task.RunnableVal2; 036import com.plotsquared.core.util.task.RunnableVal3; 037import com.plotsquared.core.util.task.TaskManager; 038import net.kyori.adventure.text.minimessage.Template; 039import org.checkerframework.checker.nullness.qual.NonNull; 040 041import java.util.concurrent.CompletableFuture; 042 043@CommandDeclaration(command = "clear", 044 requiredType = RequiredType.NONE, 045 permission = "plots.clear", 046 category = CommandCategory.APPEARANCE, 047 usage = "/plot clear", 048 aliases = "reset", 049 confirmation = true) 050public class Clear extends Command { 051 052 private final EventDispatcher eventDispatcher; 053 @SuppressWarnings({"unused", "FieldCanBeLocal"}) 054 private final GlobalBlockQueue blockQueue; 055 056 @Inject 057 public Clear( 058 final @NonNull EventDispatcher eventDispatcher, 059 final @NonNull GlobalBlockQueue blockQueue 060 ) { 061 super(MainCommand.getInstance(), true); 062 this.eventDispatcher = eventDispatcher; 063 this.blockQueue = blockQueue; 064 } 065 066 @Override 067 public CompletableFuture<Boolean> execute( 068 final PlotPlayer<?> player, String[] args, 069 RunnableVal3<Command, Runnable, Runnable> confirm, 070 RunnableVal2<Command, CommandResult> whenDone 071 ) throws CommandException { 072 if (args.length != 0) { 073 sendUsage(player); 074 return CompletableFuture.completedFuture(false); 075 } 076 final Plot plot = check(player.getCurrentPlot(), TranslatableCaption.of("errors.not_in_plot")); 077 Result eventResult = this.eventDispatcher.callClear(plot).getEventResult(); 078 if (eventResult == Result.DENY) { 079 player.sendMessage( 080 TranslatableCaption.of("events.event_denied"), 081 Template.of("value", "Clear") 082 ); 083 return CompletableFuture.completedFuture(true); 084 } 085 if (plot.getVolume() > Integer.MAX_VALUE) { 086 player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large")); 087 return CompletableFuture.completedFuture(true); 088 } 089 boolean force = eventResult == Result.FORCE; 090 checkTrue( 091 force || plot.isOwner(player.getUUID()) || player.hasPermission("plots.admin.command.clear"), 092 TranslatableCaption.of("permission.no_plot_perms") 093 ); 094 checkTrue(plot.getRunning() == 0, TranslatableCaption.of("errors.wait_for_timer")); 095 checkTrue( 096 force || !Settings.Done.RESTRICT_BUILDING || !DoneFlag.isDone(plot) || player.hasPermission("plots.continue"), 097 TranslatableCaption.of("done.done_already_done") 098 ); 099 confirm.run(this, () -> { 100 if (Settings.Teleport.ON_CLEAR) { 101 plot.getPlayersInPlot().forEach(playerInPlot -> plot.teleportPlayer(playerInPlot, TeleportCause.COMMAND_CLEAR, 102 result -> { 103 } 104 )); 105 } 106 BackupManager.backup(player, plot, () -> { 107 final long start = System.currentTimeMillis(); 108 boolean result = plot.getPlotModificationManager().clear(true, false, player, () -> { 109 TaskManager.runTask(() -> { 110 plot.removeRunning(); 111 // If the state changes, then mark it as no longer done 112 if (DoneFlag.isDone(plot)) { 113 PlotFlag<?, ?> plotFlag = 114 plot.getFlagContainer().getFlag(DoneFlag.class); 115 PlotFlagRemoveEvent event = this.eventDispatcher 116 .callFlagRemove(plotFlag, plot); 117 if (event.getEventResult() != Result.DENY) { 118 plot.removeFlag(event.getFlag()); 119 } 120 } 121 if (!plot.getFlag(AnalysisFlag.class).isEmpty()) { 122 PlotFlag<?, ?> plotFlag = 123 plot.getFlagContainer().getFlag(AnalysisFlag.class); 124 PlotFlagRemoveEvent event = this.eventDispatcher 125 .callFlagRemove(plotFlag, plot); 126 if (event.getEventResult() != Result.DENY) { 127 plot.removeFlag(event.getFlag()); 128 } 129 } 130 player.sendMessage( 131 TranslatableCaption.of("working.clearing_done"), 132 Template.of("amount", String.valueOf(System.currentTimeMillis() - start)), 133 Template.of("plot", plot.getId().toString()) 134 ); 135 }); 136 }); 137 if (!result) { 138 player.sendMessage(TranslatableCaption.of("errors.wait_for_timer")); 139 } else { 140 plot.addRunning(); 141 } 142 }); 143 }, null); 144 return CompletableFuture.completedFuture(true); 145 } 146 147}