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.configuration.Settings;
023import com.plotsquared.core.configuration.caption.TranslatableCaption;
024import com.plotsquared.core.events.Result;
025import com.plotsquared.core.events.TeleportCause;
026import com.plotsquared.core.location.Location;
027import com.plotsquared.core.permissions.Permission;
028import com.plotsquared.core.player.PlotPlayer;
029import com.plotsquared.core.plot.Plot;
030import com.plotsquared.core.plot.PlotArea;
031import com.plotsquared.core.util.EconHandler;
032import com.plotsquared.core.util.EventDispatcher;
033import com.plotsquared.core.util.PlotExpression;
034import com.plotsquared.core.util.task.TaskManager;
035import net.kyori.adventure.text.Component;
036import net.kyori.adventure.text.minimessage.tag.Tag;
037import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
038import org.checkerframework.checker.nullness.qual.NonNull;
039
040
041@CommandDeclaration(command = "delete",
042        permission = "plots.delete",
043        usage = "/plot delete",
044        aliases = {"dispose", "del"},
045        category = CommandCategory.CLAIMING,
046        requiredType = RequiredType.NONE,
047        confirmation = true)
048public class Delete extends SubCommand {
049
050    private final EventDispatcher eventDispatcher;
051    private final EconHandler econHandler;
052
053    @Inject
054    public Delete(
055            final @NonNull EventDispatcher eventDispatcher,
056            final @NonNull EconHandler econHandler
057    ) {
058        this.eventDispatcher = eventDispatcher;
059        this.econHandler = econHandler;
060    }
061
062    @Override
063    public boolean onCommand(final PlotPlayer<?> player, String[] args) {
064        Location location = player.getLocation();
065        final Plot plot = location.getPlotAbs();
066        if (plot == null) {
067            player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
068            return false;
069        }
070        if (!plot.hasOwner()) {
071            player.sendMessage(TranslatableCaption.of("info.plot_unowned"));
072            return false;
073        }
074        if (plot.getVolume() > Integer.MAX_VALUE) {
075            player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large"));
076            return false;
077        }
078        Result eventResult = this.eventDispatcher.callDelete(plot).getEventResult();
079        if (eventResult == Result.DENY) {
080            player.sendMessage(
081                    TranslatableCaption.of("events.event_denied"),
082                    TagResolver.resolver("value", Tag.inserting(Component.text("Delete")))
083            );
084            return true;
085        }
086        boolean force = eventResult == Result.FORCE;
087        if (!force && !plot.isOwner(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_DELETE)) {
088            player.sendMessage(TranslatableCaption.of("permission.no_plot_perms"));
089            return false;
090        }
091        final PlotArea plotArea = plot.getArea();
092        final java.util.Set<Plot> plots = plot.getConnectedPlots();
093        final int currentPlots = Settings.Limit.GLOBAL ?
094                player.getPlotCount() :
095                player.getPlotCount(location.getWorldName());
096        Runnable run = () -> {
097            if (plot.getRunning() > 0) {
098                player.sendMessage(TranslatableCaption.of("errors.wait_for_timer"));
099                return;
100            }
101            final long start = System.currentTimeMillis();
102            if (Settings.Teleport.ON_DELETE) {
103                plot.getPlayersInPlot().forEach(playerInPlot -> plot.teleportPlayer(playerInPlot, TeleportCause.COMMAND_DELETE,
104                        result -> {
105                        }
106                ));
107            }
108            boolean result = plot.getPlotModificationManager().deletePlot(player, () -> {
109                plot.removeRunning();
110                if (this.econHandler.isEnabled(plotArea)) {
111                    PlotExpression valueExr = plotArea.getPrices().get("sell");
112                    double value = plots.size() * valueExr.evaluate(currentPlots);
113                    if (value > 0d) {
114                        this.econHandler.depositMoney(player, value);
115                        player.sendMessage(
116                                TranslatableCaption.of("economy.added_balance"),
117                                TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(value))))
118                        );
119                    }
120                }
121                player.sendMessage(
122                        TranslatableCaption.of("working.deleting_done"),
123                        TagResolver.resolver(
124                                "amount",
125                                Tag.inserting(Component.text(String.valueOf(System.currentTimeMillis() - start)))
126                        ),
127                        TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
128                );
129                eventDispatcher.callPostDelete(plot);
130            });
131            if (result) {
132                plot.addRunning();
133            } else {
134                player.sendMessage(TranslatableCaption.of("errors.wait_for_timer"));
135            }
136        };
137        if (hasConfirmation(player)) {
138            CmdConfirm.addPending(player, getCommandString() + ' ' + plot.getId(), run);
139        } else {
140            TaskManager.runTask(run);
141        }
142        return true;
143    }
144
145}