From b4b7a2785f48be8132d4867ad507fa38d8f84719 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Mon, 10 Apr 2017 13:25:29 +1000 Subject: [PATCH] Improved worldedit help --- .../main/java/com/boydti/fawe/config/BBC.java | 7 + .../boydti/fawe/wrappers/WorldWrapper.java | 2 +- .../worldedit/command/BiomeCommands.java | 2 + .../worldedit/command/UtilityCommands.java | 134 ++++++++++++------ .../platform/AbstractPlayerActor.java | 1 - .../parametric/ParametricCallable.java | 8 ++ 6 files changed, 111 insertions(+), 43 deletions(-) diff --git a/core/src/main/java/com/boydti/fawe/config/BBC.java b/core/src/main/java/com/boydti/fawe/config/BBC.java index fa31fd29..d30feb40 100644 --- a/core/src/main/java/com/boydti/fawe/config/BBC.java +++ b/core/src/main/java/com/boydti/fawe/config/BBC.java @@ -214,6 +214,10 @@ public enum BBC { COMMAND_INVALID_SYNTAX("The command was not used properly (no more help available).", "WorldEdit.Command"), + HELP_HEADER_CATEGORIES("Command Types", "WorldEdit.Help"), + HELP_HEADER("Help: page %s0/%s1", "WorldEdit.Help"), + HELP_HEADER_FOOTER("&7Use: &8//help [type|command] [#]&7\n&7Wiki: https://git.io/vSKE5", "WorldEdit.Help"), + PROGRESS_MESSAGE("%s1/%s0 (%s2%) @%s3cps %s4s left", "Progress"), PROGRESS_FINISHED("[ Done! ]", "Progress"), @@ -318,6 +322,9 @@ public enum BBC { TIP_REGEN_0("Tip: Use a biome with /regen [biome]", "Tips"), TIP_REGEN_1("Tip: Use a seed with /regen [biome] [seed]", "Tips"), + TIP_BIOME_PATTERN("Tip: The &c#biome:forest&7 pattern can be used in any command", "Tips"), + TIP_BIOME_MASK("Tip: Restrict to a biome with the `$jungle` mask", "Tips"), + diff --git a/core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java b/core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java index 50b315ec..7b3ca39e 100644 --- a/core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java +++ b/core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java @@ -37,7 +37,7 @@ public class WorldWrapper extends LocalWorld { if (world == null) { return null; } - if (world instanceof WorldWrapper) { + if (world instanceof WorldWrapper) { return (WorldWrapper) world; } return new WorldWrapper(world); diff --git a/core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java index df010c92..e2aeaa34 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.command; import com.boydti.fawe.config.BBC; +import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.visitor.Fast2DIterator; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; @@ -223,6 +224,7 @@ public class BiomeCommands { Operations.completeLegacy(visitor); BBC.BIOME_CHANGED.send(player, visitor.getAffected()); + if (!FawePlayer.wrap(player).hasPermission("fawe.tips")) BBC.TIP_BIOME_PATTERN.or(BBC.TIP_BIOME_MASK).send(player); } public static Class inject() { diff --git a/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index ca097825..b2cd5dd9 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -27,6 +27,7 @@ import com.google.common.util.concurrent.AtomicDouble; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandException; +import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.Logging; import com.sk89q.worldedit.EditSession; @@ -62,17 +63,16 @@ import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.util.command.PrimaryAliasComparator; import com.sk89q.worldedit.util.command.binding.Text; import com.sk89q.worldedit.util.command.parametric.Optional; +import com.sk89q.worldedit.util.command.parametric.ParametricCallable; import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; -import com.sk89q.worldedit.util.formatting.Style; -import com.sk89q.worldedit.util.formatting.StyledFragment; -import com.sk89q.worldedit.util.formatting.component.Code; -import com.sk89q.worldedit.util.formatting.component.CommandListBox; import com.sk89q.worldedit.util.formatting.component.CommandUsageBox; import com.sk89q.worldedit.world.World; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -548,24 +548,25 @@ public class UtilityCommands { public static void help(CommandContext args, WorldEdit we, Actor actor) { CommandCallable callable = we.getPlatformManager().getCommandManager().getDispatcher(); - int page = 0; + CommandLocals locals = args.getLocals(); + + int page = -1; + String category = null; final int perPage = actor instanceof Player ? 8 : 20; // More pages for console int effectiveLength = args.argsLength(); // Detect page from args try { - if (args.argsLength() > 0) { + if (effectiveLength > 0) { page = args.getInteger(args.argsLength() - 1); if (page <= 0) { page = 1; } else { page--; } - effectiveLength--; } - } catch (NumberFormatException ignored) { - } + } catch (NumberFormatException ignored) {} boolean isRootLevel = true; List visited = new ArrayList(); @@ -585,14 +586,18 @@ public class UtilityCommands { callable = mapping.getCallable(); } else { if (isRootLevel) { - actor.printError(String.format("The command '%s' could not be found.", args.getString(i))); - return; + if (effectiveLength != 1) { + actor.printError(String.format("The command '%s' could not be found.", args.getString(i))); + return; + } + break; } else { actor.printError(String.format("The sub-command '%s' under '%s' could not be found.", command, Joiner.on(" ").join(visited))); return; } } + effectiveLength--; visited.add(args.getString(i)); isRootLevel = false; @@ -609,42 +614,89 @@ public class UtilityCommands { // Get a list of aliases List aliases = new ArrayList(dispatcher.getCommands()); - Collections.sort(aliases, new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN)); + List cmdStrings = new ArrayList<>(); + // Group by callable - // Calculate pagination - int offset = perPage * page; - int pageTotal = (int) Math.ceil(aliases.size() / (double) perPage); - - // Box - CommandListBox box = new CommandListBox(String.format("Help: page %d/%d ", page + 1, pageTotal)); - StyledFragment contents = box.getContents(); - StyledFragment tip = contents.createFragment(Style.GRAY); - - if (offset >= aliases.size()) { - tip.createFragment(Style.RED).append(String.format("There is no page %d (total number of pages is %d).", page + 1, pageTotal)).newLine(); - } else { - List list = aliases.subList(offset, Math.min(offset + perPage, aliases.size())); - - tip.append("Type "); - tip.append(new Code().append("//help ").append(" []")); - tip.append(" for more information.").newLine(); - - // Add each command - for (CommandMapping mapping : list) { + if (page == -1 || effectiveLength > 0) { + Map> grouped = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + for (CommandMapping mapping : aliases) { + CommandCallable c = mapping.getCallable(); + String group; + if (c instanceof ParametricCallable) { + group = ((ParametricCallable) c).getObject().getClass().getSimpleName().replaceAll("Commands", ""); + } else { + group = "Miscellaneous"; + } + ArrayList queue = grouped.get(group); + if (queue == null) { + queue = new ArrayList<>(); + grouped.put(group, queue); + } + queue.add(mapping); + } + if (effectiveLength > 0) { + String cat = args.getString(0); + aliases = grouped.get(cat); + if (aliases == null) { + actor.printError(String.format("The command or group '%s' could not be found.", cat)); + return; + } + page = Math.max(0, page); + } else { + StringBuilder message = new StringBuilder(); + String cmd = args.getCommand(); + message.append(BBC.getPrefix() + BBC.HELP_HEADER_CATEGORIES.s() + "\n"); StringBuilder builder = new StringBuilder(); - if (isRootLevel) { - builder.append("/"); + boolean first = true; + for (Map.Entry> entry : grouped.entrySet()) { + message.append("&a/" + cmd + " " + entry.getKey() + "&8 - &7" + entry.getValue().size() + "\n"); } - if (!visited.isEmpty()) { - builder.append(Joiner.on(" ").join(visited)); - builder.append(" "); - } - builder.append(mapping.getPrimaryAlias()); - box.appendCommand(builder.toString(), mapping.getDescription().getDescription()); + message.append(BBC.HELP_HEADER_FOOTER.s()); + actor.print(BBC.color(message.toString())); + return; } } +// else + { + Collections.sort(aliases, new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN)); - actor.printRaw(ColorCodeBuilder.asColorCodes(box)); + // Calculate pagination + int offset = perPage * page; + int pageTotal = (int) Math.ceil(aliases.size() / (double) perPage); + + // Box + StringBuilder message = new StringBuilder(); + + if (offset >= aliases.size()) { + message.append("&c").append(String.format("There is no page %d (total number of pages is %d).", page + 1, pageTotal)); + } else { + message.append(BBC.getPrefix() + BBC.HELP_HEADER.format(page + 1, pageTotal) + "\n"); + List list = aliases.subList(offset, Math.min(offset + perPage, aliases.size())); + + boolean first = true; + // Add each command + for (CommandMapping mapping : list) { + CommandCallable c = mapping.getCallable(); + boolean perm = c.testPermission(locals); +// String primary = BBC.color(perm ? "&2" : "&4"); + String color = BBC.color(perm ? "&a" : "&c"); + message.append(color); + if (isRootLevel) { + message.append("/"); + } + if (!visited.isEmpty()) { + message.append(Joiner.on(" ").join(visited)); + message.append(" "); + } + message.append(mapping.getPrimaryAlias()); + message.append("&8 - &7"); + message.append(mapping.getDescription().getDescription()); + message.append('\n'); + } + message.append(BBC.HELP_HEADER_FOOTER.f()); + } + actor.print(BBC.color(message.toString())); + } } else { CommandUsageBox box = new CommandUsageBox(callable, Joiner.on(" ").join(visited)); actor.printRaw(ColorCodeBuilder.asColorCodes(box)); diff --git a/core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java index ba58f0e4..d0c8d9cc 100644 --- a/core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java +++ b/core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -118,7 +118,6 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { ++y; } - System.out.println("Not found"); } @Override diff --git a/core/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java b/core/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java index 945e3e32..52eb7ec3 100644 --- a/core/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java +++ b/core/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java @@ -268,6 +268,14 @@ public class ParametricCallable implements CommandCallable { return true; } + public Object getObject() { + return object; + } + + public Method getMethod() { + return method; + } + @Override public List getSuggestions(String arguments, CommandLocals locals) throws CommandException { String[] split = CommandContext.split("ignored" + " " + arguments);