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