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.caption.StaticCaption; 022import com.plotsquared.core.configuration.caption.TranslatableCaption; 023import com.plotsquared.core.player.PlotPlayer; 024import com.plotsquared.core.util.MathMan; 025import com.plotsquared.core.util.StringMan; 026import com.plotsquared.core.util.helpmenu.HelpMenu; 027import com.plotsquared.core.util.task.RunnableVal2; 028import com.plotsquared.core.util.task.RunnableVal3; 029import net.kyori.adventure.text.Component; 030import net.kyori.adventure.text.TextComponent; 031import net.kyori.adventure.text.minimessage.tag.Tag; 032import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; 033 034import java.util.ArrayList; 035import java.util.Collection; 036import java.util.List; 037import java.util.Locale; 038import java.util.concurrent.CompletableFuture; 039 040@CommandDeclaration(command = "help", 041 aliases = "?", 042 category = CommandCategory.INFO, 043 usage = "help [category | #]", 044 permission = "plots.use") 045public class Help extends Command { 046 047 public Help(Command parent) { 048 super(parent, true); 049 } 050 051 @Override 052 public boolean canExecute(PlotPlayer<?> player, boolean message) { 053 return true; 054 } 055 056 @Override 057 public CompletableFuture<Boolean> execute( 058 PlotPlayer<?> player, String[] args, 059 RunnableVal3<Command, Runnable, Runnable> confirm, 060 RunnableVal2<Command, CommandResult> whenDone 061 ) { 062 switch (args.length) { 063 case 0 -> { 064 return displayHelp(player, null, 0); 065 } 066 case 1 -> { 067 if (MathMan.isInteger(args[0])) { 068 try { 069 return displayHelp(player, null, Integer.parseInt(args[0])); 070 } catch (NumberFormatException ignored) { 071 return displayHelp(player, null, 1); 072 } 073 } else { 074 return displayHelp(player, args[0], 1); 075 } 076 } 077 case 2 -> { 078 if (MathMan.isInteger(args[1])) { 079 try { 080 return displayHelp(player, args[0], Integer.parseInt(args[1])); 081 } catch (NumberFormatException ignored) { 082 return displayHelp(player, args[0], 1); 083 } 084 } 085 return CompletableFuture.completedFuture(false); 086 } 087 default -> sendUsage(player); 088 } 089 return CompletableFuture.completedFuture(true); 090 } 091 092 public CompletableFuture<Boolean> displayHelp( 093 final PlotPlayer<?> player, final String catRaw, 094 final int page 095 ) { 096 return CompletableFuture.supplyAsync(() -> { 097 String cat = catRaw; 098 099 CommandCategory catEnum = null; 100 if (cat != null) { 101 if (!"all".equalsIgnoreCase(cat)) { 102 for (CommandCategory c : CommandCategory.values()) { 103 if (StringMan.isEqualIgnoreCaseToAny(cat, c.name(), c.toString())) { 104 catEnum = c; 105 cat = c.name(); 106 break; 107 } 108 } 109 if (catEnum == null) { 110 cat = null; 111 } 112 } 113 } 114 if (cat == null && page == 0) { 115 TextComponent.Builder builder = Component.text(); 116 builder.append(MINI_MESSAGE.deserialize(TranslatableCaption.of("help.help_header").getComponent(player))); 117 for (CommandCategory c : CommandCategory.values()) { 118 if (!c.canAccess(player)) { 119 continue; 120 } 121 builder.append(Component.newline()).append(MINI_MESSAGE 122 .deserialize( 123 TranslatableCaption.of("help.help_info_item").getComponent(player), 124 TagResolver.builder() 125 .tag("command", Tag.inserting(Component.text("/plot help"))) 126 .tag("category", Tag.inserting(Component.text(c.name().toLowerCase()))) 127 .tag("category_desc", Tag.inserting(c.toComponent(player))) 128 .build() 129 )); 130 } 131 builder.append(Component.newline()).append(MINI_MESSAGE 132 .deserialize( 133 TranslatableCaption.of("help.help_info_item").getComponent(player), 134 TagResolver.builder() 135 .tag("command", Tag.inserting(Component.text("/plot help"))) 136 .tag("category", Tag.inserting(Component.text("all"))) 137 .tag( 138 "category_desc", 139 Tag.inserting(TranslatableCaption 140 .of("help.help_display_all_commands") 141 .toComponent(player)) 142 ) 143 .build() 144 )); 145 builder.append(Component.newline()).append(MINI_MESSAGE.deserialize(TranslatableCaption 146 .of("help.help_footer") 147 .getComponent(player))); 148 player.sendMessage(StaticCaption.of(MINI_MESSAGE.serialize(builder.asComponent()))); 149 return true; 150 } 151 new HelpMenu(player).setCategory(catEnum).getCommands().generateMaxPages().generatePage( 152 page - 1, 153 getParent().toString(), 154 player 155 ) 156 .render(); 157 return true; 158 }); 159 } 160 161 @Override 162 public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) { 163 final String argument = args[0].toLowerCase(Locale.ENGLISH); 164 List<Command> result = new ArrayList<>(); 165 166 for (final CommandCategory category : CommandCategory.values()) { 167 if (!category.canAccess(player)) { 168 continue; 169 } 170 String name = category.name().toLowerCase(); 171 if (!name.startsWith(argument)) { 172 continue; 173 } 174 result.add(new Command(null, false, name, "", RequiredType.NONE, null) { 175 }); 176 } 177 // add the category "all" 178 if ("all".startsWith(argument)) { 179 result.add(new Command(null, false, "all", "", RequiredType.NONE, null) { 180 }); 181 } 182 return result; 183 } 184 185}