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.PlotSquared;
023import com.plotsquared.core.configuration.caption.StaticCaption;
024import com.plotsquared.core.configuration.caption.TranslatableCaption;
025import com.plotsquared.core.player.PlotPlayer;
026import com.plotsquared.core.plot.world.PlotAreaManager;
027import com.plotsquared.core.util.StringMan;
028import com.plotsquared.core.util.WorldUtil;
029import com.plotsquared.core.util.entity.EntityCategories;
030import com.plotsquared.core.util.entity.EntityCategory;
031import com.plotsquared.core.util.query.PlotQuery;
032import com.plotsquared.core.uuid.UUIDMapping;
033import com.sk89q.worldedit.world.entity.EntityType;
034import net.kyori.adventure.text.Component;
035import net.kyori.adventure.text.TextComponent;
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
040import java.util.Collection;
041import java.util.Comparator;
042import java.util.Locale;
043import java.util.Map;
044import java.util.Set;
045import java.util.stream.Collectors;
046import java.util.stream.Stream;
047
048@CommandDeclaration(command = "debug",
049        category = CommandCategory.DEBUG,
050        usage = "/plot debug",
051        permission = "plots.admin")
052public class Debug extends SubCommand {
053
054    private final PlotAreaManager plotAreaManager;
055    private final WorldUtil worldUtil;
056
057    @Inject
058    public Debug(
059            final @NonNull PlotAreaManager plotAreaManager,
060            final @NonNull WorldUtil worldUtil
061    ) {
062        this.plotAreaManager = plotAreaManager;
063        this.worldUtil = worldUtil;
064    }
065
066    @Override
067    public boolean onCommand(PlotPlayer<?> player, String[] args) {
068        if (args.length == 0) {
069            player.sendMessage(
070                    TranslatableCaption.of("commandconfig.command_syntax"),
071                    TagResolver.resolver(
072                            "value",
073                            Tag.inserting(Component.text("/plot debug <player | debug-players | entitytypes | msg>"))
074                    )
075            );
076        }
077        if (args.length > 0) {
078            if ("player".equalsIgnoreCase(args[0])) {
079                for (Map.Entry<String, Object> meta : player.getMeta().entrySet()) {
080                    player.sendMessage(StaticCaption.of("Key: " + meta.getKey() + " Value: " + meta
081                            .getValue()
082                            .toString() + " , "));
083                }
084                return true;
085            }
086        }
087        if (args.length > 0 && "uuids".equalsIgnoreCase(args[0])) {
088            final Collection<UUIDMapping> mappings = PlotSquared.get().getImpromptuUUIDPipeline().getAllImmediately();
089            player.sendMessage(
090                    TranslatableCaption.of("debug.cached_uuids"),
091                    TagResolver.resolver("value", Tag.inserting(Component.text(mappings.size())))
092            );
093            return true;
094        }
095        if (args.length > 0 && "debug-players".equalsIgnoreCase(args[0])) {
096            player.sendMessage(TranslatableCaption.of("debug.player_in_debugmode"));
097            for (final PlotPlayer<?> pp : PlotPlayer.getDebugModePlayers()) {
098                player.sendMessage(
099                        TranslatableCaption.of("debug.player_in_debugmode_list"),
100                        TagResolver.resolver("value", Tag.inserting(Component.text(pp.getName())))
101                );
102            }
103            return true;
104        }
105        if (args.length > 0 && "entitytypes".equalsIgnoreCase(args[0])) {
106            EntityCategories.init();
107            player.sendMessage(TranslatableCaption.of("debug.entity_categories"));
108            EntityCategory.REGISTRY.forEach(category -> {
109                final StringBuilder builder =
110                        new StringBuilder("<gray>-</gray> <gold>").append(category.getId()).append("</gold><gray>: <gold>");
111                for (final EntityType entityType : category.getAll()) {
112                    builder.append(entityType.getId()).append(" ");
113                }
114                builder.append("</gold>");
115                player.sendMessage(StaticCaption.of("<prefix>" + builder));
116            });
117            EntityType.REGISTRY.values().stream().sorted(Comparator.comparing(EntityType::getId))
118                    .forEach(entityType -> {
119                        long categoryCount = EntityCategory.REGISTRY.values().stream()
120                                .filter(category -> category.contains(entityType)).count();
121                        if (categoryCount > 0) {
122                            return;
123                        }
124                        player.sendMessage(StaticCaption.of("<prefix>" + entityType.getName() + " is in "
125                                + categoryCount + " categories"));
126                    });
127            return true;
128        }
129        Set<TranslatableCaption> captions = PlotSquared
130                .get()
131                .getCaptionMap(TranslatableCaption.DEFAULT_NAMESPACE)
132                .getCaptions();
133        TextComponent.Builder information = Component.text();
134        Component header = TranslatableCaption.of("debug.debug_header").toComponent(player)
135                .append(Component.newline());
136        String line = TranslatableCaption.of("debug.debug_line").getComponent(player) + "\n";
137        String section = TranslatableCaption.of("debug.debug_section").getComponent(player) + "\n";
138        information.append(header);
139        information.append(MINI_MESSAGE.deserialize(
140                section,
141                TagResolver.resolver("val", Tag.inserting(Component.text("PlotArea")))
142        ));
143        information.append(MINI_MESSAGE
144                .deserialize(
145                        line,
146                        TagResolver.builder()
147                                .tag("var", Tag.inserting(Component.text("Plot Worlds")))
148                                .tag(
149                                        "val",
150                                        Tag.inserting(Component.text(StringMan.join(
151                                                this.plotAreaManager.getAllPlotAreas(),
152                                                ", "
153                                        )))
154                                )
155                                .build()
156                ));
157        information.append(
158                MINI_MESSAGE.deserialize(
159                        line,
160                        TagResolver.builder()
161                                .tag("var", Tag.inserting(Component.text("Owned Plots")))
162                                .tag(
163                                        "val",
164                                        Tag.inserting(Component.text(PlotQuery.newQuery().allPlots().count()))
165                                )
166                                .build()
167                ));
168        information.append(MINI_MESSAGE.deserialize(
169                section,
170                TagResolver.resolver("val", Tag.inserting(Component.text("Messages")))
171        ));
172        information.append(MINI_MESSAGE.deserialize(
173                line,
174                TagResolver.builder()
175                        .tag("var", Tag.inserting(Component.text("Total Messages")))
176                        .tag(
177                                "val",
178                                Tag.inserting(Component.text(captions.size()))
179                        )
180                        .build()
181        ));
182        player.sendMessage(StaticCaption.of(MINI_MESSAGE.serialize(information.build())));
183        return true;
184    }
185
186    @Override
187    public Collection<Command> tab(final PlotPlayer<?> player, String[] args, boolean space) {
188        return Stream.of("debug-players", "entitytypes")
189                .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH)))
190                .map(value -> new Command(null, false, value, "plots.admin", RequiredType.NONE, null) {
191                }).collect(Collectors.toList());
192    }
193
194}