From 302d089d55e7deabc3bd0eb4e1de8da7257536ce Mon Sep 17 00:00:00 2001 From: sk89q Date: Sun, 29 Jun 2014 01:39:56 -0700 Subject: [PATCH 01/21] Assembly needs to go after the shader .jar is built. --- pom.xml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index b9d717b8b..89e1d0efc 100644 --- a/pom.xml +++ b/pom.xml @@ -355,24 +355,6 @@ - - - maven-assembly-plugin - 2.2-beta-2 - - ${basedir}/src/main/assembly/default.xml - - - - release - package - - single - - - - - org.apache.maven.plugins @@ -396,6 +378,24 @@ + + + maven-assembly-plugin + 2.2-beta-2 + + ${basedir}/src/main/assembly/default.xml + + + + release + package + + single + + + + + org.apache.maven.plugins From d4dde8c4a64209d987f009e33462a20a1b2bbe45 Mon Sep 17 00:00:00 2001 From: sk89q Date: Sun, 29 Jun 2014 01:43:30 -0700 Subject: [PATCH 02/21] [Bukkit] Handle onDisable() better when onEnable() fails. --- .../com/sk89q/worldedit/bukkit/WorldEditPlugin.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index 9f0beff64..0cdaf470d 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -156,10 +156,12 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter { */ @Override public void onDisable() { - controller.clearSessions(); - controller.getPlatformManager().unregister(server); - config.unload(); - server.unregisterCommands(); + if (controller != null) { + controller.clearSessions(); + controller.getPlatformManager().unregister(server); + config.unload(); + server.unregisterCommands(); + } this.getServer().getScheduler().cancelTasks(this); } From ad9b8ce3b1987c495c6661affc54e99a714750df Mon Sep 17 00:00:00 2001 From: sk89q Date: Sun, 29 Jun 2014 12:28:27 -0700 Subject: [PATCH 03/21] [Bukkit] Made BukkitCommandSender public again. CommandHelper subclasses this, although whether things will work properly after this change is to be said. Fixes WORLDEDIT-3136. --- .../com/sk89q/worldedit/bukkit/BukkitCommandSender.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java index a8dc5adc2..74dfc2e41 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java @@ -19,8 +19,6 @@ package com.sk89q.worldedit.bukkit; -import com.sk89q.worldedit.LocalWorld; -import com.sk89q.worldedit.PlayerNeededException; import com.sk89q.worldedit.WorldEditPermissionException; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.internal.cui.CUIEvent; @@ -32,12 +30,12 @@ import java.io.File; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -class BukkitCommandSender implements Actor { +public class BukkitCommandSender implements Actor { private CommandSender sender; private WorldEditPlugin plugin; - BukkitCommandSender(WorldEditPlugin plugin, CommandSender sender) { + public BukkitCommandSender(WorldEditPlugin plugin, CommandSender sender) { checkNotNull(plugin); checkNotNull(sender); checkArgument(!(sender instanceof Player), "Cannot wrap a player"); From 0a5a1e1b010dc1170900c1d88f0a6e02a0efa368 Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 21:00:02 -0700 Subject: [PATCH 04/21] Fixed typo in //curve's help. Fixes WORLDEDIT-3025. --- src/main/java/com/sk89q/worldedit/command/RegionCommands.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/src/main/java/com/sk89q/worldedit/command/RegionCommands.java index 5534df372..e8dd44277 100644 --- a/src/main/java/com/sk89q/worldedit/command/RegionCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -131,7 +131,7 @@ public class RegionCommands { desc = "Draws a spline through selected points", help = "Draws a spline through selected points.\n" + - "Can only be uesd with convex polyhedral selections.\n" + + "Can only be used with convex polyhedral selections.\n" + "Flags:\n" + " -h generates only a shell", flags = "h", From d1f5beb961b9d4d847cf7e2543bc0b1141b21b6c Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 21:48:26 -0700 Subject: [PATCH 05/21] Shortened /schematic command descriptions. --- .../sk89q/worldedit/command/SchematicCommands.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index 61ea46fb8..2b0d25526 100644 --- a/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -54,8 +54,8 @@ public class SchematicCommands { @Command( aliases = { "load", "l" }, usage = "[format] ", - desc = "Load a schematic into your clipboard", - help = "Load a schematic into your clipboard\n" + + desc = "Load a file into your clipboard", + help = "Load a schematic file into your clipboard\n" + "Format is a format from \"//schematic formats\"\n" + "If the format is not provided, WorldEdit will\n" + "attempt to automatically detect the format of the schematic", @@ -121,8 +121,8 @@ public class SchematicCommands { @Command( aliases = { "save", "s" }, usage = "[format] ", - desc = "Save a schematic into your clipboard", - help = "Save a schematic into your clipboard\n" + + desc = "Save your clipboard to file", + help = "Save your clipboard to file\n" + "Format is a format from \"//schematic formats\"\n", min = 1, max = 2 @@ -181,7 +181,7 @@ public class SchematicCommands { @Command( aliases = { "delete", "d" }, usage = "", - desc = "Delete a schematic from the schematic list", + desc = "Delete a saved schematic", help = "Delete a schematic from the schematic list", min = 1, max = 1 @@ -210,7 +210,7 @@ public class SchematicCommands { @Command( aliases = {"formats", "listformats", "f"}, - desc = "List available schematic formats", + desc = "List available formats", max = 0 ) @CommandPermissions("worldedit.schematic.formats") @@ -235,7 +235,7 @@ public class SchematicCommands { @Command( aliases = {"list", "all", "ls"}, - desc = "List available schematics", + desc = "List saved schematics", max = 0, flags = "dn", help = "List all schematics in the schematics directory\n" + From 1e2523ddcba4efcea79455698c0c8526fb32066f Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 21:56:05 -0700 Subject: [PATCH 06/21] Updated //help with colors and sub-command support. --- .../worldedit/command/UtilityCommands.java | 206 ++++++++++++++---- .../util/command/PrimaryAliasComparator.java | 43 ++++ .../sk89q/worldedit/util/formatting/Cmd.java | 34 +++ 3 files changed, 238 insertions(+), 45 deletions(-) create mode 100644 src/main/java/com/sk89q/worldedit/util/command/PrimaryAliasComparator.java create mode 100644 src/main/java/com/sk89q/worldedit/util/formatting/Cmd.java diff --git a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index 7487cd52e..0f0633491 100644 --- a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -19,9 +19,19 @@ package com.sk89q.worldedit.command; -import com.sk89q.minecraft.util.commands.*; -import com.sk89q.worldedit.*; +import com.google.common.base.Joiner; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.minecraft.util.commands.Logging; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.EntityType; +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld.KillFlags; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; @@ -29,16 +39,23 @@ import com.sk89q.worldedit.patterns.Pattern; import com.sk89q.worldedit.patterns.SingleBlockPattern; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.command.CommandCallable; import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.Description; import com.sk89q.worldedit.util.command.Dispatcher; +import com.sk89q.worldedit.util.command.PrimaryAliasComparator; import com.sk89q.worldedit.util.command.parametric.Optional; +import com.sk89q.worldedit.util.formatting.Cmd; +import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; +import com.sk89q.worldedit.util.formatting.CommandListBox; +import com.sk89q.worldedit.util.formatting.Style; +import com.sk89q.worldedit.util.formatting.StyledFragment; import com.sk89q.worldedit.world.World; -import java.util.Comparator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT; @@ -497,59 +514,158 @@ public class UtilityCommands { help(args, we, actor); } - public static void help(CommandContext args, WorldEdit we, Actor actor) { - final Dispatcher dispatcher = we.getPlatformManager().getCommandManager().getDispatcher(); + private static CommandMapping detectCommand(Dispatcher dispatcher, String command, boolean isRootLevel) { + CommandMapping mapping; - if (args.argsLength() == 0) { - SortedSet commands = new TreeSet(new Comparator() { - @Override - public int compare(String o1, String o2) { - final int ret = o1.replaceAll("/", "").compareToIgnoreCase(o2.replaceAll("/", "")); - if (ret == 0) { - return o1.compareToIgnoreCase(o2); - } - return ret; - } - }); - commands.addAll(dispatcher.getPrimaryAliases()); + // First try the command as entered + mapping = dispatcher.get(command); + if (mapping != null) { + return mapping; + } - StringBuilder sb = new StringBuilder(); - boolean first = true; - for (String command : commands) { - if (!first) { - sb.append(", "); - } - - sb.append('/'); - sb.append(command); - first = false; + // Then if we're looking at root commands and the user didn't use + // any slashes, let's try double slashes and then single slashes. + // However, be aware that there exists different single slash + // and double slash commands in WorldEdit + if (isRootLevel && !command.contains("/")) { + mapping = dispatcher.get("//" + command); + if (mapping != null) { + return mapping; } - actor.print(sb.toString()); - - return; + mapping = dispatcher.get("/" + command); + if (mapping != null) { + return mapping; + } } - String command = args.getJoinedStrings(0).toLowerCase().replaceAll("^/", ""); - CommandMapping mapping = dispatcher.get(command); + return null; + } - if (mapping == null) { - actor.printError("Unknown command '" + command + "'."); - return; + public static void help(CommandContext args, WorldEdit we, Actor actor) { + CommandCallable callable = we.getPlatformManager().getCommandManager().getDispatcher(); + + int page = 0; + 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) { + page = args.getInteger(args.argsLength() - 1); + if (page <= 0) { + page = 1; + } else { + page--; + } + + effectiveLength--; + } + } catch (NumberFormatException ignored) { } - Description description = mapping.getDescription(); + boolean isRootLevel = true; + List visited = new ArrayList(); - if (description.getUsage() != null) { - actor.printDebug("Usage: " + description.getUsage()); + // Drill down to the command + for (int i = 0; i < effectiveLength; i++) { + String command = args.getString(i); + + if (callable instanceof Dispatcher) { + // Chop off the beginning / if we're are the root level + if (isRootLevel && command.length() > 1 && command.charAt(0) == '/') { + command = command.substring(1); + } + + CommandMapping mapping = detectCommand((Dispatcher) callable, command, isRootLevel); + if (mapping != null) { + callable = mapping.getCallable(); + } else { + if (isRootLevel) { + actor.printError(String.format("The command '%s' could not be found.", args.getString(i))); + return; + } else { + actor.printError(String.format("The sub-command '%s' under '%s' could not be found.", + command, Joiner.on(" ").join(visited))); + return; + } + } + + visited.add(args.getString(i)); + isRootLevel = false; + } else { + actor.printError(String.format("'%s' has no sub-commands. (Maybe '%s' is for a parameter?)", + Joiner.on(" ").join(visited), command)); + return; + } } - if (description.getHelp() != null) { - actor.print(description.getHelp()); - } else if (description.getShortDescription() != null) { - actor.print(description.getShortDescription()); + // Create the message + if (callable instanceof Dispatcher) { + Dispatcher dispatcher = (Dispatcher) callable; + + // Get a list of aliases + List aliases = new ArrayList(dispatcher.getCommands()); + Collections.sort(aliases, PrimaryAliasComparator.INSTANCE); + + // 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 Cmd().append("//help ").append(" []")); + tip.append(" for more information.").newLine(); + + // Add each command + for (CommandMapping mapping : list) { + StringBuilder builder = new StringBuilder(); + if (isRootLevel) { + builder.append("/"); + } + if (!visited.isEmpty()) { + builder.append(Joiner.on(" ").join(visited)); + builder.append(" "); + } + builder.append(mapping.getPrimaryAlias()); + box.appendCommand(builder.toString(), mapping.getDescription().getShortDescription()); + } + } + + actor.printRaw(ColorCodeBuilder.asColorCodes(box)); } else { - actor.print("No further help is available."); + CommandListBox box = new CommandListBox(String.format("Help: %s", Joiner.on(" ").join(visited))); + StyledFragment contents = box.getContents(); + + Description description = callable.getDescription(); + + if (description.getUsage() != null) { + contents.createFragment(Style.YELLOW).append("Usage: "); + contents.append(description.getUsage()); + } else { + contents.createFragment(Style.GRAY).append("Usage information is not available."); + } + + contents.newLine(); + + if (description.getHelp() != null) { + contents.createFragment(Style.YELLOW_DARK).append(description.getHelp()); + } else if (description.getShortDescription() != null) { + contents.createFragment(Style.YELLOW_DARK).append(description.getShortDescription()); + } else { + contents.createFragment(Style.GRAY).append("No further help is available."); + } + + actor.printRaw(ColorCodeBuilder.asColorCodes(box)); } } } diff --git a/src/main/java/com/sk89q/worldedit/util/command/PrimaryAliasComparator.java b/src/main/java/com/sk89q/worldedit/util/command/PrimaryAliasComparator.java new file mode 100644 index 000000000..bcc4197ff --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/command/PrimaryAliasComparator.java @@ -0,0 +1,43 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.command; + +import java.util.Comparator; + +/** + * Compares the primary aliases of two {@link CommandMapping} using + * {@link String#compareTo(String)}. + */ +public final class PrimaryAliasComparator implements Comparator { + + /** + * An instance of this class. + */ + public static final PrimaryAliasComparator INSTANCE = new PrimaryAliasComparator(); + + private PrimaryAliasComparator() { + } + + @Override + public int compare(CommandMapping o1, CommandMapping o2) { + return o1.getPrimaryAlias().compareTo(o2.getPrimaryAlias()); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/Cmd.java b/src/main/java/com/sk89q/worldedit/util/formatting/Cmd.java new file mode 100644 index 000000000..c940b73fa --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/formatting/Cmd.java @@ -0,0 +1,34 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.formatting; + +/** + * Represents a fragment representing a command that is to be typed. + */ +public class Cmd extends StyledFragment { + + /** + * Create a new instance. + */ + public Cmd() { + super(Style.CYAN); + } + +} From c29ca03e3508fbbd9d230e3504aa89ad3b0fddc7 Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 22:08:08 -0700 Subject: [PATCH 07/21] Improved re-use of command help formatting. --- .../worldedit/command/UtilityCommands.java | 32 ++------ .../util/command/SimpleDispatcher.java | 2 +- .../{Cmd.java => components/Code.java} | 9 ++- .../{ => components}/CommandListBox.java | 4 +- .../components/CommandUsageBox.java | 74 +++++++++++++++++++ .../util/formatting/components/Label.java | 37 ++++++++++ .../{ => components}/MessageBox.java | 6 +- .../util/formatting/components/Subtle.java | 37 ++++++++++ 8 files changed, 169 insertions(+), 32 deletions(-) rename src/main/java/com/sk89q/worldedit/util/formatting/{Cmd.java => components/Code.java} (81%) rename src/main/java/com/sk89q/worldedit/util/formatting/{ => components}/CommandListBox.java (92%) create mode 100644 src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java create mode 100644 src/main/java/com/sk89q/worldedit/util/formatting/components/Label.java rename src/main/java/com/sk89q/worldedit/util/formatting/{ => components}/MessageBox.java (90%) create mode 100644 src/main/java/com/sk89q/worldedit/util/formatting/components/Subtle.java diff --git a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index 0f0633491..e231c1c2e 100644 --- a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -41,13 +41,13 @@ import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.command.CommandCallable; import com.sk89q.worldedit.util.command.CommandMapping; -import com.sk89q.worldedit.util.command.Description; import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.util.command.PrimaryAliasComparator; import com.sk89q.worldedit.util.command.parametric.Optional; -import com.sk89q.worldedit.util.formatting.Cmd; +import com.sk89q.worldedit.util.formatting.components.Code; import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; -import com.sk89q.worldedit.util.formatting.CommandListBox; +import com.sk89q.worldedit.util.formatting.components.CommandListBox; +import com.sk89q.worldedit.util.formatting.components.CommandUsageBox; import com.sk89q.worldedit.util.formatting.Style; import com.sk89q.worldedit.util.formatting.StyledFragment; import com.sk89q.worldedit.world.World; @@ -623,7 +623,7 @@ public class UtilityCommands { List list = aliases.subList(offset, Math.min(offset + perPage, aliases.size())); tip.append("Type "); - tip.append(new Cmd().append("//help ").append(" []")); + tip.append(new Code().append("//help ").append(" []")); tip.append(" for more information.").newLine(); // Add each command @@ -643,28 +643,8 @@ public class UtilityCommands { actor.printRaw(ColorCodeBuilder.asColorCodes(box)); } else { - CommandListBox box = new CommandListBox(String.format("Help: %s", Joiner.on(" ").join(visited))); - StyledFragment contents = box.getContents(); - - Description description = callable.getDescription(); - - if (description.getUsage() != null) { - contents.createFragment(Style.YELLOW).append("Usage: "); - contents.append(description.getUsage()); - } else { - contents.createFragment(Style.GRAY).append("Usage information is not available."); - } - - contents.newLine(); - - if (description.getHelp() != null) { - contents.createFragment(Style.YELLOW_DARK).append(description.getHelp()); - } else if (description.getShortDescription() != null) { - contents.createFragment(Style.YELLOW_DARK).append(description.getShortDescription()); - } else { - contents.createFragment(Style.GRAY).append("No further help is available."); - } - + String title = String.format("Help: %s", Joiner.on(" ").join(visited)); + CommandUsageBox box = new CommandUsageBox(callable.getDescription(), title); actor.printRaw(ColorCodeBuilder.asColorCodes(box)); } } diff --git a/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java b/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java index a84c6b497..e4733a4f0 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java +++ b/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java @@ -22,7 +22,7 @@ package com.sk89q.worldedit.util.command; import com.google.common.base.Joiner; import com.sk89q.minecraft.util.commands.*; import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; -import com.sk89q.worldedit.util.formatting.CommandListBox; +import com.sk89q.worldedit.util.formatting.components.CommandListBox; import com.sk89q.worldedit.util.formatting.StyledFragment; import java.util.*; diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/Cmd.java b/src/main/java/com/sk89q/worldedit/util/formatting/components/Code.java similarity index 81% rename from src/main/java/com/sk89q/worldedit/util/formatting/Cmd.java rename to src/main/java/com/sk89q/worldedit/util/formatting/components/Code.java index c940b73fa..dd26e7aff 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/Cmd.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/components/Code.java @@ -17,17 +17,20 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.util.formatting; +package com.sk89q.worldedit.util.formatting.components; + +import com.sk89q.worldedit.util.formatting.Style; +import com.sk89q.worldedit.util.formatting.StyledFragment; /** * Represents a fragment representing a command that is to be typed. */ -public class Cmd extends StyledFragment { +public class Code extends StyledFragment { /** * Create a new instance. */ - public Cmd() { + public Code() { super(Style.CYAN); } diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/CommandListBox.java b/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandListBox.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/util/formatting/CommandListBox.java rename to src/main/java/com/sk89q/worldedit/util/formatting/components/CommandListBox.java index 03fa0b754..b1eb0a644 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/CommandListBox.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandListBox.java @@ -17,7 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.util.formatting; +package com.sk89q.worldedit.util.formatting.components; + +import com.sk89q.worldedit.util.formatting.Style; public class CommandListBox extends MessageBox { diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java b/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java new file mode 100644 index 000000000..d14683e09 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java @@ -0,0 +1,74 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.formatting.components; + +import com.sk89q.worldedit.util.command.Description; +import com.sk89q.worldedit.util.formatting.Style; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A box to describe usage of a command. + */ +public class CommandUsageBox extends MessageBox { + + /** + * Create a new box. + * + * @param description the command to describe + * @param title the title + */ + public CommandUsageBox(Description description, String title) { + super(title); + checkNotNull(description); + attachCommandUsage(description); + } + + /** + * Create a new box. + * + * @param description the command to describe + */ + public CommandUsageBox(Description description) { + super("Usage Help"); + checkNotNull(description); + attachCommandUsage(description); + } + + private void attachCommandUsage(Description description) { + if (description.getUsage() != null) { + getContents().append(new Label().append("Usage: ")); + getContents().append(description.getUsage()); + } else { + getContents().append(new Subtle().append("Usage information is not available.")); + } + + getContents().newLine(); + + if (description.getHelp() != null) { + getContents().createFragment(Style.YELLOW_DARK).append(description.getHelp()); + } else if (description.getShortDescription() != null) { + getContents().createFragment(Style.YELLOW_DARK).append(description.getShortDescription()); + } else { + getContents().append(new Subtle().append("No further help is available.")); + } + } + +} diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/Label.java b/src/main/java/com/sk89q/worldedit/util/formatting/components/Label.java new file mode 100644 index 000000000..a646a1899 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/formatting/components/Label.java @@ -0,0 +1,37 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.formatting.components; + +import com.sk89q.worldedit.util.formatting.Style; +import com.sk89q.worldedit.util.formatting.StyledFragment; + +/** + * Represents a fragment representing a label. + */ +public class Label extends StyledFragment { + + /** + * Create a new instance. + */ + public Label() { + super(Style.YELLOW); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/MessageBox.java b/src/main/java/com/sk89q/worldedit/util/formatting/components/MessageBox.java similarity index 90% rename from src/main/java/com/sk89q/worldedit/util/formatting/MessageBox.java rename to src/main/java/com/sk89q/worldedit/util/formatting/components/MessageBox.java index 66cf81ab3..d0a97e8c3 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/MessageBox.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/components/MessageBox.java @@ -17,7 +17,11 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.util.formatting; +package com.sk89q.worldedit.util.formatting.components; + +import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; +import com.sk89q.worldedit.util.formatting.Style; +import com.sk89q.worldedit.util.formatting.StyledFragment; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/Subtle.java b/src/main/java/com/sk89q/worldedit/util/formatting/components/Subtle.java new file mode 100644 index 000000000..48e927b89 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/formatting/components/Subtle.java @@ -0,0 +1,37 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.formatting.components; + +import com.sk89q.worldedit.util.formatting.Style; +import com.sk89q.worldedit.util.formatting.StyledFragment; + +/** + * Represents a subtle part of the message. + */ +public class Subtle extends StyledFragment { + + /** + * Create a new instance. + */ + public Subtle() { + super(Style.GRAY); + } + +} From 11d37bce2bc9e6e3d8d01e2f68bd949a3ec07d30 Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 22:48:04 -0700 Subject: [PATCH 08/21] Implemented -? and changed handling of InvalidUsageException. Fixes WORLDEDIT-2947. --- .../util/commands/CommandContext.java | 2 +- .../util/commands/CommandException.java | 2 +- .../worldedit/command/UtilityCommands.java | 3 +- .../extension/platform/CommandManager.java | 14 +++- .../util/command/InvalidUsageException.java | 33 ++++++-- .../util/command/SimpleDispatcher.java | 34 ++++---- .../parametric/ParametricCallable.java | 35 +++++++-- .../components/CommandUsageBox.java | 78 +++++++++++++------ 8 files changed, 138 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java b/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java index 31900a9d2..dd3fa00e2 100644 --- a/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java +++ b/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java @@ -145,7 +145,7 @@ public class CommandContext { suggestionContext = SuggestionContext.hangingValue(); // Not a flag? - if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z]+$")) { + if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z\\?]+$")) { if (!isHanging) { suggestionContext = SuggestionContext.lastValue(); } diff --git a/src/main/java/com/sk89q/minecraft/util/commands/CommandException.java b/src/main/java/com/sk89q/minecraft/util/commands/CommandException.java index eae94c75f..b6e30825f 100644 --- a/src/main/java/com/sk89q/minecraft/util/commands/CommandException.java +++ b/src/main/java/com/sk89q/minecraft/util/commands/CommandException.java @@ -66,7 +66,7 @@ public class CommandException extends Exception { } builder.append(spacedSuffix); } - return builder.toString(); + return builder.toString().trim(); } } diff --git a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index e231c1c2e..ce43904b9 100644 --- a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -643,8 +643,7 @@ public class UtilityCommands { actor.printRaw(ColorCodeBuilder.asColorCodes(box)); } else { - String title = String.format("Help: %s", Joiner.on(" ").join(visited)); - CommandUsageBox box = new CommandUsageBox(callable.getDescription(), title); + CommandUsageBox box = new CommandUsageBox(callable, Joiner.on(" ").join(visited)); actor.printRaw(ColorCodeBuilder.asColorCodes(box)); } } diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java index cc9f26556..56fc1754b 100644 --- a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java +++ b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java @@ -42,6 +42,8 @@ import com.sk89q.worldedit.util.command.fluent.CommandGraph; import com.sk89q.worldedit.util.command.parametric.LegacyCommandsHandler; import com.sk89q.worldedit.util.command.parametric.ParametricBuilder; import com.sk89q.worldedit.util.eventbus.Subscribe; +import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; +import com.sk89q.worldedit.util.formatting.components.CommandUsageBox; import com.sk89q.worldedit.util.logging.DynamicStreamHandler; import com.sk89q.worldedit.util.logging.LogFormat; @@ -220,7 +222,17 @@ public final class CommandManager { } catch (CommandPermissionsException e) { actor.printError("You don't have permission to do this."); } catch (InvalidUsageException e) { - actor.printError(e.getMessage() + "\nUsage: " + e.getUsage("/")); + if (e.isFullUsageSuggested()) { + actor.printRaw(ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.toStackString("/", ""), locals))); + String message = e.getMessage(); + if (message != null) { + actor.printError(message); + } + } else { + String message = e.getMessage(); + actor.printError(message != null ? message : "The command was not used properly (no more help available)."); + actor.printError(e.getUsage("/")); + } } catch (WrappedCommandException e) { Throwable t = e.getCause(); actor.printError("Please report this error: [See console]"); diff --git a/src/main/java/com/sk89q/worldedit/util/command/InvalidUsageException.java b/src/main/java/com/sk89q/worldedit/util/command/InvalidUsageException.java index a97ce4d2f..56195cdf2 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/InvalidUsageException.java +++ b/src/main/java/com/sk89q/worldedit/util/command/InvalidUsageException.java @@ -21,29 +21,46 @@ package com.sk89q.worldedit.util.command; import com.sk89q.minecraft.util.commands.CommandException; +import static com.google.common.base.Preconditions.checkNotNull; + /** * Thrown when a command is not used properly. */ public class InvalidUsageException extends CommandException { private static final long serialVersionUID = -3222004168669490390L; - private final Description description; + private final CommandCallable command; + private final boolean fullUsageSuggested; - public InvalidUsageException(Description description) { - this.description = description; + public InvalidUsageException(CommandCallable command) { + this(null, command); } - public InvalidUsageException(String message, Description description) { + public InvalidUsageException(String message, CommandCallable command) { + this(message, command, false); + } + + public InvalidUsageException(String message, CommandCallable command, boolean fullUsageSuggested) { super(message); - this.description = description; + checkNotNull(command); + this.command = command; + this.fullUsageSuggested = fullUsageSuggested; } - public Description getDescription() { - return description; + public CommandCallable getCommand() { + return command; } public String getUsage(String prefix) { - return toStackString(prefix, getDescription().getUsage()); + return toStackString(prefix, command.getDescription().getUsage()); } + /** + * Return whether the full usage of the command should be shown. + * + * @return show full usage + */ + public boolean isFullUsageSuggested() { + return fullUsageSuggested; + } } diff --git a/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java b/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java index e4733a4f0..8bb7d52c5 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java +++ b/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java @@ -20,12 +20,20 @@ package com.sk89q.worldedit.util.command; import com.google.common.base.Joiner; -import com.sk89q.minecraft.util.commands.*; -import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; -import com.sk89q.worldedit.util.formatting.components.CommandListBox; -import com.sk89q.worldedit.util.formatting.StyledFragment; +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.CommandPermissionsException; +import com.sk89q.minecraft.util.commands.WrappedCommandException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * A simple implementation of {@link Dispatcher}. @@ -109,7 +117,7 @@ public class SimpleDispatcher implements Dispatcher { Set aliases = getPrimaryAliases(); if (aliases.isEmpty()) { - throw new InvalidUsageException("This command has no sub-commands.", getDescription()); + throw new InvalidUsageException("This command has no sub-commands.", this); } else if (split.length > 0) { String subCommand = split[0]; String subArguments = Joiner.on(" ").join(Arrays.copyOfRange(split, 1, split.length)); @@ -132,7 +140,7 @@ public class SimpleDispatcher implements Dispatcher { } - throw new InvalidUsageException(ColorCodeBuilder.asColorCodes(getSubcommandList(locals, parentCommands)), getDescription()); + throw new InvalidUsageException("Please choose a sub-command.", this, true); } @Override @@ -185,16 +193,4 @@ public class SimpleDispatcher implements Dispatcher { return false; } - private StyledFragment getSubcommandList(CommandLocals locals, String[] parentCommands) { - CommandListBox box = new CommandListBox("Subcommands"); - String prefix = parentCommands.length > 0 ? "/" + Joiner.on(" ").join(parentCommands) + " " : ""; - for (CommandMapping mapping : getCommands()) { - if (mapping.getCallable().testPermission(locals)) { - box.appendCommand(prefix + mapping.getPrimaryAlias(), mapping.getDescription().getShortDescription()); - } - } - - return box; - } - } diff --git a/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java b/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java index 9cbecc03e..b98aeb00f 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java +++ b/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java @@ -19,15 +19,32 @@ package com.sk89q.worldedit.util.command.parametric; -import com.sk89q.minecraft.util.commands.*; -import com.sk89q.worldedit.util.command.*; +import com.google.common.base.Joiner; +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.CommandPermissionsException; +import com.sk89q.minecraft.util.commands.WrappedCommandException; +import com.sk89q.worldedit.util.command.CommandCallable; +import com.sk89q.worldedit.util.command.InvalidUsageException; +import com.sk89q.worldedit.util.command.MissingParameterException; +import com.sk89q.worldedit.util.command.Parameter; +import com.sk89q.worldedit.util.command.SimpleDescription; +import com.sk89q.worldedit.util.command.UnconsumedParameterException; import com.sk89q.worldedit.util.command.binding.Switch; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * The implementation of a {@link CommandCallable} for the {@link ParametricBuilder}. @@ -169,6 +186,12 @@ class ParametricCallable implements CommandCallable { String[] split = CommandContext.split(calledCommand + " " + stringArguments); CommandContext context = new CommandContext(split, getValueFlags(), false, locals); + // Provide help if -? is specified + if (context.hasFlag('?')) { + String title = Joiner.on(" ").join(parentCommands); + throw new InvalidUsageException(null, this, true); + } + Object[] args = new Object[parameters.length]; ContextArgumentStack arguments = new ContextArgumentStack(context); ParameterData parameter = null; @@ -221,14 +244,14 @@ class ParametricCallable implements CommandCallable { handler.postInvoke(handler, method, parameters, args, context); } } catch (MissingParameterException e) { - throw new InvalidUsageException("Too few parameters!", getDescription()); + throw new InvalidUsageException("Too few parameters!", this); } catch (UnconsumedParameterException e) { - throw new InvalidUsageException("Too many parameters! Unused parameters: " + e.getUnconsumed(), getDescription()); + throw new InvalidUsageException("Too many parameters! Unused parameters: " + e.getUnconsumed(), this); } catch (ParameterException e) { assert parameter != null; String name = parameter.getName(); - throw new InvalidUsageException("For parameter '" + name + "': " + e.getMessage(), getDescription()); + throw new InvalidUsageException("For parameter '" + name + "': " + e.getMessage(), this); } catch (InvocationTargetException e) { for (ExceptionConverter converter : builder.getExceptionConverters()) { converter.convert(e.getCause()); diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java b/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java index d14683e09..4332c8efb 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java @@ -19,56 +19,84 @@ package com.sk89q.worldedit.util.formatting.components; +import com.sk89q.minecraft.util.commands.CommandLocals; +import com.sk89q.worldedit.util.command.CommandCallable; +import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.Description; +import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.util.formatting.Style; +import com.sk89q.worldedit.util.formatting.StyledFragment; + +import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; /** * A box to describe usage of a command. */ -public class CommandUsageBox extends MessageBox { +public class CommandUsageBox extends StyledFragment { /** - * Create a new box. + * Create a new usage box. * - * @param description the command to describe - * @param title the title + * @param command the command to describe + * @param commandString the command that was used, such as "/we" or "/brush sphere" */ - public CommandUsageBox(Description description, String title) { - super(title); - checkNotNull(description); - attachCommandUsage(description); + public CommandUsageBox(CommandCallable command, String commandString) { + this(command, commandString, null); } /** - * Create a new box. + * Create a new usage box. * - * @param description the command to describe + * @param command the command to describe + * @param commandString the command that was used, such as "/we" or "/brush sphere" + * @param locals list of locals to use */ - public CommandUsageBox(Description description) { - super("Usage Help"); - checkNotNull(description); - attachCommandUsage(description); - } - - private void attachCommandUsage(Description description) { - if (description.getUsage() != null) { - getContents().append(new Label().append("Usage: ")); - getContents().append(description.getUsage()); + public CommandUsageBox(CommandCallable command, String commandString, @Nullable CommandLocals locals) { + checkNotNull(command); + checkNotNull(commandString); + if (command instanceof Dispatcher) { + attachDispatcherUsage((Dispatcher) command, commandString, locals); } else { - getContents().append(new Subtle().append("Usage information is not available.")); + attachCommandUsage(command.getDescription(), commandString); + } + } + + private void attachDispatcherUsage(Dispatcher dispatcher, String commandString, @Nullable CommandLocals locals) { + CommandListBox box = new CommandListBox("Subcommands"); + String prefix = !commandString.isEmpty() ? commandString + " " : ""; + for (CommandMapping mapping : dispatcher.getCommands()) { + if (locals == null || mapping.getCallable().testPermission(locals)) { + box.appendCommand(prefix + mapping.getPrimaryAlias(), mapping.getDescription().getShortDescription()); + } } - getContents().newLine(); + append(box); + } + + private void attachCommandUsage(Description description, String commandString) { + MessageBox box = new MessageBox("Help for " + commandString); + StyledFragment contents = box.getContents(); + + if (description.getUsage() != null) { + contents.append(new Label().append("Usage: ")); + contents.append(description.getUsage()); + } else { + contents.append(new Subtle().append("Usage information is not available.")); + } + + contents.newLine(); if (description.getHelp() != null) { - getContents().createFragment(Style.YELLOW_DARK).append(description.getHelp()); + contents.createFragment(Style.YELLOW_DARK).append(description.getHelp()); } else if (description.getShortDescription() != null) { - getContents().createFragment(Style.YELLOW_DARK).append(description.getShortDescription()); + contents.append(description.getShortDescription()); } else { - getContents().append(new Subtle().append("No further help is available.")); + contents.append(new Subtle().append("No further help is available.")); } + + append(box); } } From 08ad5f4451055abccc05fd479d674a754a0da2e8 Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 22:51:21 -0700 Subject: [PATCH 09/21] Handle exceptions thrown from bindings as a convertible InvocationTargetException. For example, if IncompleteRegionException is thrown by a binding, it will result in a InvocationTargetException now with a getCause(), which gets handled as if that exception was thrown from the actual Method that is invoked for the command. --- .../com/sk89q/worldedit/util/command/parametric/Binding.java | 5 +++-- .../worldedit/util/command/parametric/BindingHelper.java | 4 ++-- .../util/command/parametric/ParametricCallable.java | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/sk89q/worldedit/util/command/parametric/Binding.java b/src/main/java/com/sk89q/worldedit/util/command/parametric/Binding.java index dcf931c81..108fc1bf8 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/parametric/Binding.java +++ b/src/main/java/com/sk89q/worldedit/util/command/parametric/Binding.java @@ -23,6 +23,7 @@ import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.worldedit.util.command.binding.PrimitiveBindings; import com.sk89q.worldedit.util.command.binding.StandardBindings; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import java.util.List; @@ -77,8 +78,8 @@ public interface Binding { * @throws ParameterException thrown if the parameter could not be formulated * @throws CommandException on a command exception */ - Object bind(ParameterData parameter, ArgumentStack scoped, boolean onlyConsume) - throws ParameterException, CommandException; + Object bind(ParameterData parameter, ArgumentStack scoped, boolean onlyConsume) + throws ParameterException, CommandException, InvocationTargetException; /** * Get a list of suggestions for the given parameter and user arguments. diff --git a/src/main/java/com/sk89q/worldedit/util/command/parametric/BindingHelper.java b/src/main/java/com/sk89q/worldedit/util/command/parametric/BindingHelper.java index b442da6a2..b56c76426 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/parametric/BindingHelper.java +++ b/src/main/java/com/sk89q/worldedit/util/command/parametric/BindingHelper.java @@ -143,7 +143,7 @@ public class BindingHelper implements Binding { @Override public Object bind(ParameterData parameter, ArgumentStack scoped, - boolean onlyConsume) throws ParameterException, CommandException { + boolean onlyConsume) throws ParameterException, CommandException, InvocationTargetException { BoundMethod binding = match(parameter); List args = new ArrayList(); args.add(scoped); @@ -178,7 +178,7 @@ public class BindingHelper implements Binding { } else if (e.getCause() instanceof CommandException) { throw (CommandException) e.getCause(); } - throw new RuntimeException(e.getCause()); + throw e; } } diff --git a/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java b/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java index b98aeb00f..7a657d848 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java +++ b/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java @@ -366,8 +366,8 @@ class ParametricCallable implements CommandCallable { * @throws ParameterException on an error * @throws CommandException on an error */ - private Object getDefaultValue(int i, ContextArgumentStack scoped) - throws ParameterException, CommandException { + private Object getDefaultValue(int i, ContextArgumentStack scoped) + throws ParameterException, CommandException, InvocationTargetException { CommandContext context = scoped.getContext(); ParameterData parameter = parameters[i]; From 88f0f1061a2852d1035dc8cb4399e62712874def Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 23:02:04 -0700 Subject: [PATCH 10/21] Cleaned up InvalidUsageException and CommandException to be less confusing. --- .../util/commands/CommandException.java | 14 ++++- .../extension/platform/CommandManager.java | 6 +- .../util/command/InvalidUsageException.java | 57 ++++++++++++++++--- 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/sk89q/minecraft/util/commands/CommandException.java b/src/main/java/com/sk89q/minecraft/util/commands/CommandException.java index b6e30825f..968c31e6a 100644 --- a/src/main/java/com/sk89q/minecraft/util/commands/CommandException.java +++ b/src/main/java/com/sk89q/minecraft/util/commands/CommandException.java @@ -19,10 +19,13 @@ package com.sk89q.minecraft.util.commands; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; +import static com.google.common.base.Preconditions.checkNotNull; + public class CommandException extends Exception { private static final long serialVersionUID = 870638193072101739L; @@ -48,7 +51,16 @@ public class CommandException extends Exception { commandStack.add(name); } - public String toStackString(String prefix, String spacedSuffix) { + /** + * Gets the command that was called, which will include the sub-command + * (i.e. "/br sphere"). + * + * @param prefix the command shebang character (such as "/") -- may be empty + * @param spacedSuffix a suffix to put at the end (optional) -- may be null + * @return the command that was used + */ + public String getCommandUsed(String prefix, @Nullable String spacedSuffix) { + checkNotNull(prefix); StringBuilder builder = new StringBuilder(); if (prefix != null) { builder.append(prefix); diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java index 56fc1754b..94e7dec03 100644 --- a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java +++ b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java @@ -222,8 +222,8 @@ public final class CommandManager { } catch (CommandPermissionsException e) { actor.printError("You don't have permission to do this."); } catch (InvalidUsageException e) { - if (e.isFullUsageSuggested()) { - actor.printRaw(ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.toStackString("/", ""), locals))); + if (e.isFullHelpSuggested()) { + actor.printRaw(ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.getCommandUsed("/", ""), locals))); String message = e.getMessage(); if (message != null) { actor.printError(message); @@ -231,7 +231,7 @@ public final class CommandManager { } else { String message = e.getMessage(); actor.printError(message != null ? message : "The command was not used properly (no more help available)."); - actor.printError(e.getUsage("/")); + actor.printError(e.getSimpleUsageString("/")); } } catch (WrappedCommandException e) { Throwable t = e.getCause(); diff --git a/src/main/java/com/sk89q/worldedit/util/command/InvalidUsageException.java b/src/main/java/com/sk89q/worldedit/util/command/InvalidUsageException.java index 56195cdf2..9795aaaef 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/InvalidUsageException.java +++ b/src/main/java/com/sk89q/worldedit/util/command/InvalidUsageException.java @@ -21,38 +21,79 @@ package com.sk89q.worldedit.util.command; import com.sk89q.minecraft.util.commands.CommandException; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkNotNull; /** * Thrown when a command is not used properly. + *

+ * When handling this exception, print the error message if it is not null. + * Print a one line help instruction unless {@link #isFullHelpSuggested()} + * is true, which, in that case, the full help of the command should be shown. + *

+ * If no error message is set and full help is not to be shown, then a generic + * "you used this command incorrectly" message should be shown. */ public class InvalidUsageException extends CommandException { private static final long serialVersionUID = -3222004168669490390L; private final CommandCallable command; - private final boolean fullUsageSuggested; + private final boolean fullHelpSuggested; + /** + * Create a new instance with no error message and with no suggestion + * that full and complete help for the command should be shown. This will + * result in a generic error message. + * + * @param command the command + */ public InvalidUsageException(CommandCallable command) { this(null, command); } - public InvalidUsageException(String message, CommandCallable command) { + /** + * Create a new instance with a message and with no suggestion + * that full and complete help for the command should be shown. + * + * @param message the message + * @param command the command + */ + public InvalidUsageException(@Nullable String message, CommandCallable command) { this(message, command, false); } - public InvalidUsageException(String message, CommandCallable command, boolean fullUsageSuggested) { + /** + * Create a new instance with a message. + * + * @param message the message + * @param command the command + * @param fullHelpSuggested true if the full help for the command should be shown + */ + public InvalidUsageException(@Nullable String message, CommandCallable command, boolean fullHelpSuggested) { super(message); checkNotNull(command); this.command = command; - this.fullUsageSuggested = fullUsageSuggested; + this.fullHelpSuggested = fullHelpSuggested; } + /** + * Get the command. + * + * @return the command + */ public CommandCallable getCommand() { return command; } - public String getUsage(String prefix) { - return toStackString(prefix, command.getDescription().getUsage()); + /** + * Get a simple usage string. + * + * @param prefix the command shebang (such as "/") -- may be blank + * @return a usage string + */ + public String getSimpleUsageString(String prefix) { + return getCommandUsed(prefix, command.getDescription().getUsage()); } /** @@ -60,7 +101,7 @@ public class InvalidUsageException extends CommandException { * * @return show full usage */ - public boolean isFullUsageSuggested() { - return fullUsageSuggested; + public boolean isFullHelpSuggested() { + return fullHelpSuggested; } } From f0530f9d28a87e12df4e551cf1ceaed311242138 Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 23:03:46 -0700 Subject: [PATCH 11/21] Removed gold color from CommandUsageBox for command help. --- .../worldedit/util/formatting/components/CommandUsageBox.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java b/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java index 4332c8efb..a4470c010 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java @@ -89,7 +89,7 @@ public class CommandUsageBox extends StyledFragment { contents.newLine(); if (description.getHelp() != null) { - contents.createFragment(Style.YELLOW_DARK).append(description.getHelp()); + contents.append(description.getHelp()); } else if (description.getShortDescription() != null) { contents.append(description.getShortDescription()); } else { From 75b1fe6090e8e936efbcfc17c68141f094c0afee Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 23:04:32 -0700 Subject: [PATCH 12/21] Added "Usage: " back when handling InvalidUsageException. --- .../com/sk89q/worldedit/extension/platform/CommandManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java index 94e7dec03..a477043bf 100644 --- a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java +++ b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java @@ -231,7 +231,7 @@ public final class CommandManager { } else { String message = e.getMessage(); actor.printError(message != null ? message : "The command was not used properly (no more help available)."); - actor.printError(e.getSimpleUsageString("/")); + actor.printError("Usage: " + e.getSimpleUsageString("/")); } } catch (WrappedCommandException e) { Throwable t = e.getCause(); From 2effc57b7860f7c16af6c0f5ba22e9b58febc909 Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 23:17:44 -0700 Subject: [PATCH 13/21] When sorting commands for //help, ignore / characters. --- .../worldedit/command/UtilityCommands.java | 9 ++++---- .../extension/platform/CommandManager.java | 2 ++ .../util/command/PrimaryAliasComparator.java | 22 ++++++++++++++++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index ce43904b9..fc3ba4311 100644 --- a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -35,6 +35,7 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extension.platform.CommandManager; import com.sk89q.worldedit.patterns.Pattern; import com.sk89q.worldedit.patterns.SingleBlockPattern; import com.sk89q.worldedit.regions.CuboidRegion; @@ -44,12 +45,12 @@ import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.util.command.PrimaryAliasComparator; import com.sk89q.worldedit.util.command.parametric.Optional; -import com.sk89q.worldedit.util.formatting.components.Code; import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; -import com.sk89q.worldedit.util.formatting.components.CommandListBox; -import com.sk89q.worldedit.util.formatting.components.CommandUsageBox; import com.sk89q.worldedit.util.formatting.Style; import com.sk89q.worldedit.util.formatting.StyledFragment; +import com.sk89q.worldedit.util.formatting.components.Code; +import com.sk89q.worldedit.util.formatting.components.CommandListBox; +import com.sk89q.worldedit.util.formatting.components.CommandUsageBox; import com.sk89q.worldedit.world.World; import java.util.ArrayList; @@ -606,7 +607,7 @@ public class UtilityCommands { // Get a list of aliases List aliases = new ArrayList(dispatcher.getCommands()); - Collections.sort(aliases, PrimaryAliasComparator.INSTANCE); + Collections.sort(aliases, new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN)); // Calculate pagination int offset = perPage * page; diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java index a477043bf..1f1afcc98 100644 --- a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java +++ b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java @@ -52,6 +52,7 @@ import java.io.IOException; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Pattern; import static com.google.common.base.Preconditions.checkNotNull; @@ -62,6 +63,7 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public final class CommandManager { + public static final Pattern COMMAND_CLEAN_PATTERN = Pattern.compile("^[/]+"); private static final Logger logger = Logger.getLogger(CommandManager.class.getCanonicalName()); private static final java.util.regex.Pattern numberFormatExceptionPattern = java.util.regex.Pattern.compile("^For input string: \"(.*)\"$"); diff --git a/src/main/java/com/sk89q/worldedit/util/command/PrimaryAliasComparator.java b/src/main/java/com/sk89q/worldedit/util/command/PrimaryAliasComparator.java index bcc4197ff..b7b980acf 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/PrimaryAliasComparator.java +++ b/src/main/java/com/sk89q/worldedit/util/command/PrimaryAliasComparator.java @@ -19,7 +19,9 @@ package com.sk89q.worldedit.util.command; +import javax.annotation.Nullable; import java.util.Comparator; +import java.util.regex.Pattern; /** * Compares the primary aliases of two {@link CommandMapping} using @@ -30,14 +32,28 @@ public final class PrimaryAliasComparator implements Comparator /** * An instance of this class. */ - public static final PrimaryAliasComparator INSTANCE = new PrimaryAliasComparator(); + public static final PrimaryAliasComparator INSTANCE = new PrimaryAliasComparator(null); + private final @Nullable Pattern removalPattern; - private PrimaryAliasComparator() { + /** + * Create a new instance. + * + * @param removalPattern a regex to remove unwanted characters from the compared aliases + */ + public PrimaryAliasComparator(@Nullable Pattern removalPattern) { + this.removalPattern = removalPattern; + } + + private String clean(String alias) { + if (removalPattern != null) { + return removalPattern.matcher(alias).replaceAll(""); + } + return alias; } @Override public int compare(CommandMapping o1, CommandMapping o2) { - return o1.getPrimaryAlias().compareTo(o2.getPrimaryAlias()); + return clean(o1.getPrimaryAlias()).compareTo(clean(o2.getPrimaryAlias())); } } From 7c2f6f0bcc0f864decbeac4132a4a5139c19d796 Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 30 Jun 2014 23:22:04 -0700 Subject: [PATCH 14/21] Sort commands for Dispatchers in CommandUsageBox. --- .../util/formatting/components/CommandUsageBox.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java b/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java index a4470c010..b8fa617a3 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java @@ -20,14 +20,18 @@ package com.sk89q.worldedit.util.formatting.components; import com.sk89q.minecraft.util.commands.CommandLocals; +import com.sk89q.worldedit.extension.platform.CommandManager; import com.sk89q.worldedit.util.command.CommandCallable; import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.Description; import com.sk89q.worldedit.util.command.Dispatcher; -import com.sk89q.worldedit.util.formatting.Style; +import com.sk89q.worldedit.util.command.PrimaryAliasComparator; import com.sk89q.worldedit.util.formatting.StyledFragment; import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import static com.google.common.base.Preconditions.checkNotNull; @@ -66,7 +70,11 @@ public class CommandUsageBox extends StyledFragment { private void attachDispatcherUsage(Dispatcher dispatcher, String commandString, @Nullable CommandLocals locals) { CommandListBox box = new CommandListBox("Subcommands"); String prefix = !commandString.isEmpty() ? commandString + " " : ""; - for (CommandMapping mapping : dispatcher.getCommands()) { + + List list = new ArrayList(dispatcher.getCommands()); + Collections.sort(list, new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN)); + + for (CommandMapping mapping : list) { if (locals == null || mapping.getCallable().testPermission(locals)) { box.appendCommand(prefix + mapping.getPrimaryAlias(), mapping.getDescription().getShortDescription()); } From 83a657e561e86a1f809d16808d045cfdcbdf24cd Mon Sep 17 00:00:00 2001 From: sk89q Date: Tue, 1 Jul 2014 00:22:11 -0700 Subject: [PATCH 15/21] formatting.components -> formatting.component --- .../util/formatting/{components => component}/Code.java | 2 +- .../formatting/{components => component}/CommandListBox.java | 2 +- .../formatting/{components => component}/CommandUsageBox.java | 2 +- .../util/formatting/{components => component}/Label.java | 2 +- .../util/formatting/{components => component}/MessageBox.java | 2 +- .../util/formatting/{components => component}/Subtle.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename src/main/java/com/sk89q/worldedit/util/formatting/{components => component}/Code.java (95%) rename src/main/java/com/sk89q/worldedit/util/formatting/{components => component}/CommandListBox.java (96%) rename src/main/java/com/sk89q/worldedit/util/formatting/{components => component}/CommandUsageBox.java (98%) rename src/main/java/com/sk89q/worldedit/util/formatting/{components => component}/Label.java (95%) rename src/main/java/com/sk89q/worldedit/util/formatting/{components => component}/MessageBox.java (97%) rename src/main/java/com/sk89q/worldedit/util/formatting/{components => component}/Subtle.java (95%) diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/Code.java b/src/main/java/com/sk89q/worldedit/util/formatting/component/Code.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/util/formatting/components/Code.java rename to src/main/java/com/sk89q/worldedit/util/formatting/component/Code.java index dd26e7aff..953d83fe3 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/components/Code.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/component/Code.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.util.formatting.components; +package com.sk89q.worldedit.util.formatting.component; import com.sk89q.worldedit.util.formatting.Style; import com.sk89q.worldedit.util.formatting.StyledFragment; diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandListBox.java b/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/util/formatting/components/CommandListBox.java rename to src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java index b1eb0a644..145b6baca 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandListBox.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.util.formatting.components; +package com.sk89q.worldedit.util.formatting.component; import com.sk89q.worldedit.util.formatting.Style; diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java b/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java similarity index 98% rename from src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java rename to src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java index b8fa617a3..a9f8679fe 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/components/CommandUsageBox.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.util.formatting.components; +package com.sk89q.worldedit.util.formatting.component; import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.worldedit.extension.platform.CommandManager; diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/Label.java b/src/main/java/com/sk89q/worldedit/util/formatting/component/Label.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/util/formatting/components/Label.java rename to src/main/java/com/sk89q/worldedit/util/formatting/component/Label.java index a646a1899..8a59732b0 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/components/Label.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/component/Label.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.util.formatting.components; +package com.sk89q.worldedit.util.formatting.component; import com.sk89q.worldedit.util.formatting.Style; import com.sk89q.worldedit.util.formatting.StyledFragment; diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/MessageBox.java b/src/main/java/com/sk89q/worldedit/util/formatting/component/MessageBox.java similarity index 97% rename from src/main/java/com/sk89q/worldedit/util/formatting/components/MessageBox.java rename to src/main/java/com/sk89q/worldedit/util/formatting/component/MessageBox.java index d0a97e8c3..757006d7c 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/components/MessageBox.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/component/MessageBox.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.util.formatting.components; +package com.sk89q.worldedit.util.formatting.component; import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; import com.sk89q.worldedit.util.formatting.Style; diff --git a/src/main/java/com/sk89q/worldedit/util/formatting/components/Subtle.java b/src/main/java/com/sk89q/worldedit/util/formatting/component/Subtle.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/util/formatting/components/Subtle.java rename to src/main/java/com/sk89q/worldedit/util/formatting/component/Subtle.java index 48e927b89..34316c087 100644 --- a/src/main/java/com/sk89q/worldedit/util/formatting/components/Subtle.java +++ b/src/main/java/com/sk89q/worldedit/util/formatting/component/Subtle.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.util.formatting.components; +package com.sk89q.worldedit.util.formatting.component; import com.sk89q.worldedit.util.formatting.Style; import com.sk89q.worldedit.util.formatting.StyledFragment; From a74bab7f98d6064cb33f0217bf0329e0129a275e Mon Sep 17 00:00:00 2001 From: sk89q Date: Tue, 1 Jul 2014 01:39:54 -0700 Subject: [PATCH 16/21] Added changes to formatting package in some classes. --- .../java/com/sk89q/worldedit/command/UtilityCommands.java | 6 +++--- .../sk89q/worldedit/extension/platform/CommandManager.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index fc3ba4311..7f596c8e3 100644 --- a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -48,9 +48,9 @@ import com.sk89q.worldedit.util.command.parametric.Optional; 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.components.Code; -import com.sk89q.worldedit.util.formatting.components.CommandListBox; -import com.sk89q.worldedit.util.formatting.components.CommandUsageBox; +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; diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java index 1f1afcc98..9c71cfe69 100644 --- a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java +++ b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java @@ -43,7 +43,7 @@ import com.sk89q.worldedit.util.command.parametric.LegacyCommandsHandler; import com.sk89q.worldedit.util.command.parametric.ParametricBuilder; import com.sk89q.worldedit.util.eventbus.Subscribe; import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; -import com.sk89q.worldedit.util.formatting.components.CommandUsageBox; +import com.sk89q.worldedit.util.formatting.component.CommandUsageBox; import com.sk89q.worldedit.util.logging.DynamicStreamHandler; import com.sk89q.worldedit.util.logging.LogFormat; From 63411b427a76664ccb2ddea418c1add848beadff Mon Sep 17 00:00:00 2001 From: sk89q Date: Tue, 1 Jul 2014 12:41:11 -0700 Subject: [PATCH 17/21] Added Transform.inverse() as a standard operation. --- .../worldedit/math/transform/CombinedTransform.java | 11 +++++++++++ .../com/sk89q/worldedit/math/transform/Identity.java | 5 +++++ .../com/sk89q/worldedit/math/transform/Transform.java | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/src/main/java/com/sk89q/worldedit/math/transform/CombinedTransform.java b/src/main/java/com/sk89q/worldedit/math/transform/CombinedTransform.java index 86990f49c..84b1a474b 100644 --- a/src/main/java/com/sk89q/worldedit/math/transform/CombinedTransform.java +++ b/src/main/java/com/sk89q/worldedit/math/transform/CombinedTransform.java @@ -21,8 +21,10 @@ package com.sk89q.worldedit.math.transform; import com.sk89q.worldedit.Vector; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.List; import static com.google.common.base.Preconditions.checkNotNull; @@ -60,6 +62,15 @@ public class CombinedTransform implements Transform { return vector; } + @Override + public Transform inverse() { + List list = new ArrayList(); + for (int i = transforms.length - 1; i >= 0; i--) { + list.add(transforms[i].inverse()); + } + return new CombinedTransform(list); + } + @Override public Transform combine(Transform other) { checkNotNull(other); diff --git a/src/main/java/com/sk89q/worldedit/math/transform/Identity.java b/src/main/java/com/sk89q/worldedit/math/transform/Identity.java index 3cad43c2c..6e7622ec5 100644 --- a/src/main/java/com/sk89q/worldedit/math/transform/Identity.java +++ b/src/main/java/com/sk89q/worldedit/math/transform/Identity.java @@ -31,6 +31,11 @@ public class Identity implements Transform { return vector; } + @Override + public Transform inverse() { + return this; + } + @Override public Transform combine(Transform other) { if (other instanceof Identity) { diff --git a/src/main/java/com/sk89q/worldedit/math/transform/Transform.java b/src/main/java/com/sk89q/worldedit/math/transform/Transform.java index 53f0d44ca..05a7d5196 100644 --- a/src/main/java/com/sk89q/worldedit/math/transform/Transform.java +++ b/src/main/java/com/sk89q/worldedit/math/transform/Transform.java @@ -27,6 +27,13 @@ import com.sk89q.worldedit.Vector; */ public interface Transform extends Function { + /** + * Create a new inverse transform. + * + * @return a new inverse transform + */ + Transform inverse(); + /** * Create a new {@link Transform} that combines this transform with another. * From e3ae22da80586dcf98e90742610c688e5e7de95d Mon Sep 17 00:00:00 2001 From: sk89q Date: Tue, 1 Jul 2014 12:41:52 -0700 Subject: [PATCH 18/21] Identity.combine(other) should just return other. --- src/main/java/com/sk89q/worldedit/math/transform/Identity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sk89q/worldedit/math/transform/Identity.java b/src/main/java/com/sk89q/worldedit/math/transform/Identity.java index 6e7622ec5..a5f22038d 100644 --- a/src/main/java/com/sk89q/worldedit/math/transform/Identity.java +++ b/src/main/java/com/sk89q/worldedit/math/transform/Identity.java @@ -41,7 +41,7 @@ public class Identity implements Transform { if (other instanceof Identity) { return this; } else { - return new CombinedTransform(this, other); + return other; } } } From 61053564fa7e066b7a291d5b3fd199735ec88135 Mon Sep 17 00:00:00 2001 From: sk89q Date: Tue, 1 Jul 2014 12:42:18 -0700 Subject: [PATCH 19/21] Added utility Transforms class. --- .../worldedit/math/transform/Transforms.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/main/java/com/sk89q/worldedit/math/transform/Transforms.java diff --git a/src/main/java/com/sk89q/worldedit/math/transform/Transforms.java b/src/main/java/com/sk89q/worldedit/math/transform/Transforms.java new file mode 100644 index 000000000..35f8a3df8 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/math/transform/Transforms.java @@ -0,0 +1,49 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.math.transform; + +import com.sk89q.worldedit.util.Location; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Various utility methods related to {@link Transform}s. + */ +public final class Transforms { + + private Transforms() { + } + + /** + * Transform a location's position with a given transform. + *

+ * Direction is unaffected. + * + * @param location the location + * @param transform the transform + * @return the transformed location + */ + public static Location transform(Location location, Transform transform) { + checkNotNull(location); + checkNotNull(transform); + return new Location(location.getWorld(), transform.apply(location.toVector()), location.getDirection()); + } + +} From f3fe8f2ad85c2fa1408e39838a000dad8d42577b Mon Sep 17 00:00:00 2001 From: sk89q Date: Tue, 1 Jul 2014 12:47:56 -0700 Subject: [PATCH 20/21] Extracted CommandMapping interface. --- .../util/command/CommandMapping.java | 57 ++++----------- .../util/command/SimpleCommandMapping.java | 72 +++++++++++++++++++ .../util/command/SimpleDispatcher.java | 2 +- 3 files changed, 85 insertions(+), 46 deletions(-) create mode 100644 src/main/java/com/sk89q/worldedit/util/command/SimpleCommandMapping.java diff --git a/src/main/java/com/sk89q/worldedit/util/command/CommandMapping.java b/src/main/java/com/sk89q/worldedit/util/command/CommandMapping.java index 6e44bff17..093850728 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/CommandMapping.java +++ b/src/main/java/com/sk89q/worldedit/util/command/CommandMapping.java @@ -19,70 +19,37 @@ package com.sk89q.worldedit.util.command; -import java.util.Arrays; - /** - * Tracks a command registration. + * Provides information about a mapping between a command and its aliases. */ -public class CommandMapping { - - private final String[] aliases; - private final CommandCallable callable; - - /** - * Create a new instance. - * - * @param callable the command callable - * @param alias a list of all aliases, where the first one is the primary one - */ - public CommandMapping(CommandCallable callable, String... alias) { - super(); - this.aliases = alias; - this.callable = callable; - } +public interface CommandMapping { /** * Get the primary alias. - * + * * @return the primary alias */ - public String getPrimaryAlias() { - return aliases[0]; - } - + String getPrimaryAlias(); + /** * Get a list of all aliases. - * + * * @return aliases */ - public String[] getAllAliases() { - return aliases; - } - + String[] getAllAliases(); + /** * Get the callable - * + * * @return the callable */ - public CommandCallable getCallable() { - return callable; - } + CommandCallable getCallable(); /** * Get the {@link Description} form the callable. - * + * * @return the description */ - public Description getDescription() { - return getCallable().getDescription(); - } - - @Override - public String toString() { - return "CommandMapping{" + - "aliases=" + Arrays.toString(aliases) + - ", callable=" + callable + - '}'; - } + Description getDescription(); } diff --git a/src/main/java/com/sk89q/worldedit/util/command/SimpleCommandMapping.java b/src/main/java/com/sk89q/worldedit/util/command/SimpleCommandMapping.java new file mode 100644 index 000000000..982832c48 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/command/SimpleCommandMapping.java @@ -0,0 +1,72 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.command; + +import java.util.Arrays; + +/** + * Tracks a command registration. + */ +public class SimpleCommandMapping implements CommandMapping { + + private final String[] aliases; + private final CommandCallable callable; + + /** + * Create a new instance. + * + * @param callable the command callable + * @param alias a list of all aliases, where the first one is the primary one + */ + public SimpleCommandMapping(CommandCallable callable, String... alias) { + super(); + this.aliases = alias; + this.callable = callable; + } + + @Override + public String getPrimaryAlias() { + return aliases[0]; + } + + @Override + public String[] getAllAliases() { + return aliases; + } + + @Override + public CommandCallable getCallable() { + return callable; + } + + @Override + public Description getDescription() { + return getCallable().getDescription(); + } + + @Override + public String toString() { + return "CommandMapping{" + + "aliases=" + Arrays.toString(aliases) + + ", callable=" + callable + + '}'; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java b/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java index 8bb7d52c5..86dbcc70a 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java +++ b/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java @@ -55,7 +55,7 @@ public class SimpleDispatcher implements Dispatcher { @Override public void registerCommand(CommandCallable callable, String... alias) { - CommandMapping mapping = new CommandMapping(callable, alias); + CommandMapping mapping = new SimpleCommandMapping(callable, alias); // Check for replacements for (String a : alias) { From 1b0a6bfcd8ba925a46c0abc0b6536872e1682178 Mon Sep 17 00:00:00 2001 From: sk89q Date: Tue, 1 Jul 2014 12:56:27 -0700 Subject: [PATCH 21/21] Removed CommandCallable.getValueFlags(). Parsing of arguments is no longer done automatically so this method is extraneous. --- .../com/sk89q/worldedit/util/command/CommandCallable.java | 8 -------- .../sk89q/worldedit/util/command/SimpleDispatcher.java | 5 ----- .../util/command/parametric/ParametricCallable.java | 6 +++++- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/sk89q/worldedit/util/command/CommandCallable.java b/src/main/java/com/sk89q/worldedit/util/command/CommandCallable.java index 9a16a467c..3c75884c5 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/CommandCallable.java +++ b/src/main/java/com/sk89q/worldedit/util/command/CommandCallable.java @@ -23,19 +23,11 @@ import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandLocals; import java.util.List; -import java.util.Set; /** * A command that can be executed. */ public interface CommandCallable { - - /** - * Get a list of value flags used by this command. - * - * @return a list of value flags - */ - Set getValueFlags(); /** * Execute the correct command based on the input. diff --git a/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java b/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java index 86dbcc70a..ea027ec55 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java +++ b/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java @@ -101,11 +101,6 @@ public class SimpleDispatcher implements Dispatcher { return commands.get(alias.toLowerCase()); } - @Override - public Set getValueFlags() { - return Collections.emptySet(); - } - @Override public boolean call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException { // We have permission for this command if we have permissions for subcommands diff --git a/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java b/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java index 7a657d848..6fc9266fe 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java +++ b/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java @@ -273,7 +273,11 @@ class ParametricCallable implements CommandCallable { return Collections.emptyList(); } - @Override + /** + * Get a list of value flags used by this command. + * + * @return a list of value flags + */ public Set getValueFlags() { return valueFlags; }