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.configuration.Settings;
022import com.plotsquared.core.configuration.caption.Caption;
023import com.plotsquared.core.configuration.caption.TranslatableCaption;
024import com.plotsquared.core.database.DBFunc;
025import com.plotsquared.core.permissions.Permission;
026import com.plotsquared.core.player.PlotPlayer;
027import com.plotsquared.core.plot.Plot;
028import com.plotsquared.core.plot.flag.implementations.HideInfoFlag;
029import com.plotsquared.core.util.TabCompletions;
030import net.kyori.adventure.text.Component;
031import net.kyori.adventure.text.minimessage.tag.Tag;
032import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
033
034import java.util.Collection;
035import java.util.Collections;
036import java.util.LinkedList;
037import java.util.List;
038import java.util.stream.Collectors;
039
040@CommandDeclaration(command = "info",
041        aliases = "i",
042        usage = "/plot info <id> [-f to force info]",
043        category = CommandCategory.INFO)
044public class Info extends SubCommand {
045
046    @Override
047    public boolean onCommand(final PlotPlayer<?> player, String[] args) {
048        Plot plot;
049        String arg;
050        if (args.length > 0) {
051            arg = args[0];
052            switch (arg) {
053                // TODO: (re?)implement /plot info inv. (it was never properly implemented)
054                case "trusted", "alias", "biome", "denied", "flags", "id", "size", "members", "creationdate", "seen", "owner", "rating", "likes" ->
055                        plot = Plot
056                                .getPlotFromString(player, null, false);
057                default -> {
058                    plot = Plot.getPlotFromString(player, arg, false);
059                    if (args.length == 2) {
060                        arg = args[1];
061                    } else {
062                        arg = null;
063                    }
064                }
065            }
066            if (plot == null) {
067                plot = player.getCurrentPlot();
068            }
069        } else {
070            arg = null;
071            plot = player.getCurrentPlot();
072        }
073        if (plot == null) {
074            player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
075            return false;
076        }
077
078        if (arg != null) {
079            if (args.length == 1) {
080                args = new String[0];
081            } else {
082                args = new String[]{args[1]};
083            }
084        }
085
086        // hide-info flag
087        if (plot.getFlag(HideInfoFlag.class)) {
088            boolean allowed = false;
089            for (final String argument : args) {
090                if (argument.equalsIgnoreCase("-f")) {
091                    if (!player
092                            .hasPermission(Permission.PERMISSION_AREA_INFO_FORCE.toString())) {
093                        player.sendMessage(
094                                TranslatableCaption.of("permission.no_permission"),
095                                TagResolver.resolver(
096                                        "node",
097                                        Tag.inserting(Permission.PERMISSION_AREA_INFO_FORCE)
098                                )
099                        );
100                        return true;
101                    }
102                    allowed = true;
103                    break;
104                }
105            }
106            if (!allowed) {
107                player.sendMessage(TranslatableCaption.of("info.plot_info_hidden"));
108                return true;
109            }
110        }
111
112        boolean hasOwner = plot.hasOwner();
113        // Wildcard player {added}
114        boolean containsEveryone = plot.getTrusted().contains(DBFunc.EVERYONE);
115        boolean trustedEveryone = plot.getMembers().contains(DBFunc.EVERYONE);
116        // Unclaimed?
117        if (!hasOwner && !containsEveryone && !trustedEveryone) {
118            player.sendMessage(
119                    TranslatableCaption.of("info.plot_info_unclaimed"),
120                    TagResolver.resolver(
121                            "plot",
122                            Tag.inserting(Component.text(plot.getId().getX() + ";" + plot.getId().getY()))
123                    )
124            );
125            return true;
126        }
127        Caption info = TranslatableCaption.of("info.plot_info_format");
128        boolean full;
129        if (arg != null) {
130            info = getCaption(arg);
131            if (info == null) {
132                if (Settings.Ratings.USE_LIKES) {
133                    player.sendMessage(TranslatableCaption.of("info.plot_info_categories.use_likes"));
134                } else {
135                    player.sendMessage(TranslatableCaption.of("info.plot_info_categories.use_rating"));
136                }
137                return false;
138            }
139            full = true;
140        } else {
141            full = false;
142        }
143        plot.format(info, player, full).thenAcceptAsync(player::sendMessage);
144        return true;
145    }
146
147    @Override
148    public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) {
149        final List<String> completions = new LinkedList<>();
150        if (player.hasPermission(Permission.PERMISSION_AREA_INFO_FORCE)) {
151            completions.add("-f");
152        }
153
154        final List<Command> commands = completions.stream().filter(completion -> completion
155                        .toLowerCase()
156                        .startsWith(args[0].toLowerCase()))
157                .map(completion -> new Command(null, true, completion, "", RequiredType.PLAYER, CommandCategory.INFO) {
158                }).collect(Collectors.toCollection(LinkedList::new));
159
160        if (player.hasPermission(Permission.PERMISSION_AREA_INFO_FORCE) && args[0].length() > 0) {
161            commands.addAll(TabCompletions.completePlayers(player, args[0], Collections.emptyList()));
162        }
163
164        return commands;
165    }
166
167    private Caption getCaption(String string) {
168        return switch (string) {
169            case "trusted" -> TranslatableCaption.of("info.plot_info_trusted");
170            case "alias" -> TranslatableCaption.of("info.plot_info_alias");
171            case "biome" -> TranslatableCaption.of("info.plot_info_biome");
172            case "denied" -> TranslatableCaption.of("info.plot_info_denied");
173            case "flags" -> TranslatableCaption.of("info.plot_info_flags");
174            case "id" -> TranslatableCaption.of("info.plot_info_id");
175            case "size" -> TranslatableCaption.of("info.plot_info_size");
176            case "members" -> TranslatableCaption.of("info.plot_info_members");
177            case "owner" -> TranslatableCaption.of("info.plot_info_owner");
178            case "rating" -> TranslatableCaption.of("info.plot_info_rating");
179            case "likes" -> TranslatableCaption.of("info.plot_info_likes");
180            case "seen" -> TranslatableCaption.of("info.plot_info_seen");
181            case "creationdate" -> TranslatableCaption.of("info.plot_info_creationdate");
182            default -> null;
183        };
184    }
185
186}