From b656925e4ffbac693ea183a0e3f341f2be99b77c Mon Sep 17 00:00:00 2001 From: Video Date: Fri, 15 Apr 2022 05:28:32 -0600 Subject: [PATCH] Fixes two bugs related to commands - Fixes commands not showing up in their own dedicated section in /help - Fixes duplicate/disorganized commands in the HTTPD help page by overhauling it --- .../command/FreedomCommand.java | 52 ++++---- .../httpd/HTMLGenerationTools.java | 8 +- .../httpd/module/Module_help.java | 122 +++++++++++------- 3 files changed, 103 insertions(+), 79 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/FreedomCommand.java b/src/main/java/me/totalfreedom/totalfreedommod/command/FreedomCommand.java index 8d2dd093..017307a4 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/FreedomCommand.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/FreedomCommand.java @@ -13,19 +13,15 @@ import me.totalfreedom.totalfreedommod.TotalFreedomMod; import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.player.PlayerData; import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FUtil; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Server; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandMap; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.command.PluginCommand; -import org.bukkit.command.TabCompleter; +import org.bukkit.command.*; import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; import org.bukkit.util.StringUtil; import org.jetbrains.annotations.NotNull; @@ -40,7 +36,6 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter public static final String NO_PERMISSION = ChatColor.RED + "You do not have permission to execute this command."; public static final Timer timer = new Timer(); public static final Map COOLDOWN_TIMERS = new HashMap<>(); - private static CommandMap commandMap; protected final TotalFreedomMod plugin = TotalFreedomMod.getPlugin(); protected final Server server = plugin.getServer(); private final String name; @@ -69,34 +64,22 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter this.cooldown = perms.cooldown(); } - public static CommandMap getCommandMap() - { - if (commandMap == null) - { - try - { - final Field f = Bukkit.getServer().getPluginManager().getClass().getDeclaredField("commandMap"); - f.setAccessible(true); - commandMap = (CommandMap)f.get(Bukkit.getServer().getPluginManager()); - } - catch (Exception e) - { - e.printStackTrace(); - } - } - return commandMap; - } - public static FreedomCommand getFrom(Command command) { try { - return (FreedomCommand)(((PluginCommand)command).getExecutor()); + if (command instanceof FCommand) + { + return ((FCommand) command).getExecutor(); + } } catch (Exception ex) { + FLog.severe(ex); return null; } + + return null; } public static String getCommandPrefix() @@ -119,7 +102,7 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter { cmd.setUsage(this.usage); } - getCommandMap().register("totalfreedommod", cmd); + server.getCommandMap().register("totalfreedommod", cmd); cmd.setExecutor(this); } @@ -316,7 +299,7 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter return perms; } - private final class FCommand extends Command + public final class FCommand extends Command implements PluginIdentifiableCommand { private FreedomCommand cmd = null; @@ -325,6 +308,11 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter super(command); } + public final FreedomCommand getExecutor() + { + return cmd; + } + public void setExecutor(FreedomCommand cmd) { this.cmd = cmd; @@ -427,5 +415,11 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter } return new ArrayList<>(); } + + @Override + public @NotNull Plugin getPlugin() + { + return plugin; + } } } \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTMLGenerationTools.java b/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTMLGenerationTools.java index b682e8cc..a808ab53 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTMLGenerationTools.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTMLGenerationTools.java @@ -11,9 +11,15 @@ public class HTMLGenerationTools return "

" + escapeHtml4(data) + "

\r\n"; } + public static String heading(String data, String id, int level) + { + return "" + escapeHtml4(data) + + "\r\n"; + } + public static String heading(String data, int level) { - return "" + escapeHtml4(data) + "\r\n"; + return heading(data, null, level); } public static String list(Map map) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_help.java b/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_help.java index d19849be..dbaeddda 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_help.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_help.java @@ -1,52 +1,67 @@ package me.totalfreedom.totalfreedommod.httpd.module; import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; -import me.totalfreedom.totalfreedommod.TotalFreedomMod; import me.totalfreedom.totalfreedommod.command.FreedomCommand; import me.totalfreedom.totalfreedommod.httpd.NanoHTTPD; -import me.totalfreedom.totalfreedommod.rank.Displayable; +import me.totalfreedom.totalfreedommod.rank.Rank; import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandMap; import org.bukkit.command.PluginIdentifiableCommand; -import org.bukkit.command.SimpleCommandMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + import static me.totalfreedom.totalfreedommod.httpd.HTMLGenerationTools.heading; import static me.totalfreedom.totalfreedommod.httpd.HTMLGenerationTools.paragraph; import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4; public class Module_help extends HTTPDModule { - public Module_help(NanoHTTPD.HTTPSession session) { super(session); } - private static String buildDescription(Command command) + private static String buildDescription(@NotNull Command command) + { + return buildDescription(command.getName(), command.getDescription(), command.getUsage(), StringUtils.join(command.getAliases(), ", ")); + } + + private static String buildDescription(@NotNull FreedomCommand command) + { + return buildDescription(command.getName(), command.getDescription(), command.getUsage(), command.getAliases()); + } + + private static String buildDescription(@NotNull String name, @Nullable String description, @NotNull String usage, @NotNull String aliases) { StringBuilder sb = new StringBuilder(); sb.append( "
  • {$CMD_NAME} - Usage: {$CMD_USAGE}" - .replace("{$CMD_NAME}", escapeHtml4(command.getName().trim())) - .replace("{$CMD_USAGE}", escapeHtml4(command.getUsage().trim()))); + .replace("{$CMD_NAME}", escapeHtml4(name.trim())) + .replace("{$CMD_USAGE}", escapeHtml4(usage.trim()))); - if (!command.getAliases().isEmpty()) + if (!aliases.isEmpty()) { sb.append( " - Aliases: {$CMD_ALIASES}" - .replace("{$CMD_ALIASES}", escapeHtml4(StringUtils.join(command.getAliases(), ", ")))); + .replace("{$CMD_ALIASES}", escapeHtml4(aliases.trim()))); } - sb.append( - "
    {$CMD_DESC}
  • \r\n" - .replace("{$CMD_DESC}", escapeHtml4(command.getDescription().trim()))); + if (description != null) + { + sb.append( + "
    {$CMD_DESC}\r\n" + .replace("{$CMD_DESC}", escapeHtml4(description.trim()))); + } return sb.toString(); } @@ -54,11 +69,7 @@ public class Module_help extends HTTPDModule @Override public String getBody() { - final CommandMap map = FreedomCommand.getCommandMap(); - if (!(map instanceof SimpleCommandMap)) - { - return paragraph("Error loading commands."); - } + final CommandMap map = Bukkit.getCommandMap(); final StringBuilder responseBody = new StringBuilder() .append(heading("Command Help", 1)) @@ -66,7 +77,7 @@ public class Module_help extends HTTPDModule "This page is an automatically generated listing of all plugin commands that are currently live on the server. " + "Please note that it does not include vanilla server commands.")); - final Collection knownCommands = ((SimpleCommandMap)map).getCommands(); + final Collection knownCommands = map.getKnownCommands().values(); final Map> commandsByPlugin = new HashMap<>(); for (Command command : knownCommands) @@ -79,34 +90,47 @@ public class Module_help extends HTTPDModule List pluginCommands = commandsByPlugin.computeIfAbsent(pluginName, k -> Lists.newArrayList()); - pluginCommands.add(command); + if (!pluginCommands.contains(command)) + { + pluginCommands.add(command); + } } + final CommandComparator comparator = new CommandComparator(); + + // For every plugin... for (Map.Entry> entry : commandsByPlugin.entrySet()) { final String pluginName = entry.getKey(); final List commands = entry.getValue(); - commands.sort(new CommandComparator()); + // Sort them alphabetically + commands.sort(comparator); - responseBody.append(heading(pluginName, 2)).append("
      \r\n"); + responseBody.append(heading(pluginName, pluginName, 2)).append("
        \r\n"); - Displayable lastTfmCommandLevel = null; - for (Command command : commands) + if (!plugin.getName().equals(pluginName)) { - if (!TotalFreedomMod.pluginName.equals(pluginName)) - { - responseBody.append(buildDescription(command)); - continue; - } + commands.forEach((command) -> responseBody.append(buildDescription(command))); + } + else + { + Map> freedomCommands = new HashMap<>(); - Displayable tfmCommandLevel = Objects.requireNonNull(FreedomCommand.getFrom(command)).getPerms().level(); - if (lastTfmCommandLevel == null || lastTfmCommandLevel != tfmCommandLevel) - { - responseBody.append("
      \r\n").append(heading(tfmCommandLevel.getName(), 3)).append("
        \r\n"); - } - lastTfmCommandLevel = tfmCommandLevel; - responseBody.append(buildDescription(command)); + // Filters out non-TFM commands + commands.stream().filter((cmd) -> cmd instanceof FreedomCommand.FCommand).forEach((tfmCmd) -> { + Rank rank = FreedomCommand.getFrom(tfmCmd).getLevel(); + if (!freedomCommands.containsKey(rank)) + freedomCommands.put(rank, new ArrayList<>()); + freedomCommands.get(rank).add(FreedomCommand.getFrom(tfmCmd)); + }); + + // Finally dumps them to HTML + Arrays.stream(Rank.values()).filter(freedomCommands::containsKey) + .sorted(comparator::compare).forEach((rank -> { + responseBody.append("
      \r\n").append(heading(rank.getName(), 3)).append("
        \r\n"); + freedomCommands.get(rank).stream().sorted(comparator::compare).forEach((command) -> responseBody.append(buildDescription(command))); + })); } responseBody.append("
      \r\n"); @@ -118,7 +142,7 @@ public class Module_help extends HTTPDModule @Override public String getTitle() { - return "TotalFreedomMod :: Command Help"; + return plugin.getName() + " :: Command Help"; } @Override @@ -129,23 +153,23 @@ public class Module_help extends HTTPDModule public static class CommandComparator implements Comparator { - @Override public int compare(Command a, Command b) { - FreedomCommand ca = FreedomCommand.getFrom(a); - FreedomCommand cb = FreedomCommand.getFrom(b); + return a.getName().compareTo(b.getName()); + } - if (ca == null - || cb == null - || ca.getPerms() == null - || cb.getPerms() == null) - { - return a.getName().compareTo(b.getName()); - } + public int compare(FreedomCommand a, FreedomCommand b) + { + return a.getName().compareTo(b.getName()); + } - return ca.getPerms().level().getName().compareTo(cb.getPerms().level().getName()); + public int compare(Rank a, Rank b) + { + Integer levelA = a.getLevel(); + Integer levelB = b.getLevel(); + + return levelB.compareTo(levelA); } } - }