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.plotsquared.core.PlotSquared;
022import com.plotsquared.core.configuration.Settings;
023import com.plotsquared.core.configuration.caption.TranslatableCaption;
024import com.plotsquared.core.location.Location;
025import com.plotsquared.core.permissions.Permission;
026import com.plotsquared.core.player.PlotPlayer;
027import com.plotsquared.core.plot.Plot;
028import com.plotsquared.core.util.MathMan;
029import com.plotsquared.core.util.query.PlotQuery;
030import net.kyori.adventure.text.minimessage.Template;
031
032import java.util.ArrayList;
033import java.util.Collection;
034import java.util.Collections;
035import java.util.List;
036import java.util.concurrent.TimeoutException;
037
038@CommandDeclaration(command = "alias",
039        permission = "plots.alias",
040        usage = "/plot alias <set | remove> <alias>",
041        aliases = {"setalias", "sa", "name", "rename", "setname", "seta", "nameplot"},
042        category = CommandCategory.SETTINGS,
043        requiredType = RequiredType.PLAYER)
044public class Alias extends SubCommand {
045
046    private static final Command SET_COMMAND = new Command(null, false, "set", null, RequiredType.NONE, null) {
047    };
048    private static final Command REMOVE_COMMAND = new Command(null, false, "remove", null, RequiredType.NONE, null) {
049    };
050
051    @Override
052    public boolean onCommand(PlotPlayer<?> player, String[] args) {
053
054        if (args.length == 0) {
055            sendUsage(player);
056            return false;
057        }
058
059        Location location = player.getLocation();
060        Plot plot = location.getPlotAbs();
061        if (plot == null) {
062            player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
063            return false;
064        }
065
066        if (!plot.hasOwner()) {
067            player.sendMessage(TranslatableCaption.of("working.plot_not_claimed"));
068            return false;
069        }
070
071        boolean result = false;
072
073        boolean owner = plot.isOwner(player.getUUID());
074        boolean permission;
075        boolean admin;
076        switch (args[0].toLowerCase()) {
077            case "set" -> {
078                if (args.length != 2) {
079                    sendUsage(player);
080                    return false;
081                }
082                permission = isPermitted(player, Permission.PERMISSION_ALIAS_SET);
083                admin = isPermitted(player, Permission.PERMISSION_ADMIN_ALIAS_SET);
084                if (!admin && !owner) {
085                    player.sendMessage(TranslatableCaption.of("permission.no_plot_perms"));
086                    return false;
087                }
088                if (permission) { // is either admin or owner
089                    setAlias(player, plot, args[1]);
090                    return true;
091                } else {
092                    player.sendMessage(
093                            TranslatableCaption.of("permission.no_permission"),
094                            Template.of("node", String.valueOf(Permission.PERMISSION_ALIAS_SET))
095                    );
096                }
097            }
098            case "remove" -> {
099                permission = isPermitted(player, Permission.PERMISSION_ALIAS_REMOVE);
100                admin = isPermitted(player, Permission.PERMISSION_ADMIN_ALIAS_REMOVE);
101                if (!admin && !owner) {
102                    player.sendMessage(TranslatableCaption.of("permission.no_plot_perms"));
103                    return false;
104                }
105                if (permission) {
106                    result = removeAlias(player, plot);
107                } else {
108                    player.sendMessage(
109                            TranslatableCaption.of("permission.no_permission"),
110                            Template.of("node", String.valueOf(Permission.PERMISSION_ALIAS_REMOVE))
111                    );
112                }
113            }
114            default -> {
115                sendUsage(player);
116                result = false;
117            }
118        }
119
120        return result;
121    }
122
123    @Override
124    public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) {
125        final List<Command> commands = new ArrayList<>(2);
126        if (args.length == 1) {
127            if ("set".startsWith(args[0])) {
128                commands.add(SET_COMMAND);
129            }
130            if ("remove".startsWith(args[0])) {
131                commands.add(REMOVE_COMMAND);
132            }
133            return commands;
134        }
135        return Collections.emptySet();
136    }
137
138    private void setAlias(PlotPlayer<?> player, Plot plot, String alias) {
139        if (alias.isEmpty()) {
140            sendUsage(player);
141        } else if (alias.length() >= 50) {
142            player.sendMessage(TranslatableCaption.of("alias.alias_too_long"));
143        } else if (MathMan.isInteger(alias)) {
144            player.sendMessage(TranslatableCaption.of("flag.not_valid_value")); // TODO this is obviously wrong
145        } else {
146            if (PlotQuery.newQuery().inArea(plot.getArea())
147                    .withAlias(alias)
148                    .anyMatch()) {
149                player.sendMessage(
150                        TranslatableCaption.of("alias.alias_is_taken"),
151                        Template.of("alias", alias)
152                );
153                return;
154            }
155            if (Settings.UUID.OFFLINE) {
156                plot.setAlias(alias);
157                player.sendMessage(TranslatableCaption.of("alias.alias_set_to"), Template.of("alias", alias));
158                return;
159            }
160            PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> {
161                if (throwable instanceof TimeoutException) {
162                    player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout"));
163                } else if (uuid != null) {
164                    player.sendMessage(
165                            TranslatableCaption.of("alias.alias_is_taken"),
166                            Template.of("alias", alias)
167                    );
168                } else {
169                    plot.setAlias(alias);
170                    player.sendMessage(
171                            TranslatableCaption.of("alias.alias_set_to"),
172                            Template.of("alias", alias)
173                    );
174                }
175            }));
176        }
177    }
178
179    private boolean removeAlias(PlotPlayer<?> player, Plot plot) {
180        String alias = plot.getAlias();
181        if (!plot.getAlias().isEmpty()) {
182            player.sendMessage(
183                    TranslatableCaption.of("alias.alias_removed"),
184                    Template.of("alias", alias)
185            );
186        } else {
187            player.sendMessage(
188                    TranslatableCaption.of("alias.no_alias_set")
189            );
190        }
191        plot.setAlias(null);
192        return true;
193    }
194
195    private boolean isPermitted(PlotPlayer<?> player, Permission permission) {
196        return player.hasPermission(permission);
197    }
198
199}