Update new commands with suggestion and help support.

This commit is contained in:
Albert Pham 2015-10-27 13:51:45 -07:00
parent 935de4c93d
commit f4bb5272e1
32 changed files with 1150 additions and 215 deletions

View File

@ -51,6 +51,7 @@
<allow pkg="cpw"/> <allow pkg="cpw"/>
<allow pkg="net.minecraft"/> <allow pkg="net.minecraft"/>
<allow pkg="net.minecraftforge"/> <allow pkg="net.minecraftforge"/>
<allow pkg="com.mojang.authlib"/>
<allow pkg="org.apache.logging.log4j"/> <allow pkg="org.apache.logging.log4j"/>
<allow pkg="org.lwjgl"/> <allow pkg="org.lwjgl"/>
</subpackage> </subpackage>

View File

@ -17,40 +17,49 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.util.command; package com.sk89q.worldedit.command.argument;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import java.util.List; import java.util.List;
public abstract class CommandExecutor<T> implements CommandCallable { public class BooleanFlag implements CommandExecutor<Boolean> {
@Override private final char flag;
public final T call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException { private final String description;
CommandArgs args = new CommandArgs.Parser().parse(arguments);
T ret = call(args, locals, parentCommands); public BooleanFlag(char flag, String description) {
args.requireAllConsumed(); this.flag = flag;
return ret; this.description = description;
} }
public abstract T call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException; @Override
public Boolean call(CommandArgs args, CommandLocals locals) throws CommandException {
return args.containsFlag(flag);
}
@Override @Override
public Description getDescription() { public List<String> getSuggestions(CommandArgs args, CommandLocals locals) {
return new SimpleDescription(); return Lists.newArrayList("-" + flag);
}
@Override
public String getUsage() {
return "[-" + flag + "]";
}
@Override
public String getDescription() {
return description;
} }
@Override @Override
public boolean testPermission(CommandLocals locals) { public boolean testPermission(CommandLocals locals) {
return false; return true;
}
@Override
public List<String> getSuggestions(String arguments, CommandLocals locals) throws CommandException {
return Lists.newArrayList();
} }
} }

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.command.argument;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
@ -29,16 +29,20 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.function.factory.Deform; import com.sk89q.worldedit.function.factory.Deform;
import com.sk89q.worldedit.function.factory.Deform.Mode; import com.sk89q.worldedit.function.factory.Deform.Mode;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.composition.SimpleCommand;
public class DeformCommand extends CommandExecutor<Deform> { public class DeformArg extends SimpleCommand<Deform> {
private final BooleanFlag rawCoordsFlag = addParameter(new BooleanFlag('r', "Raw coords mode"));
private final BooleanFlag offsetFlag = addParameter(new BooleanFlag('o', "Offset mode"));
private final StringArg expressionParser = addParameter(new StringArg("expression", "Expression to apply"));
@Override @Override
public Deform call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException { public Deform call(CommandArgs args, CommandLocals locals) throws CommandException {
String expression = args.next(); String expression = expressionParser.call(args, locals);
boolean rawCoords = args.containsFlag('r'); boolean rawCoords = rawCoordsFlag.call(args, locals);
boolean offset = args.containsFlag('o'); boolean offset = offsetFlag.call(args, locals);
Deform deform = new Deform(expression); Deform deform = new Deform(expression);
@ -60,4 +64,14 @@ public class DeformCommand extends CommandExecutor<Deform> {
return deform; return deform;
} }
@Override
public String getDescription() {
return "Deforms an area by applying a math expression";
}
@Override
protected boolean testPermission0(CommandLocals locals) {
return true;
}
} }

View File

@ -17,27 +17,39 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.command.argument;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.util.command.composition.SimpleCommand;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
public class ItemCommand extends CommandExecutor<BaseItem> { public class ItemArg extends SimpleCommand<BaseItem> {
private final StringArg stringArg;
public ItemArg(String name) {
stringArg = addParameter(new StringArg(name, "The item name", null));
}
public ItemArg(String name, String defaultSuggestion) {
stringArg = addParameter(new StringArg(name, "The item name", defaultSuggestion));
}
@Override @Override
public BaseItem call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException { public BaseItem call(CommandArgs args, CommandLocals locals) throws CommandException {
String itemString = stringArg.call(args, locals);
Actor actor = locals.get(Actor.class); Actor actor = locals.get(Actor.class);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor); LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
@ -52,7 +64,7 @@ public class ItemCommand extends CommandExecutor<BaseItem> {
parserContext.setSession(session); parserContext.setSession(session);
try { try {
return WorldEdit.getInstance().getItemFactory().parseFromInput(args.next(), parserContext); return WorldEdit.getInstance().getItemFactory().parseFromInput(itemString, parserContext);
} catch (NoMatchException e) { } catch (NoMatchException e) {
throw new CommandException(e.getMessage(), e); throw new CommandException(e.getMessage(), e);
} catch (InputParseException e) { } catch (InputParseException e) {
@ -60,4 +72,14 @@ public class ItemCommand extends CommandExecutor<BaseItem> {
} }
} }
@Override
public String getDescription() {
return "Match an item";
}
@Override
protected boolean testPermission0(CommandLocals locals) {
return true;
}
} }

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.command.argument;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
@ -29,20 +29,32 @@ import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.function.EditContext; import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.composition.SimpleCommand;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class ItemUseCommand extends CommandExecutor<Function<EditContext, RegionFunction>> { public class ItemUserArg extends SimpleCommand<Function<EditContext, RegionFunction>> {
private final ItemArg itemArg = addParameter(new ItemArg("item", "minecraft:dye:15"));
@Override @Override
public Function<EditContext, RegionFunction> call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException { public Function<EditContext, RegionFunction> call(CommandArgs args, CommandLocals locals) throws CommandException {
BaseItem item = new ItemCommand().call(args, locals, parentCommands); BaseItem item = itemArg.call(args, locals);
return new ItemUseFactory(item); return new ItemUseFactory(item);
} }
@Override
public String getDescription() {
return "Applies an item";
}
@Override
protected boolean testPermission0(CommandLocals locals) {
return true;
}
private static final class ItemUseFactory implements Function<EditContext, RegionFunction> { private static final class ItemUseFactory implements Function<EditContext, RegionFunction> {
private final BaseItem item; private final BaseItem item;

View File

@ -0,0 +1,83 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.argument;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import java.util.Collections;
import java.util.List;
public class NumberArg implements CommandExecutor<Number> {
private final String name;
private final String description;
private final String defaultSuggestion;
public NumberArg(String name, String description) {
this(name, description, null);
}
public NumberArg(String name, String description, String defaultSuggestion) {
this.name = name;
this.description = description;
this.defaultSuggestion = defaultSuggestion;
}
@Override
public Number call(CommandArgs args, CommandLocals locals) throws CommandException {
try {
String next = args.next();
try {
return Double.parseDouble(next);
} catch (NumberFormatException ignored) {
throw new CommandException("The value for <" + name + "> should be a number. '" + next + "' is not a number.");
}
} catch (MissingArgumentException e) {
throw new CommandException("Missing value for <" + name + "> (try a number).");
}
}
@Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
String value = args.next();
return value.isEmpty() && defaultSuggestion != null ? Lists.newArrayList(defaultSuggestion) : Collections.<String>emptyList();
}
@Override
public String getUsage() {
return "<" + name + ">";
}
@Override
public String getDescription() {
return description;
}
@Override
public boolean testPermission(CommandLocals locals) {
return true;
}
}

View File

@ -17,12 +17,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.command.argument;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.util.command.composition.SimpleCommand;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.NoMatchException;
@ -30,14 +31,21 @@ import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
public class PatternCommand extends CommandExecutor<Pattern> { public class PatternArg extends SimpleCommand<Pattern> {
private final StringArg stringArg;
public PatternArg(String name) {
stringArg = addParameter(new StringArg(name, "The pattern"));
}
@Override @Override
public Pattern call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException { public Pattern call(CommandArgs args, CommandLocals locals) throws CommandException {
String patternString = stringArg.call(args, locals);
Actor actor = locals.get(Actor.class); Actor actor = locals.get(Actor.class);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor); LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
@ -52,7 +60,7 @@ public class PatternCommand extends CommandExecutor<Pattern> {
parserContext.setSession(session); parserContext.setSession(session);
try { try {
return WorldEdit.getInstance().getPatternFactory().parseFromInput(args.next(), parserContext); return WorldEdit.getInstance().getPatternFactory().parseFromInput(patternString, parserContext);
} catch (NoMatchException e) { } catch (NoMatchException e) {
throw new CommandException(e.getMessage(), e); throw new CommandException(e.getMessage(), e);
} catch (InputParseException e) { } catch (InputParseException e) {
@ -60,4 +68,14 @@ public class PatternCommand extends CommandExecutor<Pattern> {
} }
} }
@Override
public String getDescription() {
return "Choose a pattern";
}
@Override
public boolean testPermission0(CommandLocals locals) {
return true;
}
} }

View File

@ -0,0 +1,40 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.argument;
import com.google.common.base.Function;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.util.command.composition.BranchingCommand;
public class PointGeneratorArg extends BranchingCommand<Function<EditContext, ? extends RegionFunction>> {
public PointGeneratorArg() {
super("generatorType");
putOption(new TreeGeneratorArg("treeType"), "tree", "forest");
putOption(new ItemUserArg(), "item", "itemstack", "use");
}
@Override
public String getDescription() {
return "Choose a point generator function";
}
}

View File

@ -0,0 +1,78 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.argument;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.regions.factory.CuboidRegionFactory;
import com.sk89q.worldedit.regions.factory.CylinderRegionFactory;
import com.sk89q.worldedit.regions.factory.RegionFactory;
import com.sk89q.worldedit.regions.factory.SphereRegionFactory;
import com.sk89q.worldedit.util.command.argument.ArgumentUtils;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import java.util.List;
public class RegionFactoryArg implements CommandExecutor<RegionFactory> {
@Override
public RegionFactory call(CommandArgs args, CommandLocals locals) throws CommandException {
try {
String type = args.next();
if (type.equals("cuboid")) {
return new CuboidRegionFactory();
} else if (type.equals("sphere")) {
return new SphereRegionFactory();
} else if (type.equals("cyl") || type.equals("cylinder")) {
return new CylinderRegionFactory(1); // TODO: Adjustable height
} else {
throw new CommandException("Unknown shape type: " + type + " (try one of " + getUsage() + ")");
}
} catch (MissingArgumentException e) {
throw new CommandException("Missing shape type (try one of " + getUsage() + ")");
}
}
@Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
return ArgumentUtils.getMatchingSuggestions(Lists.newArrayList("cuboid", "sphere", "cyl"), args.next());
}
@Override
public String getUsage() {
return "(cuboid | sphere | cyl)";
}
@Override
public String getDescription() {
return "Defines a region";
}
@Override
public boolean testPermission(CommandLocals locals) {
return true;
}
}

View File

@ -17,29 +17,43 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.command.argument;
import com.google.common.base.Function;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.function.EditContext; import com.sk89q.worldedit.function.factory.RegionReplace;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
import com.sk89q.worldedit.util.command.CommandExecutor; import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
public class PointGeneratorCommand extends CommandExecutor<Function<EditContext, ? extends RegionFunction>> { import java.util.Collections;
import java.util.List;
public class RegionReplaceArg implements CommandExecutor<RegionReplace> {
@Override @Override
public Function<EditContext, ? extends RegionFunction> call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException { public RegionReplace call(CommandArgs args, CommandLocals locals) throws CommandException {
String type = args.next(); return new RegionReplace();
if (type.equalsIgnoreCase("forest") || type.equalsIgnoreCase("tree")) {
return new TreeGeneratorCommand().call(args, locals, parentCommands);
} else if (type.equalsIgnoreCase("item") || type.equalsIgnoreCase("itemstack")) {
return new ItemUseCommand().call(args, locals, parentCommands);
} else {
throw new CommandException("Unknown type of generator: " + type);
} }
@Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
return Collections.emptyList();
}
@Override
public String getUsage() {
return "";
}
@Override
public String getDescription() {
return "Replaces a region";
}
@Override
public boolean testPermission(CommandLocals locals) {
return true;
} }
} }

View File

@ -0,0 +1,78 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.argument;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import java.util.Collections;
import java.util.List;
public class StringArg implements CommandExecutor<String> {
private final String name;
private final String description;
private final String defaultSuggestion;
public StringArg(String name, String description) {
this(name, description, null);
}
public StringArg(String name, String description, String defaultSuggestion) {
this.name = name;
this.description = description;
this.defaultSuggestion = defaultSuggestion;
}
@Override
public String call(CommandArgs args, CommandLocals locals) throws CommandException {
try {
return args.next();
} catch (MissingArgumentException e) {
throw new CommandException("Missing value for <" + name + ">.");
}
}
@Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
String value = args.next();
return value.isEmpty() && defaultSuggestion != null ? Lists.newArrayList(defaultSuggestion) : Collections.<String>emptyList();
}
@Override
public String getUsage() {
return "<" + name + ">";
}
@Override
public String getDescription() {
return description;
}
@Override
public boolean testPermission(CommandLocals locals) {
return true;
}
}

View File

@ -17,9 +17,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.command.argument;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
@ -27,23 +29,61 @@ import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.generator.ForestGenerator; import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.util.command.CommandExecutor; import com.sk89q.worldedit.util.command.argument.ArgumentUtils;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
public class TreeGeneratorCommand extends CommandExecutor<Function<EditContext, ForestGenerator>> { public class TreeGeneratorArg implements CommandExecutor<Function<EditContext, ForestGenerator>> {
private final String name;
public TreeGeneratorArg(String name) {
this.name = name;
}
private String getOptionsList() {
return Joiner.on(" | ").join(Arrays.asList(TreeType.values()));
}
@Override @Override
public Function<EditContext, ForestGenerator> call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException { public Function<EditContext, ForestGenerator> call(CommandArgs args, CommandLocals locals) throws CommandException {
try {
String input = args.next(); String input = args.next();
TreeType type = TreeGenerator.lookup(input); TreeType type = TreeGenerator.lookup(input);
if (type != null) { if (type != null) {
return new GeneratorFactory(type); return new GeneratorFactory(type);
} else { } else {
throw new CommandException(String.format("Can't recognize tree type '%s' -- choose from: %s", input, Arrays.toString(TreeType.values()))); throw new CommandException("Unknown value for <" + name + "> (try one of " + getOptionsList() + ").");
} }
} catch (MissingArgumentException e) {
throw new CommandException("Missing value for <" + name + "> (try one of " + getOptionsList() + ").");
}
}
@Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
String s = args.next();
return s.isEmpty() ? Lists.newArrayList(TreeType.getPrimaryAliases()) : ArgumentUtils.getMatchingSuggestions(TreeType.getAliases(), s);
}
@Override
public String getUsage() {
return "<" + name + ">";
}
@Override
public String getDescription() {
return "Choose a tree generator";
}
@Override
public boolean testPermission(CommandLocals locals) {
return true;
} }
private static class GeneratorFactory implements Function<EditContext, ForestGenerator> { private static class GeneratorFactory implements Function<EditContext, ForestGenerator> {
@ -64,4 +104,5 @@ public class TreeGeneratorCommand extends CommandExecutor<Function<EditContext,
return "tree of type " + type; return "tree of type " + type;
} }
} }
} }

View File

@ -17,24 +17,44 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.command.tool.brush; package com.sk89q.worldedit.command.composition;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.command.composition.PointGeneratorCommand; import com.sk89q.worldedit.command.argument.PointGeneratorArg;
import com.sk89q.worldedit.function.EditContext; import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.factory.RegionApply; import com.sk89q.worldedit.function.factory.RegionApply;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.composition.ParameterCommand;
public class ApplyCommand extends CommandExecutor<RegionApply> { import java.util.Collections;
import java.util.List;
public class ApplyCommand extends ParameterCommand<RegionApply> {
private final PointGeneratorArg pointGeneratorArg = addParameter(new PointGeneratorArg());
@Override @Override
public RegionApply call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException { public RegionApply call(CommandArgs args, CommandLocals locals) throws CommandException {
Function<EditContext, ? extends RegionFunction> function = new PointGeneratorCommand().call(args, locals, parentCommands); Function<EditContext, ? extends RegionFunction> function = pointGeneratorArg.call(args, locals);
return new RegionApply(function); return new RegionApply(function);
} }
@Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) {
return Collections.emptyList();
}
@Override
public String getDescription() {
return "Applies a point generator to an area";
}
@Override
protected boolean testPermission0(CommandLocals locals) {
return true;
}
} }

View File

@ -1,48 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.composition;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.regions.factory.CuboidRegionFactory;
import com.sk89q.worldedit.regions.factory.CylinderRegionFactory;
import com.sk89q.worldedit.regions.factory.RegionFactory;
import com.sk89q.worldedit.regions.factory.SphereRegionFactory;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
public class RegionFactoryCommand extends CommandExecutor<RegionFactory> {
@Override
public RegionFactory call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
String type = args.next();
if (type.equals("cuboid")) {
return new CuboidRegionFactory();
} else if (type.equals("sphere")) {
return new SphereRegionFactory();
} else if (type.equals("cyl") || type.equals("cylinder")) {
return new CylinderRegionFactory(1); // TODO: Adjustable height
} else {
throw new CommandException("Unknown shape type: " + type);
}
}
}

View File

@ -23,28 +23,31 @@ import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.argument.PatternArg;
import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.BrushTool;
import com.sk89q.worldedit.command.tool.InvalidToolBindException; import com.sk89q.worldedit.command.tool.InvalidToolBindException;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.command.CommandExecutor; import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.composition.SimpleCommand;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public class FillBrushCommand<T> extends CommandExecutor<T> { public class ReplaceBrushCommand<T> extends SimpleCommand<T> {
private final PatternArg patternArg = addParameter(new PatternArg("fillPattern"));
private final CommandExecutor<? extends T> delegate; private final CommandExecutor<? extends T> delegate;
public FillBrushCommand(CommandExecutor<? extends T> delegate) { public ReplaceBrushCommand(CommandExecutor<? extends T> delegate) {
checkNotNull(delegate, "delegate"); checkNotNull(delegate, "delegate");
this.delegate = delegate; this.delegate = addParameter(delegate);
} }
@Override @Override
public T call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException { public T call(CommandArgs args, CommandLocals locals) throws CommandException {
Pattern pattern = new PatternCommand().call(args, locals, parentCommands); Pattern pattern = patternArg.call(args, locals);
Player player = (Player) locals.get(Actor.class); Player player = (Player) locals.get(Actor.class);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player); LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
@ -56,6 +59,17 @@ public class FillBrushCommand<T> extends CommandExecutor<T> {
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e); WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e);
} }
return delegate.call(args, locals, parentCommands); return delegate.call(args, locals);
} }
@Override
public String getDescription() {
return "Replaces an area with a pattern";
}
@Override
protected boolean testPermission0(CommandLocals locals) {
return true;
}
} }

View File

@ -22,19 +22,34 @@ package com.sk89q.worldedit.command.composition;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.command.argument.NumberArg;
import com.sk89q.worldedit.command.argument.PointGeneratorArg;
import com.sk89q.worldedit.function.EditContext; import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.factory.Scatter; import com.sk89q.worldedit.function.factory.Scatter;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.composition.SimpleCommand;
public class ScatterCommand extends CommandExecutor<Scatter> { public class ScatterCommand extends SimpleCommand<Scatter> {
private final NumberArg densityCommand = addParameter(new NumberArg("density", "0-100", "20"));
private final PointGeneratorArg pointGeneratorArg = addParameter(new PointGeneratorArg());
@Override @Override
public Scatter call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException { public Scatter call(CommandArgs args, CommandLocals locals) throws CommandException {
double density = args.nextDouble() / 100.0; double density = densityCommand.call(args, locals).doubleValue() / 100.0;
Function<EditContext, ? extends RegionFunction> function = new PointGeneratorCommand().call(args, locals, parentCommands); Function<EditContext, ? extends RegionFunction> function = pointGeneratorArg.call(args, locals);
return new Scatter(function, density); return new Scatter(function, density);
} }
@Override
public String getDescription() {
return "Scatters a function over an area";
}
@Override
protected boolean testPermission0(CommandLocals locals) {
return true;
}
} }

View File

@ -19,13 +19,14 @@
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.command.composition;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.minecraft.util.commands.CommandPermissionsException; import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxBrushRadiusException; import com.sk89q.worldedit.MaxBrushRadiusException;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.argument.NumberArg;
import com.sk89q.worldedit.command.argument.RegionFactoryArg;
import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.BrushTool;
import com.sk89q.worldedit.command.tool.InvalidToolBindException; import com.sk89q.worldedit.command.tool.InvalidToolBindException;
import com.sk89q.worldedit.command.tool.brush.OperationFactoryBrush; import com.sk89q.worldedit.command.tool.brush.OperationFactoryBrush;
@ -33,39 +34,36 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.function.factory.OperationFactory; import com.sk89q.worldedit.function.factory.OperationFactory;
import com.sk89q.worldedit.regions.factory.RegionFactory; import com.sk89q.worldedit.regions.factory.RegionFactory;
import com.sk89q.worldedit.util.command.CommandExecutor; import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import com.sk89q.worldedit.util.command.Description;
import com.sk89q.worldedit.util.command.Parameter;
import com.sk89q.worldedit.util.command.SimpleDescription;
import com.sk89q.worldedit.util.command.SimpleParameter;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.composition.SimpleCommand;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public class ShapedBrushCommand extends CommandExecutor<Object> { public class ShapedBrushCommand extends SimpleCommand<Object> {
private final CommandExecutor<? extends OperationFactory> delegate; private final CommandExecutor<? extends OperationFactory> delegate;
private final String permission; private final String permission;
private final RegionFactoryArg regionFactoryArg = addParameter(new RegionFactoryArg());
private final NumberArg radiusCommand = addParameter(new NumberArg("size", "The size of the brush", "5"));
public ShapedBrushCommand(CommandExecutor<? extends OperationFactory> delegate, String permission) { public ShapedBrushCommand(CommandExecutor<? extends OperationFactory> delegate, String permission) {
checkNotNull(delegate, "delegate"); checkNotNull(delegate, "delegate");
this.permission = permission; this.permission = permission;
this.delegate = delegate; this.delegate = delegate;
addParameter(delegate);
} }
@Override @Override
public Object call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException { public Object call(CommandArgs args, CommandLocals locals) throws CommandException {
if (!testPermission(locals)) { if (!testPermission(locals)) {
throw new CommandPermissionsException(); throw new CommandPermissionsException();
} }
RegionFactory regionFactory = new RegionFactoryCommand().call(args, locals, parentCommands); RegionFactory regionFactory = regionFactoryArg.call(args, locals);
int radius = args.nextInt(); int radius = radiusCommand.call(args, locals).intValue();
OperationFactory factory = delegate.call(args, locals, parentCommands); OperationFactory factory = delegate.call(args, locals);
args.requireAllConsumed();
Player player = (Player) locals.get(Actor.class); Player player = (Player) locals.get(Actor.class);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player); LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
@ -87,22 +85,12 @@ public class ShapedBrushCommand extends CommandExecutor<Object> {
} }
@Override @Override
public Description getDescription() { public String getDescription() {
List<Parameter> parameters = Lists.newArrayList(); return delegate.getDescription();
parameters.add(new SimpleParameter("radius"));
parameters.add(new SimpleParameter("shape"));
parameters.add(new SimpleParameter("...shapeArgs...").setOptional(true));
parameters.add(new SimpleParameter("...brushArgs...").setOptional(true));
SimpleDescription desc = new SimpleDescription();
desc.setDescription(delegate.getDescription().getDescription());
desc.setHelp(delegate.getDescription().getHelp());
desc.setPermissions(Lists.newArrayList(permission));
return desc;
} }
@Override @Override
public boolean testPermission(CommandLocals locals) { public boolean testPermission0(CommandLocals locals) {
Actor sender = locals.get(Actor.class); Actor sender = locals.get(Actor.class);
if (sender == null) { if (sender == null) {
throw new RuntimeException("Uh oh! No 'Actor' specified so that we can check permissions"); throw new RuntimeException("Uh oh! No 'Actor' specified so that we can check permissions");

View File

@ -47,12 +47,12 @@ import com.sk89q.worldedit.command.ToolCommands;
import com.sk89q.worldedit.command.ToolUtilCommands; import com.sk89q.worldedit.command.ToolUtilCommands;
import com.sk89q.worldedit.command.UtilityCommands; import com.sk89q.worldedit.command.UtilityCommands;
import com.sk89q.worldedit.command.WorldEditCommands; import com.sk89q.worldedit.command.WorldEditCommands;
import com.sk89q.worldedit.command.composition.DeformCommand; import com.sk89q.worldedit.command.argument.DeformArg;
import com.sk89q.worldedit.command.composition.FillBrushCommand; import com.sk89q.worldedit.command.composition.ReplaceBrushCommand;
import com.sk89q.worldedit.command.composition.RegionReplaceCommand; import com.sk89q.worldedit.command.argument.RegionReplaceArg;
import com.sk89q.worldedit.command.composition.ScatterCommand; import com.sk89q.worldedit.command.composition.ScatterCommand;
import com.sk89q.worldedit.command.composition.ShapedBrushCommand; import com.sk89q.worldedit.command.composition.ShapedBrushCommand;
import com.sk89q.worldedit.command.tool.brush.ApplyCommand; import com.sk89q.worldedit.command.composition.ApplyCommand;
import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent; import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.function.factory.OperationFactory; import com.sk89q.worldedit.function.factory.OperationFactory;
@ -64,6 +64,7 @@ import com.sk89q.worldedit.internal.command.WorldEditExceptionConverter;
import com.sk89q.worldedit.session.request.Request; import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.InvalidUsageException; import com.sk89q.worldedit.util.command.InvalidUsageException;
import com.sk89q.worldedit.util.command.composition.LegacyCommandAdapter;
import com.sk89q.worldedit.util.command.fluent.CommandGraph; import com.sk89q.worldedit.util.command.fluent.CommandGraph;
import com.sk89q.worldedit.util.command.parametric.ExceptionConverter; import com.sk89q.worldedit.util.command.parametric.ExceptionConverter;
import com.sk89q.worldedit.util.command.parametric.LegacyCommandsHandler; import com.sk89q.worldedit.util.command.parametric.LegacyCommandsHandler;
@ -161,10 +162,10 @@ public final class CommandManager {
.group("brush", "br") .group("brush", "br")
.describeAs("Brushing commands") .describeAs("Brushing commands")
.registerMethods(new BrushCommands(worldEdit)) .registerMethods(new BrushCommands(worldEdit))
.register(new ShapedBrushCommand(new DeformCommand(), "worldedit.brush.deform"), "deform") .register(new LegacyCommandAdapter(new ShapedBrushCommand(new DeformArg(), "worldedit.brush.deform")), "deform")
.register(new ShapedBrushCommand(new FillBrushCommand<OperationFactory>(new RegionReplaceCommand()), "worldedit.brush.set"), "set") .register(new LegacyCommandAdapter(new ShapedBrushCommand(new ReplaceBrushCommand<OperationFactory>(new RegionReplaceArg()), "worldedit.brush.set")), "set")
.register(new ShapedBrushCommand(new ScatterCommand(), "worldedit.brush.scatter"), "scatter") .register(new LegacyCommandAdapter(new ShapedBrushCommand(new ScatterCommand(), "worldedit.brush.scatter")), "scatter")
.register(new ShapedBrushCommand(new ApplyCommand(), "worldedit.brush.apply"), "apply") .register(new LegacyCommandAdapter(new ShapedBrushCommand(new ApplyCommand(), "worldedit.brush.apply")), "apply")
.parent() .parent()
.group("superpickaxe", "pickaxe", "sp") .group("superpickaxe", "pickaxe", "sp")
.describeAs("Super-pickaxe commands") .describeAs("Super-pickaxe commands")

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.util; package com.sk89q.worldedit.util;
import com.google.common.collect.Sets;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
@ -26,10 +27,12 @@ import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockID;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set;
/** /**
* Tree generator. * Tree generator.
@ -105,6 +108,7 @@ public class TreeGenerator {
* Stores a map of the names for fast access. * Stores a map of the names for fast access.
*/ */
private static final Map<String, TreeType> lookup = new HashMap<String, TreeType>(); private static final Map<String, TreeType> lookup = new HashMap<String, TreeType>();
private static final Set<String> primaryAliases = Sets.newHashSet();
private final String name; private final String name;
private final String[] lookupKeys; private final String[] lookupKeys;
@ -114,6 +118,9 @@ public class TreeGenerator {
for (String key : type.lookupKeys) { for (String key : type.lookupKeys) {
lookup.put(key, type); lookup.put(key, type);
} }
if (type.lookupKeys.length > 0) {
primaryAliases.add(type.lookupKeys[0]);
}
} }
} }
@ -122,6 +129,14 @@ public class TreeGenerator {
this.lookupKeys = lookupKeys; this.lookupKeys = lookupKeys;
} }
public static Set<String> getAliases() {
return Collections.unmodifiableSet(lookup.keySet());
}
public static Set<String> getPrimaryAliases() {
return Collections.unmodifiableSet(primaryAliases);
}
public boolean generate(EditSession editSession, Vector pos) throws MaxChangedBlocksException { public boolean generate(EditSession editSession, Vector pos) throws MaxChangedBlocksException {
return editSession.getWorld().generateTree(this, editSession, pos); return editSession.getWorld().generateTree(this, editSession, pos);
} }

View File

@ -102,8 +102,9 @@ public class SimpleDescription implements Description {
* *
* @param usage usage string, or null * @param usage usage string, or null
*/ */
public void overrideUsage(String usage) { public SimpleDescription overrideUsage(String usage) {
this.overrideUsage = usage; this.overrideUsage = usage;
return this;
} }
@Override @Override

View File

@ -17,7 +17,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.util.command.argument;
public class ArgumentException extends Exception {
public ArgumentException() {
}
public ArgumentException(String message) {
super(message);
}
public ArgumentException(String message, Throwable cause) {
super(message, cause);
}
public ArgumentException(Throwable cause) {
super(cause);
}
public class ForestCommand {
} }

View File

@ -0,0 +1,39 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.command.argument;
public class ArgumentParseException extends ArgumentException {
public ArgumentParseException() {
}
public ArgumentParseException(String message) {
super(message);
}
public ArgumentParseException(String message, Throwable cause) {
super(message, cause);
}
public ArgumentParseException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,45 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.command.argument;
import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.List;
public final class ArgumentUtils {
private ArgumentUtils() {
}
public static List<String> getMatchingSuggestions(Collection<String> items, String s) {
if (s.isEmpty()) {
return Lists.newArrayList(items);
}
List<String> suggestions = Lists.newArrayList();
for (String item : items) {
if (item.toLowerCase().startsWith(s)) {
suggestions.add(item);
}
}
return suggestions;
}
}

View File

@ -46,23 +46,23 @@ public class CommandArgs {
return position < arguments.size(); return position < arguments.size();
} }
public String next() throws CommandException { public String next() throws MissingArgumentException {
try { try {
return arguments.get(position++); return arguments.get(position++);
} catch (IndexOutOfBoundsException ignored) { } catch (IndexOutOfBoundsException ignored) {
throw new CommandException("Too few arguments specified."); throw new MissingArgumentException("Too few arguments specified.");
} }
} }
public String peek() throws CommandException { public String peek() throws MissingArgumentException {
try { try {
return arguments.get(position); return arguments.get(position);
} catch (IndexOutOfBoundsException ignored) { } catch (IndexOutOfBoundsException ignored) {
throw new CommandException("Too few arguments specified."); throw new MissingArgumentException("Too few arguments specified.");
} }
} }
public String remaining() throws CommandException { public String remaining() throws MissingArgumentException {
if (hasNext()) { if (hasNext()) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
boolean first = true; boolean first = true;
@ -75,11 +75,11 @@ public class CommandArgs {
} }
return builder.toString(); return builder.toString();
} else { } else {
throw new CommandException("Too few arguments specified."); throw new MissingArgumentException("Too few arguments specified.");
} }
} }
public String peekRemaining() throws CommandException { public String peekRemaining() throws MissingArgumentException {
if (hasNext()) { if (hasNext()) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
boolean first = true; boolean first = true;
@ -92,7 +92,7 @@ public class CommandArgs {
} }
return builder.toString(); return builder.toString();
} else { } else {
throw new CommandException("Too few arguments specified."); throw new MissingArgumentException();
} }
} }
@ -131,7 +131,7 @@ public class CommandArgs {
return flags; return flags;
} }
public void requireAllConsumed() throws CommandException { public void requireAllConsumed() throws UnusedArgumentsException {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
boolean hasUnconsumed = false; boolean hasUnconsumed = false;
@ -149,67 +149,71 @@ public class CommandArgs {
if (hasNext()) { if (hasNext()) {
hasUnconsumed = true; hasUnconsumed = true;
try {
builder.append(peekRemaining()); builder.append(peekRemaining());
} catch (MissingArgumentException e) {
throw new RuntimeException("This should not have happened", e);
}
} }
if (hasUnconsumed) { if (hasUnconsumed) {
throw new CommandException("There were unused arguments: " + builder); throw new UnusedArgumentsException("There were unused arguments: " + builder);
} }
} }
public int nextInt() throws CommandException { public int nextInt() throws ArgumentParseException, MissingArgumentException {
String next = next(); String next = next();
try { try {
return Integer.parseInt(next); return Integer.parseInt(next);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
throw new CommandException("Expected a number, got '" + next + "'"); throw new ArgumentParseException("Expected a number, got '" + next + "'");
} }
} }
public short nextShort() throws CommandException { public short nextShort() throws ArgumentParseException, MissingArgumentException {
String next = next(); String next = next();
try { try {
return Short.parseShort(next); return Short.parseShort(next);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
throw new CommandException("Expected a number, got '" + next + "'"); throw new ArgumentParseException("Expected a number, got '" + next + "'");
} }
} }
public byte nextByte() throws CommandException { public byte nextByte() throws ArgumentParseException, MissingArgumentException {
String next = next(); String next = next();
try { try {
return Byte.parseByte(next); return Byte.parseByte(next);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
throw new CommandException("Expected a number, got '" + next + "'"); throw new ArgumentParseException("Expected a number, got '" + next + "'");
} }
} }
public double nextDouble() throws CommandException { public double nextDouble() throws ArgumentParseException, MissingArgumentException {
String next = next(); String next = next();
try { try {
return Double.parseDouble(next); return Double.parseDouble(next);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
throw new CommandException("Expected a number, got '" + next + "'"); throw new ArgumentParseException("Expected a number, got '" + next + "'");
} }
} }
public float nextFloat() throws CommandException { public float nextFloat() throws ArgumentParseException, MissingArgumentException {
String next = next(); String next = next();
try { try {
return Float.parseFloat(next); return Float.parseFloat(next);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
throw new CommandException("Expected a number, got '" + next + "'"); throw new ArgumentParseException("Expected a number, got '" + next + "'");
} }
} }
public boolean nextBoolean() throws CommandException { public boolean nextBoolean() throws ArgumentParseException, MissingArgumentException {
String next = next(); String next = next();
if (next.equalsIgnoreCase("yes") || next.equalsIgnoreCase("true") || next.equalsIgnoreCase("y") || next.equalsIgnoreCase("1")) { if (next.equalsIgnoreCase("yes") || next.equalsIgnoreCase("true") || next.equalsIgnoreCase("y") || next.equalsIgnoreCase("1")) {
return true; return true;
} else if (next.equalsIgnoreCase("no") || next.equalsIgnoreCase("false") || next.equalsIgnoreCase("n") || next.equalsIgnoreCase("0")) { } else if (next.equalsIgnoreCase("no") || next.equalsIgnoreCase("false") || next.equalsIgnoreCase("n") || next.equalsIgnoreCase("0")) {
return false; return false;
} else { } else {
throw new CommandException("Expected a boolean (yes/no), got '" + next + "'"); throw new ArgumentParseException("Expected a boolean (yes/no), got '" + next + "'");
} }
} }
@ -235,64 +239,65 @@ public class CommandArgs {
return fallback; return fallback;
} }
public int getIntFlag(char c, int fallback) throws CommandException { public int getIntFlag(char c, int fallback) throws ArgumentParseException {
String next = getFlag(c, String.valueOf(fallback)); String next = getFlag(c, String.valueOf(fallback));
try { try {
return Integer.parseInt(next); return Integer.parseInt(next);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
throw new CommandException("Expected a number for flag '-" + c + "', got '" + next + "'"); throw new ArgumentParseException("Expected a number for flag '-" + c + "', got '" + next + "'");
} }
} }
public short getShortFlag(char c, short fallback) throws CommandException { public short getShortFlag(char c, short fallback) throws ArgumentParseException {
String next = getFlag(c, String.valueOf(fallback)); String next = getFlag(c, String.valueOf(fallback));
try { try {
return Short.parseShort(next); return Short.parseShort(next);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
throw new CommandException("Expected a number for flag '-" + c + "', got '" + next + "'"); throw new ArgumentParseException("Expected a number for flag '-" + c + "', got '" + next + "'");
} }
} }
public byte getByteFlag(char c, byte fallback) throws CommandException { public byte getByteFlag(char c, byte fallback) throws ArgumentParseException {
String next = getFlag(c, String.valueOf(fallback)); String next = getFlag(c, String.valueOf(fallback));
try { try {
return Byte.parseByte(next); return Byte.parseByte(next);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
throw new CommandException("Expected a number for flag '-" + c + "', got '" + next + "'"); throw new ArgumentParseException("Expected a number for flag '-" + c + "', got '" + next + "'");
} }
} }
public double getDoubleFlag(char c, double fallback) throws CommandException { public double getDoubleFlag(char c, double fallback) throws ArgumentParseException {
String next = getFlag(c, String.valueOf(fallback)); String next = getFlag(c, String.valueOf(fallback));
try { try {
return Double.parseDouble(next); return Double.parseDouble(next);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
throw new CommandException("Expected a number for flag '-" + c + "', got '" + next + "'"); throw new ArgumentParseException("Expected a number for flag '-" + c + "', got '" + next + "'");
} }
} }
public float getFloatFlag(char c, float fallback) throws CommandException { public float getFloatFlag(char c, float fallback) throws ArgumentParseException {
String next = getFlag(c, String.valueOf(fallback)); String next = getFlag(c, String.valueOf(fallback));
try { try {
return Float.parseFloat(next); return Float.parseFloat(next);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
throw new CommandException("Expected a number for flag '-" + c + "', got '" + next + "'"); throw new ArgumentParseException("Expected a number for flag '-" + c + "', got '" + next + "'");
} }
} }
public boolean getBooleanFlag(char c, boolean fallback) throws CommandException { public boolean getBooleanFlag(char c, boolean fallback) throws ArgumentParseException {
String next = getFlag(c, String.valueOf(fallback)); String next = getFlag(c, String.valueOf(fallback));
if (next.equalsIgnoreCase("yes") || next.equalsIgnoreCase("true") || next.equalsIgnoreCase("y") || next.equalsIgnoreCase("1")) { if (next.equalsIgnoreCase("yes") || next.equalsIgnoreCase("true") || next.equalsIgnoreCase("y") || next.equalsIgnoreCase("1")) {
return true; return true;
} else if (next.equalsIgnoreCase("no") || next.equalsIgnoreCase("false") || next.equalsIgnoreCase("n") || next.equalsIgnoreCase("0")) { } else if (next.equalsIgnoreCase("no") || next.equalsIgnoreCase("false") || next.equalsIgnoreCase("n") || next.equalsIgnoreCase("0")) {
return false; return false;
} else { } else {
throw new CommandException("Expected a boolean (yes/no), got '" + next + "'"); throw new ArgumentParseException("Expected a boolean (yes/no), got '" + next + "'");
} }
} }
public static class Parser { public static class Parser {
private boolean parseFlags = true; private boolean parseFlags = true;
private boolean usingHangingArguments = false;
private Set<Character> valueFlags = Sets.newHashSet(); private Set<Character> valueFlags = Sets.newHashSet();
public boolean isParseFlags() { public boolean isParseFlags() {
@ -304,6 +309,15 @@ public class CommandArgs {
return this; return this;
} }
public boolean isUsingHangingArguments() {
return usingHangingArguments;
}
public Parser setUsingHangingArguments(boolean usingHangingArguments) {
this.usingHangingArguments = usingHangingArguments;
return this;
}
public Set<Character> getValueFlags() { public Set<Character> getValueFlags() {
return valueFlags; return valueFlags;
} }
@ -319,6 +333,11 @@ public class CommandArgs {
for (int i = 0; i < context.argsLength(); i++) { for (int i = 0; i < context.argsLength(); i++) {
args.add(context.getString(i)); args.add(context.getString(i));
} }
if (isUsingHangingArguments()) {
if (arguments.isEmpty() || arguments.endsWith(" ")) {
args.add("");
}
}
Map<Character, String> flags = Maps.newHashMap(context.getValueFlags()); Map<Character, String> flags = Maps.newHashMap(context.getValueFlags());
for (Character c : context.getFlags()) { for (Character c : context.getFlags()) {
flags.put(c, null); flags.put(c, null);

View File

@ -0,0 +1,39 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.command.argument;
public class MissingArgumentException extends ArgumentException {
public MissingArgumentException() {
}
public MissingArgumentException(String message) {
super(message);
}
public MissingArgumentException(String message, Throwable cause) {
super(message, cause);
}
public MissingArgumentException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,39 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.command.argument;
public class UnusedArgumentsException extends ArgumentException {
public UnusedArgumentsException() {
}
public UnusedArgumentsException(String message) {
super(message);
}
public UnusedArgumentsException(String message, Throwable cause) {
super(message, cause);
}
public UnusedArgumentsException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,111 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.command.composition;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.util.command.argument.ArgumentUtils;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
import java.util.List;
import java.util.Map;
import java.util.Set;
public abstract class BranchingCommand<T> implements CommandExecutor<T> {
private final String name;
private final Map<String, CommandExecutor<? extends T>> options = Maps.newHashMap();
private final Set<String> primaryAliases = Sets.newHashSet();
public BranchingCommand(String name) {
this.name = name;
}
public void putOption(CommandExecutor<? extends T> executor, String primaryAlias, String... aliases) {
options.put(primaryAlias, executor);
primaryAliases.add(primaryAlias);
for (String alias : aliases) {
options.put(alias, executor);
}
}
@Override
public T call(CommandArgs args, CommandLocals locals) throws CommandException {
try {
String classifier = args.next();
CommandExecutor<? extends T> executor = options.get(classifier.toLowerCase());
if (executor != null) {
return executor.call(args, locals);
} else {
throw new CommandException("'" + classifier + "' isn't a valid option for '" + name + "'. " +
"Try one of: " + Joiner.on(", ").join(primaryAliases));
}
} catch (MissingArgumentException e) {
throw new CommandException("Missing value for <" + name + "> " +
"(try one of " + Joiner.on(" | ").join(primaryAliases) + ").");
}
}
@Override
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
String classifier = args.next();
try {
CommandExecutor<? extends T> executor = options.get(classifier.toLowerCase());
if (executor != null) {
return executor.getSuggestions(args, locals);
}
} catch (MissingArgumentException ignored) {
}
return ArgumentUtils.getMatchingSuggestions((classifier.isEmpty() ? primaryAliases : options.keySet()), classifier);
}
@Override
public String getUsage() {
List<String> optionUsages = Lists.newArrayList();
for (String alias : primaryAliases) {
CommandExecutor<? extends T> executor = options.get(alias);
String usage = executor.getUsage();
if (usage.isEmpty()) {
optionUsages.add(alias);
} else {
optionUsages.add(alias + " " + executor.getUsage());
}
}
return "(" + Joiner.on(" | ").join(optionUsages) + ")";
}
@Override
public boolean testPermission(CommandLocals locals) {
for (CommandExecutor<?> executor : options.values()) {
if (!executor.testPermission(locals)) {
return false;
}
}
return true;
}
}

View File

@ -17,19 +17,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.util.command.composition;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.function.factory.RegionReplace;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
public class RegionReplaceCommand extends CommandExecutor<RegionReplace> { import java.util.List;
@Override public interface CommandExecutor<T> {
public RegionReplace call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
return new RegionReplace(); T call(CommandArgs args, CommandLocals locals) throws CommandException;
}
List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException;
String getUsage();
String getDescription();
boolean testPermission(CommandLocals locals);
} }

View File

@ -0,0 +1,79 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.command.composition;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.util.command.CommandCallable;
import com.sk89q.worldedit.util.command.Description;
import com.sk89q.worldedit.util.command.SimpleDescription;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
import com.sk89q.worldedit.util.command.argument.UnusedArgumentsException;
import java.util.List;
public class LegacyCommandAdapter implements CommandCallable {
private final CommandExecutor<?> executor;
public LegacyCommandAdapter(CommandExecutor<?> executor) {
this.executor = executor;
}
@Override
public final Object call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException {
CommandArgs args = new CommandArgs.Parser().parse(arguments);
if (args.containsFlag('?')) {
throw new CommandException(executor.getUsage());
} else {
Object ret = executor.call(args, locals);
try {
args.requireAllConsumed();
} catch (UnusedArgumentsException e) {
throw new CommandException(e.getMessage());
}
return ret;
}
}
@Override
public Description getDescription() {
return new SimpleDescription()
.setDescription(executor.getDescription())
.overrideUsage(executor.getUsage());
}
@Override
public boolean testPermission(CommandLocals locals) {
return executor.testPermission(locals);
}
@Override
public List<String> getSuggestions(String arguments, CommandLocals locals) throws CommandException {
CommandArgs args = new CommandArgs.Parser().setUsingHangingArguments(true).parse(arguments);
try {
return executor.getSuggestions(args, locals);
} catch (MissingArgumentException e) {
return Lists.newArrayList();
}
}
}

View File

@ -0,0 +1,63 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.command.composition;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import java.util.List;
public abstract class ParameterCommand<T> implements CommandExecutor<T> {
private final List<CommandExecutor<?>> parameters = Lists.newArrayList();
protected List<CommandExecutor<?>> getParameters() {
return parameters;
}
public <T extends CommandExecutor<?>> T addParameter(T executor) {
parameters.add(executor);
return executor;
}
@Override
public final String getUsage() {
List<String> parts = Lists.newArrayList();
for (CommandExecutor<?> executor : parameters) {
parts.add(executor.getUsage());
}
return Joiner.on(" ").join(parts);
}
@Override
public final boolean testPermission(CommandLocals locals) {
for (CommandExecutor<?> executor : parameters) {
if (!executor.testPermission(locals)) {
return false;
}
}
return testPermission0(locals);
}
protected abstract boolean testPermission0(CommandLocals locals);
}

View File

@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.command.composition;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
import java.util.List;
public abstract class SimpleCommand<T> extends ParameterCommand<T> {
@Override
public final List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
List<String> suggestions = Lists.newArrayList();
boolean seenParameter = false;
for (CommandExecutor<?> parameter : getParameters()) {
try {
suggestions = parameter.getSuggestions(args, locals);
seenParameter = true;
} catch (MissingArgumentException e) {
if (seenParameter) {
return suggestions;
} else {
throw e;
}
}
}
return suggestions;
}
}

View File

@ -19,10 +19,14 @@
package com.sk89q.worldedit.forge; package com.sk89q.worldedit.forge;
import com.google.common.base.Joiner;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.CommandMapping;
import net.minecraft.command.CommandBase; import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommand; import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender; import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayerMP;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Arrays; import java.util.Arrays;
@ -48,6 +52,17 @@ public class CommandWrapper extends CommandBase {
@Override @Override
public void processCommand(ICommandSender var1, String[] var2) {} public void processCommand(ICommandSender var1, String[] var2) {}
@Override
public List addTabCompletionOptions(ICommandSender sender, String[] arguments) {
if (sender instanceof EntityPlayerMP) {
CommandSuggestionEvent event = new CommandSuggestionEvent(ForgeWorldEdit.inst.wrap((EntityPlayerMP) sender), command.getPrimaryAlias() + " " + Joiner.on(" ").join(arguments));
WorldEdit.getInstance().getEventBus().post(event);
return event.getSuggestions();
} else {
return super.addTabCompletionOptions(sender, arguments);
}
}
@Override @Override
public String getCommandUsage(ICommandSender icommandsender) { public String getCommandUsage(ICommandSender icommandsender) {
return "/" + command.getPrimaryAlias() + " " + command.getDescription().getUsage(); return "/" + command.getPrimaryAlias() + " " + command.getDescription().getUsage();
@ -64,8 +79,7 @@ public class CommandWrapper extends CommandBase {
} }
@Override @Override
public int compareTo(@Nullable public int compareTo(@Nullable Object o) {
Object o) {
if (o == null) { if (o == null) {
return 0; return 0;
} else if (o instanceof ICommand) { } else if (o instanceof ICommand) {