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