package dev.plex.request.impl; import dev.plex.HTTPDModule; import dev.plex.command.PlexCommand; import dev.plex.request.AbstractServlet; import dev.plex.request.GetMapping; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandMap; import org.bukkit.command.PluginIdentifiableCommand; public class CommandsEndpoint extends AbstractServlet { private String cachedHtml; public CommandsEndpoint(HTTPDModule module) { super(module); } @GetMapping(endpoint = "/api/commands/") public String getCommands(HttpServletRequest request, HttpServletResponse response) { if (cachedHtml == null) { cachedHtml = buildSections(); } String file = readFile(this.getClass().getResourceAsStream("/httpd/commands.html")); file = file.replace("${commands}", cachedHtml); return file; } private String buildSections() { final SortedMap> commandMap = new TreeMap<>(); List plexCommands = commandMap.computeIfAbsent("Plex", k -> new ArrayList<>()); for (PlexCommand command : module.api().commands().registeredCommands()) { plexCommands.add(CommandInfo.from(command)); } final CommandMap map = Bukkit.getCommandMap(); for (Command command : map.getKnownCommands().values()) { String plugin = "Bukkit"; if (command instanceof PluginIdentifiableCommand pic) { plugin = pic.getPlugin().getName(); } List pluginCommands = commandMap.computeIfAbsent(plugin, k -> new ArrayList<>()); CommandInfo commandInfo = CommandInfo.from(command); if (!pluginCommands.contains(commandInfo)) { pluginCommands.add(commandInfo); } } StringBuilder sb = new StringBuilder(); for (String key : commandMap.keySet()) { List commands = commandMap.get(key); commands.sort(Comparator.comparing(CommandInfo::name)); sb.append(renderSection(key, commands)); } return sb.toString(); } private static String renderSection(String plugin, List commands) { StringBuilder cards = new StringBuilder(); for (CommandInfo command : commands) { cards.append(renderCard(command)); } String name = escapeHtml(plugin); return """
%s %d %s
%s
""".formatted(name, name, commands.size(), commands.size() == 1 ? "command" : "commands", cards); } private static String renderCard(CommandInfo command) { String name = escapeHtml(command.name()); String aliases = command.aliases().isEmpty() ? "" : String.join(", ", command.aliases()); String description = command.description().isBlank() ? "" : escapeHtml(command.description()); String usage = cleanUsage(command.usage()); String permission = cleanPermission(command.permission()); String aliasMarkup = aliases.isEmpty() ? "" : "/ " + escapeHtml(aliases) + ""; String descMarkup = description.isEmpty() ? "

No description provided.

" : "

" + description + "

"; String searchBlob = (name + " " + aliases + " " + description + " " + permission).toLowerCase(); return """
/%s %s
%s
usage
%s
perm
%s
""".formatted(searchBlob, name, aliasMarkup, descMarkup, usage, permission); } private static String cleanPermission(String permission) { if (permission == null || permission.isBlank()) return "N/A"; return escapeHtml(permission).replace(";", "
"); } private static String cleanUsage(String usage) { if (usage == null || usage.isBlank()) return "Not provided"; String escaped = escapeHtml(usage); return escaped.startsWith("/") ? escaped : "/" + escaped; } private static String escapeHtml(String s) { if (s == null) return ""; return s.replace("&", "&") .replace("<", "<") .replace(">", ">") .replace("\"", """); } private record CommandInfo(String name, List aliases, String description, String usage, String permission) { private static CommandInfo from(PlexCommand command) { return new CommandInfo(command.getName(), command.getAliases(), command.getDescription(), command.getUsage(), command.getPermission()); } private static CommandInfo from(Command command) { List aliases = command.getAliases() == null ? List.of() : command.getAliases(); return new CommandInfo(command.getName(), aliases, command.getDescription(), command.getUsage(), command.getPermission()); } } }