Add some experimental brush commands.

/br set <shape> <radius> <pattern>
/br deform <shape> <expression>
/br scatter <shape> <density> <generator>
/br apply <shape> <generator>

<shape> can be: cuboid, cyl[inder], sphere

<density> is 0-100

<generator> can be:
forest|tree <type>
item <item>[:<data>] (ONLY WORKS ON FORGE)

Examples:

/br deform cuboid 5 y-=0.2
/br scatter sphere 5 100 minecraft:dye:15
This commit is contained in:
sk89q 2015-10-26 23:14:30 -07:00
parent b19cd9bec4
commit 935de4c93d
59 changed files with 2239 additions and 99 deletions

View File

@ -49,7 +49,7 @@ class BukkitCommandInspector implements CommandInspector {
public String getShortText(Command command) {
CommandMapping mapping = dispatcher.get(command.getName());
if (mapping != null) {
return mapping.getDescription().getShortDescription();
return mapping.getDescription().getDescription();
} else {
logger.warning("BukkitCommandInspector doesn't know how about the command '" + command + "'");
return "Help text not available";

View File

@ -130,7 +130,7 @@ public class BukkitServerInterface extends ServerInterface implements MultiUserP
String[] permissionsArray = new String[permissions.size()];
permissions.toArray(permissionsArray);
toRegister.add(new CommandInfo(description.getUsage(), description.getShortDescription(), command.getAllAliases(), inspector, permissionsArray));
toRegister.add(new CommandInfo(description.getUsage(), description.getDescription(), command.getAllAliases(), inspector, permissionsArray));
}
dynamicCommands.register(toRegister);

View File

@ -66,17 +66,32 @@ public class CommandContext {
/**
* Parse the given array of arguments.
*
*
* <p>Empty arguments are removed from the list of arguments.</p>
*
*
* @param args an array with arguments
* @param valueFlags a set containing all value flags (pass null to disable value flag parsing)
* @param allowHangingFlag true if hanging flags are allowed
* @param locals the locals, null to create empty one
* @throws CommandException thrown on a parsing error
*/
public CommandContext(String[] args, Set<Character> valueFlags,
boolean allowHangingFlag, CommandLocals locals) throws CommandException {
public CommandContext(String[] args, Set<Character> valueFlags, boolean allowHangingFlag, CommandLocals locals) throws CommandException {
this(args, valueFlags, allowHangingFlag, locals, true);
}
/**
* Parse the given array of arguments.
*
* <p>Empty arguments are removed from the list of arguments.</p>
*
* @param args an array with arguments
* @param valueFlags a set containing all value flags (pass null to disable value flag parsing)
* @param allowHangingFlag true if hanging flags are allowed
* @param locals the locals, null to create empty one
* @param parseFlags where to parse flags
* @throws CommandException thrown on a parsing error
*/
public CommandContext(String[] args, Set<Character> valueFlags, boolean allowHangingFlag, CommandLocals locals, boolean parseFlags) throws CommandException {
if (valueFlags == null) {
valueFlags = Collections.emptySet();
}
@ -140,57 +155,65 @@ public class CommandContext {
this.originalArgIndices = new ArrayList<Integer>(argIndexList.size());
this.parsedArgs = new ArrayList<String>(argList.size());
for (int nextArg = 0; nextArg < argList.size(); ) {
// Fetch argument
String arg = argList.get(nextArg++);
suggestionContext = SuggestionContext.hangingValue();
if (parseFlags) {
for (int nextArg = 0; nextArg < argList.size(); ) {
// Fetch argument
String arg = argList.get(nextArg++);
suggestionContext = SuggestionContext.hangingValue();
// Not a flag?
if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z\\?]+$")) {
if (!isHanging) {
suggestionContext = SuggestionContext.lastValue();
}
originalArgIndices.add(argIndexList.get(nextArg - 1));
parsedArgs.add(arg);
continue;
}
// Handle flag parsing terminator --
if (arg.equals("--")) {
while (nextArg < argList.size()) {
originalArgIndices.add(argIndexList.get(nextArg));
parsedArgs.add(argList.get(nextArg++));
}
break;
}
// Go through the flag characters
for (int i = 1; i < arg.length(); ++i) {
char flagName = arg.charAt(i);
if (valueFlags.contains(flagName)) {
if (this.valueFlags.containsKey(flagName)) {
throw new CommandException("Value flag '" + flagName + "' already given");
}
if (nextArg >= argList.size()) {
if (allowHangingFlag) {
suggestionContext = SuggestionContext.flag(flagName);
break;
} else {
throw new CommandException("No value specified for the '-" + flagName + "' flag.");
}
}
// If it is a value flag, read another argument and add it
this.valueFlags.put(flagName, argList.get(nextArg++));
// Not a flag?
if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z\\?]+$")) {
if (!isHanging) {
suggestionContext = SuggestionContext.flag(flagName);
suggestionContext = SuggestionContext.lastValue();
}
} else {
booleanFlags.add(flagName);
originalArgIndices.add(argIndexList.get(nextArg - 1));
parsedArgs.add(arg);
continue;
}
// Handle flag parsing terminator --
if (arg.equals("--")) {
while (nextArg < argList.size()) {
originalArgIndices.add(argIndexList.get(nextArg));
parsedArgs.add(argList.get(nextArg++));
}
break;
}
// Go through the flag characters
for (int i = 1; i < arg.length(); ++i) {
char flagName = arg.charAt(i);
if (valueFlags.contains(flagName)) {
if (this.valueFlags.containsKey(flagName)) {
throw new CommandException("Value flag '" + flagName + "' already given");
}
if (nextArg >= argList.size()) {
if (allowHangingFlag) {
suggestionContext = SuggestionContext.flag(flagName);
break;
} else {
throw new CommandException("No value specified for the '-" + flagName + "' flag.");
}
}
// If it is a value flag, read another argument and add it
this.valueFlags.put(flagName, argList.get(nextArg++));
if (!isHanging) {
suggestionContext = SuggestionContext.flag(flagName);
}
} else {
booleanFlags.add(flagName);
}
}
}
} else {
for (int i = 0; i < argList.size(); i++) {
String arg = argList.get(i);
originalArgIndices.add(argIndexList.get(i));
parsedArgs.add(arg);
}
}

View File

@ -613,7 +613,6 @@ public class LocalSession {
* @return the tool, or {@code null}
* @throws InvalidToolBindException if the item can't be bound to that item
*/
@Nullable
public BrushTool getBrushTool(int item) throws InvalidToolBindException {
Tool tool = getTool(item);

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit;
import com.sk89q.worldedit.CuboidClipboard.FlipDirection;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
@ -28,6 +29,7 @@ import com.sk89q.worldedit.event.platform.BlockInteractEvent;
import com.sk89q.worldedit.event.platform.InputType;
import com.sk89q.worldedit.event.platform.PlayerInputEvent;
import com.sk89q.worldedit.extension.factory.BlockFactory;
import com.sk89q.worldedit.extension.factory.ItemFactory;
import com.sk89q.worldedit.extension.factory.MaskFactory;
import com.sk89q.worldedit.extension.factory.PatternFactory;
import com.sk89q.worldedit.extension.input.ParserContext;
@ -95,6 +97,7 @@ public class WorldEdit {
private final SessionManager sessions = new SessionManager(this);
private final BlockFactory blockFactory = new BlockFactory(this);
private final ItemFactory itemFactory = new ItemFactory(this);
private final MaskFactory maskFactory = new MaskFactory(this);
private final PatternFactory patternFactory = new PatternFactory(this);
@ -152,6 +155,16 @@ public class WorldEdit {
return blockFactory;
}
/**
* Get the item factory from which new {@link BaseItem}s can be
* constructed.
*
* @return the item factory
*/
public ItemFactory getItemFactory() {
return itemFactory;
}
/**
* Get the mask factory from which new {@link com.sk89q.worldedit.function.mask.Mask}s
* can be constructed.

View File

@ -22,7 +22,12 @@ package com.sk89q.worldedit.command;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
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.blocks.BlockID;
import com.sk89q.worldedit.command.tool.BrushTool;

View File

@ -658,7 +658,7 @@ public class UtilityCommands {
builder.append(" ");
}
builder.append(mapping.getPrimaryAlias());
box.appendCommand(builder.toString(), mapping.getDescription().getShortDescription());
box.appendCommand(builder.toString(), mapping.getDescription().getDescription());
}
}

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.command.composition;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.minecraft.util.commands.WrappedCommandException;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.function.factory.Deform;
import com.sk89q.worldedit.function.factory.Deform.Mode;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
public class DeformCommand extends CommandExecutor<Deform> {
@Override
public Deform call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
String expression = args.next();
boolean rawCoords = args.containsFlag('r');
boolean offset = args.containsFlag('o');
Deform deform = new Deform(expression);
if (rawCoords) {
deform.setMode(Mode.RAW_COORD);
} else if (offset) {
deform.setMode(Mode.OFFSET);
Player player = (Player) locals.get(Actor.class);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(locals.get(Actor.class));
try {
deform.setOffset(session.getPlacementPosition(player));
} catch (IncompleteRegionException e) {
throw new WrappedCommandException(e);
}
} else {
deform.setMode(Mode.UNIT_CUBE);
}
return deform;
}
}

View File

@ -0,0 +1,61 @@
/*
* 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.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.tool.BrushTool;
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
import static com.google.common.base.Preconditions.checkNotNull;
public class FillBrushCommand<T> extends CommandExecutor<T> {
private final CommandExecutor<? extends T> delegate;
public FillBrushCommand(CommandExecutor<? extends T> delegate) {
checkNotNull(delegate, "delegate");
this.delegate = delegate;
}
@Override
public T call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
Pattern pattern = new PatternCommand().call(args, locals, parentCommands);
Player player = (Player) locals.get(Actor.class);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
try {
BrushTool tool = session.getBrushTool(player.getItemInHand());
tool.setFill(pattern);
} catch (InvalidToolBindException e) {
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e);
}
return delegate.call(args, locals, parentCommands);
}
}

View File

@ -0,0 +1,23 @@
/*
* 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;
public class ForestCommand {
}

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.command.composition;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
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.world.World;
public class ItemCommand extends CommandExecutor<BaseItem> {
@Override
public BaseItem call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
Actor actor = locals.get(Actor.class);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
ParserContext parserContext = new ParserContext();
parserContext.setActor(actor);
if (actor instanceof Entity) {
Extent extent = ((Entity) actor).getExtent();
if (extent instanceof World) {
parserContext.setWorld((World) extent);
}
}
parserContext.setSession(session);
try {
return WorldEdit.getInstance().getItemFactory().parseFromInput(args.next(), parserContext);
} catch (NoMatchException e) {
throw new CommandException(e.getMessage(), e);
} catch (InputParseException e) {
throw new CommandException(e.getMessage(), e);
}
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.google.common.base.Function;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction;
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.world.World;
import javax.annotation.Nullable;
public class ItemUseCommand extends CommandExecutor<Function<EditContext, RegionFunction>> {
@Override
public Function<EditContext, RegionFunction> call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
BaseItem item = new ItemCommand().call(args, locals, parentCommands);
return new ItemUseFactory(item);
}
private static final class ItemUseFactory implements Function<EditContext, RegionFunction> {
private final BaseItem item;
private ItemUseFactory(BaseItem item) {
this.item = item;
}
@Nullable
@Override
public RegionFunction apply(EditContext input) {
World world = ((EditSession) input.getDestination()).getWorld();
return new ItemUseFunction(world, item);
}
@Override
public String toString() {
return "application of the item " + item.getType() + ":" + item.getData();
}
}
private static final class ItemUseFunction implements RegionFunction {
private final World world;
private final BaseItem item;
private ItemUseFunction(World world, BaseItem item) {
this.world = world;
this.item = item;
}
@Override
public boolean apply(Vector position) throws WorldEditException {
return world.useItem(position, item, Direction.UP);
}
}
}

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.command.composition;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.Extent;
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.world.World;
public class PatternCommand extends CommandExecutor<Pattern> {
@Override
public Pattern call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
Actor actor = locals.get(Actor.class);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
ParserContext parserContext = new ParserContext();
parserContext.setActor(actor);
if (actor instanceof Entity) {
Extent extent = ((Entity) actor).getExtent();
if (extent instanceof World) {
parserContext.setWorld((World) extent);
}
}
parserContext.setSession(session);
try {
return WorldEdit.getInstance().getPatternFactory().parseFromInput(args.next(), parserContext);
} catch (NoMatchException e) {
throw new CommandException(e.getMessage(), e);
} catch (InputParseException e) {
throw new CommandException(e.getMessage(), e);
}
}
}

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.command.composition;
import com.google.common.base.Function;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
public class PointGeneratorCommand extends CommandExecutor<Function<EditContext, ? extends RegionFunction>> {
@Override
public Function<EditContext, ? extends RegionFunction> call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
String type = args.next();
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);
}
}
}

View File

@ -0,0 +1,48 @@
/*
* 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

@ -0,0 +1,35 @@
/*
* 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.function.factory.RegionReplace;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
public class RegionReplaceCommand extends CommandExecutor<RegionReplace> {
@Override
public RegionReplace call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
return new RegionReplace();
}
}

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.composition;
import com.google.common.base.Function;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.factory.Scatter;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
public class ScatterCommand extends CommandExecutor<Scatter> {
@Override
public Scatter call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
double density = args.nextDouble() / 100.0;
Function<EditContext, ? extends RegionFunction> function = new PointGeneratorCommand().call(args, locals, parentCommands);
return new Scatter(function, density);
}
}

View File

@ -0,0 +1,114 @@
/*
* 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.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxBrushRadiusException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.tool.BrushTool;
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
import com.sk89q.worldedit.command.tool.brush.OperationFactoryBrush;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.function.factory.OperationFactory;
import com.sk89q.worldedit.regions.factory.RegionFactory;
import com.sk89q.worldedit.util.command.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 java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
public class ShapedBrushCommand extends CommandExecutor<Object> {
private final CommandExecutor<? extends OperationFactory> delegate;
private final String permission;
public ShapedBrushCommand(CommandExecutor<? extends OperationFactory> delegate, String permission) {
checkNotNull(delegate, "delegate");
this.permission = permission;
this.delegate = delegate;
}
@Override
public Object call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
if (!testPermission(locals)) {
throw new CommandPermissionsException();
}
RegionFactory regionFactory = new RegionFactoryCommand().call(args, locals, parentCommands);
int radius = args.nextInt();
OperationFactory factory = delegate.call(args, locals, parentCommands);
args.requireAllConsumed();
Player player = (Player) locals.get(Actor.class);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
try {
WorldEdit.getInstance().checkMaxBrushRadius(radius);
BrushTool tool = session.getBrushTool(player.getItemInHand());
tool.setSize(radius);
tool.setBrush(new OperationFactoryBrush(factory, regionFactory), permission);
} catch (MaxBrushRadiusException e) {
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e);
} catch (InvalidToolBindException e) {
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e);
}
player.print("Set brush to " + factory);
return true;
}
@Override
public Description getDescription() {
List<Parameter> parameters = Lists.newArrayList();
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
public boolean testPermission(CommandLocals locals) {
Actor sender = locals.get(Actor.class);
if (sender == null) {
throw new RuntimeException("Uh oh! No 'Actor' specified so that we can check permissions");
} else {
return sender.hasPermission(permission);
}
}
}

View File

@ -0,0 +1,67 @@
/*
* 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.google.common.base.Function;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
import javax.annotation.Nullable;
import java.util.Arrays;
public class TreeGeneratorCommand extends CommandExecutor<Function<EditContext, ForestGenerator>> {
@Override
public Function<EditContext, ForestGenerator> call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
String input = args.next();
TreeType type = TreeGenerator.lookup(input);
if (type != null) {
return new GeneratorFactory(type);
} else {
throw new CommandException(String.format("Can't recognize tree type '%s' -- choose from: %s", input, Arrays.toString(TreeType.values())));
}
}
private static class GeneratorFactory implements Function<EditContext, ForestGenerator> {
private final TreeType type;
private GeneratorFactory(TreeType type) {
this.type = type;
}
@Nullable
@Override
public ForestGenerator apply(EditContext input) {
return new ForestGenerator((EditSession) input.getDestination(), new TreeGenerator(type));
}
@Override
public String toString() {
return "tree of type " + type;
}
}
}

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.tool.brush;
import com.google.common.base.Function;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.command.composition.PointGeneratorCommand;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.factory.RegionApply;
import com.sk89q.worldedit.util.command.CommandExecutor;
import com.sk89q.worldedit.util.command.argument.CommandArgs;
public class ApplyCommand extends CommandExecutor<RegionApply> {
@Override
public RegionApply call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException {
Function<EditContext, ? extends RegionFunction> function = new PointGeneratorCommand().call(args, locals, parentCommands);
return new RegionApply(function);
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.tool.brush;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.factory.OperationFactory;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.regions.factory.RegionFactory;
public class OperationFactoryBrush implements Brush {
private final OperationFactory operationFactory;
private final RegionFactory regionFactory;
public OperationFactoryBrush(OperationFactory operationFactory, RegionFactory regionFactory) {
this.operationFactory = operationFactory;
this.regionFactory = regionFactory;
}
@Override
public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
EditContext context = new EditContext();
context.setDestination(editSession);
context.setRegion(regionFactory.createCenteredAt(position, size));
context.setFill(pattern);
Operation operation = operationFactory.createOperation(context);
Operations.completeLegacy(operation);
}
}

View File

@ -0,0 +1,80 @@
/*
* 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.extension.factory;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.internal.registry.InputParser;
public class DefaultItemParser extends InputParser<BaseItem> {
protected DefaultItemParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public BaseItem parseFromInput(String input, ParserContext context) throws InputParseException {
String[] tokens = input.split(":", 3);
BaseItem item;
short meta = 0;
try {
int id = Integer.parseInt(tokens[0]);
// Parse metadata
if (tokens.length == 2) {
try {
meta = Short.parseShort(tokens[1]);
} catch (NumberFormatException ignored) {
throw new InputParseException("Expected '" + tokens[1] + "' to be a metadata value but it's not a number");
}
}
item = context.requireWorld().getWorldData().getItemRegistry().createFromId(id);
} catch (NumberFormatException e) {
if (input.length() < 2) {
throw new InputParseException("'" + input + "' isn't a known item name format");
}
String name = tokens[0] + ":" + tokens[1];
// Parse metadata
if (tokens.length == 3) {
try {
meta = Short.parseShort(tokens[2]);
} catch (NumberFormatException ignored) {
throw new InputParseException("Expected '" + tokens[2] + "' to be a metadata value but it's not a number");
}
}
item = context.requireWorld().getWorldData().getItemRegistry().createFromId(name);
}
if (item == null) {
throw new InputParseException("'" + input + "' did not match any item");
} else {
item.setData(meta);
return item;
}
}
}

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.extension.factory;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.internal.registry.AbstractFactory;
public class ItemFactory extends AbstractFactory<BaseItem> {
/**
* Create a new instance.
*
* @param worldEdit the WorldEdit instance.
*/
public ItemFactory(WorldEdit worldEdit) {
super(worldEdit);
parsers.add(new DefaultItemParser(worldEdit));
}
}

View File

@ -28,9 +28,34 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.*;
import com.sk89q.worldedit.command.BiomeCommands;
import com.sk89q.worldedit.command.BrushCommands;
import com.sk89q.worldedit.command.ChunkCommands;
import com.sk89q.worldedit.command.ClipboardCommands;
import com.sk89q.worldedit.command.GeneralCommands;
import com.sk89q.worldedit.command.GenerationCommands;
import com.sk89q.worldedit.command.HistoryCommands;
import com.sk89q.worldedit.command.NavigationCommands;
import com.sk89q.worldedit.command.RegionCommands;
import com.sk89q.worldedit.command.SchematicCommands;
import com.sk89q.worldedit.command.ScriptingCommands;
import com.sk89q.worldedit.command.SelectionCommands;
import com.sk89q.worldedit.command.SnapshotCommands;
import com.sk89q.worldedit.command.SnapshotUtilCommands;
import com.sk89q.worldedit.command.SuperPickaxeCommands;
import com.sk89q.worldedit.command.ToolCommands;
import com.sk89q.worldedit.command.ToolUtilCommands;
import com.sk89q.worldedit.command.UtilityCommands;
import com.sk89q.worldedit.command.WorldEditCommands;
import com.sk89q.worldedit.command.composition.DeformCommand;
import com.sk89q.worldedit.command.composition.FillBrushCommand;
import com.sk89q.worldedit.command.composition.RegionReplaceCommand;
import com.sk89q.worldedit.command.composition.ScatterCommand;
import com.sk89q.worldedit.command.composition.ShapedBrushCommand;
import com.sk89q.worldedit.command.tool.brush.ApplyCommand;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.function.factory.OperationFactory;
import com.sk89q.worldedit.internal.command.ActorAuthorizer;
import com.sk89q.worldedit.internal.command.CommandLoggingHandler;
import com.sk89q.worldedit.internal.command.UserCommandCompleter;
@ -40,6 +65,7 @@ import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.InvalidUsageException;
import com.sk89q.worldedit.util.command.fluent.CommandGraph;
import com.sk89q.worldedit.util.command.parametric.ExceptionConverter;
import com.sk89q.worldedit.util.command.parametric.LegacyCommandsHandler;
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
import com.sk89q.worldedit.util.eventbus.Subscribe;
@ -67,12 +93,13 @@ public final class CommandManager {
public static final Pattern COMMAND_CLEAN_PATTERN = Pattern.compile("^[/]+");
private static final Logger log = Logger.getLogger(CommandManager.class.getCanonicalName());
private static final Logger commandLog = Logger.getLogger(CommandManager.class.getCanonicalName() + ".CommandLog");
private static final java.util.regex.Pattern numberFormatExceptionPattern = java.util.regex.Pattern.compile("^For input string: \"(.*)\"$");
private static final Pattern numberFormatExceptionPattern = Pattern.compile("^For input string: \"(.*)\"$");
private final WorldEdit worldEdit;
private final PlatformManager platformManager;
private final Dispatcher dispatcher;
private final DynamicStreamHandler dynamicHandler = new DynamicStreamHandler();
private final ExceptionConverter exceptionConverter;
/**
* Create a new instance.
@ -84,6 +111,7 @@ public final class CommandManager {
checkNotNull(platformManager);
this.worldEdit = worldEdit;
this.platformManager = platformManager;
this.exceptionConverter = new WorldEditExceptionConverter(worldEdit);
// Register this instance for command events
worldEdit.getEventBus().register(this);
@ -97,7 +125,7 @@ public final class CommandManager {
builder.setAuthorizer(new ActorAuthorizer());
builder.setDefaultCompleter(new UserCommandCompleter(platformManager));
builder.addBinding(new WorldEditBinding(worldEdit));
builder.addExceptionConverter(new WorldEditExceptionConverter(worldEdit));
builder.addExceptionConverter(exceptionConverter);
builder.addInvokeListener(new LegacyCommandsHandler());
builder.addInvokeListener(new CommandLoggingHandler(worldEdit, commandLog));
@ -133,7 +161,11 @@ public final class CommandManager {
.group("brush", "br")
.describeAs("Brushing commands")
.registerMethods(new BrushCommands(worldEdit))
.parent()
.register(new ShapedBrushCommand(new DeformCommand(), "worldedit.brush.deform"), "deform")
.register(new ShapedBrushCommand(new FillBrushCommand<OperationFactory>(new RegionReplaceCommand()), "worldedit.brush.set"), "set")
.register(new ShapedBrushCommand(new ScatterCommand(), "worldedit.brush.scatter"), "scatter")
.register(new ShapedBrushCommand(new ApplyCommand(), "worldedit.brush.apply"), "apply")
.parent()
.group("superpickaxe", "pickaxe", "sp")
.describeAs("Super-pickaxe commands")
.registerMethods(new SuperPickaxeCommands(worldEdit))
@ -146,6 +178,10 @@ public final class CommandManager {
.getDispatcher();
}
public ExceptionConverter getExceptionConverter() {
return exceptionConverter;
}
void register(Platform platform) {
log.log(Level.FINE, "Registering commands with " + platform.getClass().getCanonicalName());
@ -218,6 +254,7 @@ public final class CommandManager {
CommandLocals locals = new CommandLocals();
locals.put(Actor.class, actor);
locals.put("arguments", event.getArguments());
long start = System.currentTimeMillis();
@ -282,6 +319,7 @@ public final class CommandManager {
try {
CommandLocals locals = new CommandLocals();
locals.put(Actor.class, event.getActor());
locals.put("arguments", event.getArguments());
event.setSuggestions(dispatcher.getSuggestions(event.getArguments(), locals));
} catch (CommandException e) {
event.getActor().printError(e.getMessage());

View File

@ -0,0 +1,62 @@
/*
* 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.function;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.NullExtent;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
public class EditContext {
private Extent destination = new NullExtent();
private Region region = new CuboidRegion(Vector.ZERO, Vector.ZERO);
private Pattern fill = new BlockPattern(new BaseBlock(BlockID.AIR));
public Extent getDestination() {
return destination;
}
public void setDestination(Extent destination) {
this.destination = destination;
}
public Region getRegion() {
return region;
}
public void setRegion(Region region) {
this.region = region;
}
public Pattern getFill() {
return fill;
}
public void setFill(Pattern fill) {
this.fill = fill;
}
}

View File

@ -0,0 +1,144 @@
/*
* 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.function.factory;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.regions.Region;
import static com.google.common.base.Preconditions.checkNotNull;
public class Deform implements OperationFactory {
private String expression;
private Mode mode = Mode.UNIT_CUBE;
private Vector offset = new Vector();
public Deform(String expression) {
checkNotNull(expression, "expression");
this.expression = expression;
}
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
checkNotNull(expression, "expression");
this.expression = expression;
}
public Mode getMode() {
return mode;
}
public void setMode(Mode mode) {
checkNotNull(mode, "mode");
this.mode = mode;
}
public Vector getOffset() {
return offset;
}
public void setOffset(Vector offset) {
checkNotNull(offset, "offset");
this.offset = offset;
}
@Override
public String toString() {
return "deformation of " + expression;
}
@Override
public Operation createOperation(final EditContext context) {
final Vector zero;
Vector unit;
switch (mode) {
case UNIT_CUBE:
final Vector min = context.getRegion().getMinimumPoint();
final Vector max = context.getRegion().getMaximumPoint();
zero = max.add(min).multiply(0.5);
unit = max.subtract(zero);
if (unit.getX() == 0) unit = unit.setX(1.0);
if (unit.getY() == 0) unit = unit.setY(1.0);
if (unit.getZ() == 0) unit = unit.setZ(1.0);
break;
case RAW_COORD:
zero = Vector.ZERO;
unit = Vector.ONE;
break;
case OFFSET:
default:
zero = offset;
unit = Vector.ONE;
}
return new DeformOperation(context.getDestination(), context.getRegion(), zero, unit, expression);
}
private static final class DeformOperation implements Operation {
private final Extent destination;
private final Region region;
private final Vector zero;
private final Vector unit;
private final String expression;
private DeformOperation(Extent destination, Region region, Vector zero, Vector unit, String expression) {
this.destination = destination;
this.region = region;
this.zero = zero;
this.unit = unit;
this.expression = expression;
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
try {
// TODO: Move deformation code
((EditSession) destination).deformRegion(region, zero, unit, expression);
return null;
} catch (ExpressionException e) {
throw new RuntimeException("Failed to execute expression", e); // TODO: Better exception to throw here?
}
}
@Override
public void cancel() {
}
}
public enum Mode {
RAW_COORD,
OFFSET,
UNIT_CUBE
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.function.factory;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.operation.Operation;
public interface OperationFactory {
Operation createOperation(EditContext context);
}

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.function.factory;
import com.google.common.base.Function;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import static com.google.common.base.Preconditions.checkNotNull;
public class RegionApply implements OperationFactory {
private final Function<EditContext, ? extends RegionFunction> regionFunctionFactory;
public RegionApply(Function<EditContext, ? extends RegionFunction> regionFunctionFactory) {
checkNotNull(regionFunctionFactory, "regionFunctionFactory");
this.regionFunctionFactory = regionFunctionFactory;
}
@Override
public Operation createOperation(EditContext context) {
return new RegionVisitor(context.getRegion(), regionFunctionFactory.apply(context));
}
@Override
public String toString() {
return "set " + regionFunctionFactory;
}
}

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.function.factory;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
public class RegionReplace implements OperationFactory {
@Override
public Operation createOperation(EditContext context) {
BlockReplace replace = new BlockReplace(context.getDestination(), context.getFill());
return new RegionVisitor(context.getRegion(), replace);
}
@Override
public String toString() {
return "set blocks";
}
}

View File

@ -0,0 +1,60 @@
/*
* 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.function.factory;
import com.google.common.base.Function;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.NoiseFilter2D;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
import com.sk89q.worldedit.math.noise.RandomNoise;
import com.sk89q.worldedit.regions.Region;
import static com.sk89q.worldedit.regions.Regions.*;
public class Scatter implements OperationFactory {
private final Function<EditContext, ? extends RegionFunction> regionFunctionFactory;
private final double density;
public Scatter(Function<EditContext, ? extends RegionFunction> regionFunctionFactory, double density) {
this.regionFunctionFactory = regionFunctionFactory;
this.density = density;
new NoiseFilter2D(new RandomNoise(), density); // Check validity density argument
}
@Override
public Operation createOperation(EditContext context) {
Region region = context.getRegion();
GroundFunction ground = new GroundFunction(new ExistingBlockMask(context.getDestination()), regionFunctionFactory.apply(context));
LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
return visitor;
}
@Override
public String toString() {
return "scatter " + regionFunctionFactory;
}
}

View File

@ -55,6 +55,10 @@ public class ForestGenerator implements RegionFunction {
if (t == BlockID.GRASS || t == BlockID.DIRT) {
treeGenerator.generate(editSession, position.add(0, 1, 0));
return true;
} else if (t == BlockID.LONG_GRASS || t == BlockID.DEAD_BUSH || t == BlockID.RED_FLOWER || t == BlockID.YELLOW_FLOWER) { // TODO: This list needs to be moved
editSession.setBlock(position, new BaseBlock(0));
treeGenerator.generate(editSession, position);
return true;
} else if (t == BlockID.SNOW) {
editSession.setBlock(position, new BaseBlock(BlockID.AIR));
return false;

View File

@ -0,0 +1,33 @@
/*
* 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.regions.factory;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
public class CuboidRegionFactory implements RegionFactory {
@Override
public Region createCenteredAt(Vector position, double size) {
return CuboidRegion.fromCenter(position, (int) size);
}
}

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.regions.factory;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.regions.CylinderRegion;
import com.sk89q.worldedit.regions.Region;
public class CylinderRegionFactory implements RegionFactory {
private final double height;
public CylinderRegionFactory(double height) {
this.height = height;
}
@Override
public Region createCenteredAt(Vector position, double size) {
return new CylinderRegion(position, new Vector2D(size, size), position.getBlockY() - (int) (height / 2), position.getBlockY() + (int) (height / 2));
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.regions.factory;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.regions.Region;
public interface RegionFactory {
Region createCenteredAt(Vector position, double size);
}

View File

@ -0,0 +1,33 @@
/*
* 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.regions.factory;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.regions.EllipsoidRegion;
import com.sk89q.worldedit.regions.Region;
public class SphereRegionFactory implements RegionFactory {
@Override
public Region createCenteredAt(Vector position, double size) {
return new EllipsoidRegion(position, new Vector(size, size, size));
}
}

View File

@ -39,7 +39,7 @@ public interface CommandCallable extends CommandCompleter {
* @return the called command, or null if there was no command found
* @throws CommandException thrown on a command error
*/
boolean call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException;
Object call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException;
/**
* Get an object describing this command.

View File

@ -0,0 +1,56 @@
/*
* 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;
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 java.util.List;
public abstract class CommandExecutor<T> implements CommandCallable {
@Override
public final T call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException {
CommandArgs args = new CommandArgs.Parser().parse(arguments);
T ret = call(args, locals, parentCommands);
args.requireAllConsumed();
return ret;
}
public abstract T call(CommandArgs args, CommandLocals locals, String[] parentCommands) throws CommandException;
@Override
public Description getDescription() {
return new SimpleDescription();
}
@Override
public boolean testPermission(CommandLocals locals) {
return false;
}
@Override
public List<String> getSuggestions(String arguments, CommandLocals locals) throws CommandException {
return Lists.newArrayList();
}
}

View File

@ -38,7 +38,7 @@ public interface Description {
*
* @return a description, or null if no description is available
*/
String getShortDescription();
String getDescription();
/**
* Get a longer help text about this command.
@ -67,4 +67,4 @@ public interface Description {
*/
List<String> getPermissions();
}
}

View File

@ -63,4 +63,4 @@ public interface Parameter {
*/
public String[] getDefaultValue();
}
}

View File

@ -45,12 +45,13 @@ public class SimpleDescription implements Description {
* @param parameters the list of parameters
* @see #getParameters()
*/
public void setParameters(List<Parameter> parameters) {
public SimpleDescription setParameters(List<Parameter> parameters) {
this.parameters = Collections.unmodifiableList(parameters);
return this;
}
@Override
public String getShortDescription() {
public String getDescription() {
return description;
}
@ -58,10 +59,11 @@ public class SimpleDescription implements Description {
* Set the description of the command.
*
* @param description the description
* @see #getShortDescription()
* @see #getDescription()
*/
public void setDescription(String description) {
public SimpleDescription setDescription(String description) {
this.description = description;
return this;
}
@Override
@ -75,8 +77,9 @@ public class SimpleDescription implements Description {
* @param help the help text
* @see #getHelp()
*/
public void setHelp(String help) {
public SimpleDescription setHelp(String help) {
this.help = help;
return this;
}
@Override
@ -86,11 +89,12 @@ public class SimpleDescription implements Description {
/**
* Set the permissions of this command.
*
*
* @param permissions the permissions
*/
public void setPermissions(List<String> permissions) {
public SimpleDescription setPermissions(List<String> permissions) {
this.permissions = Collections.unmodifiableList(permissions);
return this;
}
/**

View File

@ -102,7 +102,7 @@ public class SimpleDispatcher implements Dispatcher {
}
@Override
public boolean call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException {
public Object call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException {
// We have permission for this command if we have permissions for subcommands
if (!testPermission(locals)) {
throw new CommandPermissionsException();
@ -122,15 +122,13 @@ public class SimpleDispatcher implements Dispatcher {
if (mapping != null) {
try {
mapping.getCallable().call(subArguments, locals, subParents);
return mapping.getCallable().call(subArguments, locals, subParents);
} catch (CommandException e) {
e.prependStack(subCommand);
throw e;
} catch (Throwable t) {
throw new WrappedCommandException(t);
}
return true;
}
}

View File

@ -52,11 +52,12 @@ public class SimpleParameter implements Parameter {
/**
* Set the name of the parameter.
*
*
* @param name the parameter name
*/
public void setName(String name) {
public SimpleParameter setName(String name) {
this.name = name;
return this;
}
@Override
@ -71,13 +72,13 @@ public class SimpleParameter implements Parameter {
/**
* Set the flag used by this parameter.
*
* @param flag the flag, or null if there is no flag
* @param flag the flag, or null if there is no flag
* @param isValue true if the flag is a value flag
*/
public void setFlag(Character flag, boolean isValue) {
public SimpleParameter setFlag(Character flag, boolean isValue) {
this.flag = flag;
this.isValue = isValue;
return this;
}
@Override
@ -87,11 +88,12 @@ public class SimpleParameter implements Parameter {
/**
* Set whether this parameter is optional.
*
*
* @param isOptional true if this parameter is optional
*/
public void setOptional(boolean isOptional) {
public SimpleParameter setOptional(boolean isOptional) {
this.isOptional = isOptional;
return this;
}
@Override
@ -101,11 +103,12 @@ public class SimpleParameter implements Parameter {
/**
* Set the default value.
*
*
* @param defaultValue a default value, or null if none
*/
public void setDefaultValue(String[] defaultValue) {
public SimpleParameter setDefaultValue(String[] defaultValue) {
this.defaultValue = defaultValue;
return this;
}
@Override

View File

@ -0,0 +1,329 @@
/*
* 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 com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class CommandArgs {
private final List<String> arguments;
private final Map<Character, String> flags;
private int position = 0;
private Set<Character> consumedFlags = Sets.newHashSet();
public CommandArgs(List<String> arguments, Map<Character, String> flags) {
this.arguments = arguments;
this.flags = Maps.newHashMap(flags);
}
public boolean hasNext() {
return position < arguments.size();
}
public String next() throws CommandException {
try {
return arguments.get(position++);
} catch (IndexOutOfBoundsException ignored) {
throw new CommandException("Too few arguments specified.");
}
}
public String peek() throws CommandException {
try {
return arguments.get(position);
} catch (IndexOutOfBoundsException ignored) {
throw new CommandException("Too few arguments specified.");
}
}
public String remaining() throws CommandException {
if (hasNext()) {
StringBuilder builder = new StringBuilder();
boolean first = true;
while (hasNext()) {
if (!first) {
builder.append(" ");
}
builder.append(next());
first = false;
}
return builder.toString();
} else {
throw new CommandException("Too few arguments specified.");
}
}
public String peekRemaining() throws CommandException {
if (hasNext()) {
StringBuilder builder = new StringBuilder();
boolean first = true;
while (hasNext()) {
if (!first) {
builder.append(" ");
}
builder.append(next());
first = false;
}
return builder.toString();
} else {
throw new CommandException("Too few arguments specified.");
}
}
public int position() {
return position;
}
public int size() {
return arguments.size();
}
public void markConsumed() {
position = arguments.size();
}
public CommandArgs split() {
return new CommandArgs(getUnusedArguments(), getUnusedFlags());
}
private List<String> getUnusedArguments() {
List<String> args = Lists.newArrayList();
while (position < arguments.size()) {
args.add(arguments.get(position++));
}
return args;
}
private Map<Character, String> getUnusedFlags() {
Map<Character, String> flags = Maps.newHashMap();
for (Entry<Character, String> entry : this.flags.entrySet()) {
if (!consumedFlags.contains(entry.getKey())) {
flags.put(entry.getKey(), entry.getValue());
consumedFlags.add(entry.getKey());
}
}
return flags;
}
public void requireAllConsumed() throws CommandException {
StringBuilder builder = new StringBuilder();
boolean hasUnconsumed = false;
if (flags.size() > consumedFlags.size()) {
hasUnconsumed = true;
for (Entry<Character, String> entry : flags.entrySet()) {
if (!consumedFlags.contains(entry.getKey())) {
builder.append("-").append(entry.getKey()).append(" ");
if (entry.getValue() != null) {
builder.append(entry.getValue()).append(" ");
}
}
}
}
if (hasNext()) {
hasUnconsumed = true;
builder.append(peekRemaining());
}
if (hasUnconsumed) {
throw new CommandException("There were unused arguments: " + builder);
}
}
public int nextInt() throws CommandException {
String next = next();
try {
return Integer.parseInt(next);
} catch (NumberFormatException ignored) {
throw new CommandException("Expected a number, got '" + next + "'");
}
}
public short nextShort() throws CommandException {
String next = next();
try {
return Short.parseShort(next);
} catch (NumberFormatException ignored) {
throw new CommandException("Expected a number, got '" + next + "'");
}
}
public byte nextByte() throws CommandException {
String next = next();
try {
return Byte.parseByte(next);
} catch (NumberFormatException ignored) {
throw new CommandException("Expected a number, got '" + next + "'");
}
}
public double nextDouble() throws CommandException {
String next = next();
try {
return Double.parseDouble(next);
} catch (NumberFormatException ignored) {
throw new CommandException("Expected a number, got '" + next + "'");
}
}
public float nextFloat() throws CommandException {
String next = next();
try {
return Float.parseFloat(next);
} catch (NumberFormatException ignored) {
throw new CommandException("Expected a number, got '" + next + "'");
}
}
public boolean nextBoolean() throws CommandException {
String next = next();
if (next.equalsIgnoreCase("yes") || next.equalsIgnoreCase("true") || next.equalsIgnoreCase("y") || next.equalsIgnoreCase("1")) {
return true;
} else if (next.equalsIgnoreCase("no") || next.equalsIgnoreCase("false") || next.equalsIgnoreCase("n") || next.equalsIgnoreCase("0")) {
return false;
} else {
throw new CommandException("Expected a boolean (yes/no), got '" + next + "'");
}
}
public boolean containsFlag(char c) {
boolean contains = flags.containsKey(c);
if (contains) {
consumedFlags.add(c);
}
return contains;
}
public String getFlag(char c, String fallback) {
boolean contains = flags.containsKey(c);
if (contains) {
consumedFlags.add(c);
String value = flags.get(c);
if (value == null) {
return fallback;
} else {
return value;
}
}
return fallback;
}
public int getIntFlag(char c, int fallback) throws CommandException {
String next = getFlag(c, String.valueOf(fallback));
try {
return Integer.parseInt(next);
} catch (NumberFormatException ignored) {
throw new CommandException("Expected a number for flag '-" + c + "', got '" + next + "'");
}
}
public short getShortFlag(char c, short fallback) throws CommandException {
String next = getFlag(c, String.valueOf(fallback));
try {
return Short.parseShort(next);
} catch (NumberFormatException ignored) {
throw new CommandException("Expected a number for flag '-" + c + "', got '" + next + "'");
}
}
public byte getByteFlag(char c, byte fallback) throws CommandException {
String next = getFlag(c, String.valueOf(fallback));
try {
return Byte.parseByte(next);
} catch (NumberFormatException ignored) {
throw new CommandException("Expected a number for flag '-" + c + "', got '" + next + "'");
}
}
public double getDoubleFlag(char c, double fallback) throws CommandException {
String next = getFlag(c, String.valueOf(fallback));
try {
return Double.parseDouble(next);
} catch (NumberFormatException ignored) {
throw new CommandException("Expected a number for flag '-" + c + "', got '" + next + "'");
}
}
public float getFloatFlag(char c, float fallback) throws CommandException {
String next = getFlag(c, String.valueOf(fallback));
try {
return Float.parseFloat(next);
} catch (NumberFormatException ignored) {
throw new CommandException("Expected a number for flag '-" + c + "', got '" + next + "'");
}
}
public boolean getBooleanFlag(char c, boolean fallback) throws CommandException {
String next = getFlag(c, String.valueOf(fallback));
if (next.equalsIgnoreCase("yes") || next.equalsIgnoreCase("true") || next.equalsIgnoreCase("y") || next.equalsIgnoreCase("1")) {
return true;
} else if (next.equalsIgnoreCase("no") || next.equalsIgnoreCase("false") || next.equalsIgnoreCase("n") || next.equalsIgnoreCase("0")) {
return false;
} else {
throw new CommandException("Expected a boolean (yes/no), got '" + next + "'");
}
}
public static class Parser {
private boolean parseFlags = true;
private Set<Character> valueFlags = Sets.newHashSet();
public boolean isParseFlags() {
return parseFlags;
}
public Parser setParseFlags(boolean parseFlags) {
this.parseFlags = parseFlags;
return this;
}
public Set<Character> getValueFlags() {
return valueFlags;
}
public Parser setValueFlags(Set<Character> valueFlags) {
this.valueFlags = valueFlags;
return this;
}
public CommandArgs parse(String arguments) throws CommandException {
CommandContext context = new CommandContext(CommandContext.split("_ " + arguments), valueFlags, false, null, parseFlags);
List<String> args = Lists.newArrayList();
for (int i = 0; i < context.argsLength(); i++) {
args.add(context.getString(i));
}
Map<Character, String> flags = Maps.newHashMap(context.getValueFlags());
for (Character c : context.getFlags()) {
flags.put(c, null);
}
return new CommandArgs(args, flags);
}
}
}

View File

@ -20,10 +20,10 @@
package com.sk89q.worldedit.util.command.binding;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.worldedit.util.command.parametric.ArgumentStack;
import com.sk89q.worldedit.util.command.parametric.BindingBehavior;
import com.sk89q.worldedit.util.command.parametric.BindingHelper;
import com.sk89q.worldedit.util.command.parametric.BindingMatch;
import com.sk89q.worldedit.util.command.parametric.ArgumentStack;
/**
* Standard bindings that should be available to most configurations.
@ -32,15 +32,15 @@ public final class StandardBindings extends BindingHelper {
/**
* Gets a {@link CommandContext} from a {@link ArgumentStack}.
*
*
* @param context the context
* @return a selection
*/
@BindingMatch(type = CommandContext.class,
behavior = BindingBehavior.PROVIDES)
behavior = BindingBehavior.PROVIDES)
public CommandContext getCommandContext(ArgumentStack context) {
context.markConsumed(); // Consume entire stack
return context.getContext();
}
}
}

View File

@ -67,8 +67,9 @@ public class DispatcherNode {
* @param callable the executor
* @param alias the list of aliases, where the first alias is the primary one
*/
public void register(CommandCallable callable, String... alias) {
dispatcher.registerCommand(callable, alias);
public DispatcherNode register(CommandCallable callable, String... alias) {
dispatcher.registerCommand(callable, alias);;
return this;
}
/**

View File

@ -180,7 +180,7 @@ class ParametricCallable implements CommandCallable {
}
@Override
public boolean call(String stringArguments, CommandLocals locals, String[] parentCommands) throws CommandException {
public Object call(String stringArguments, CommandLocals locals, String[] parentCommands) throws CommandException {
// Test permission
if (!testPermission(locals)) {
throw new CommandPermissionsException();
@ -480,4 +480,4 @@ class ParametricCallable implements CommandCallable {
}
}
}
}

View File

@ -76,7 +76,7 @@ public class CommandUsageBox extends StyledFragment {
for (CommandMapping mapping : list) {
if (locals == null || mapping.getCallable().testPermission(locals)) {
box.appendCommand(prefix + mapping.getPrimaryAlias(), mapping.getDescription().getShortDescription());
box.appendCommand(prefix + mapping.getPrimaryAlias(), mapping.getDescription().getDescription());
}
}
@ -98,8 +98,8 @@ public class CommandUsageBox extends StyledFragment {
if (description.getHelp() != null) {
contents.append(description.getHelp());
} else if (description.getShortDescription() != null) {
contents.append(description.getShortDescription());
} else if (description.getDescription() != null) {
contents.append(description.getDescription());
} else {
contents.append(new Subtle().append("No further help is available."));
}

View File

@ -25,6 +25,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType;
@ -32,6 +33,7 @@ import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import javax.annotation.Nullable;
@ -45,6 +47,11 @@ public abstract class AbstractWorld implements World {
private final PriorityQueue<QueuedEffect> effectQueue = new PriorityQueue<QueuedEffect>();
private int taskId = -1;
@Override
public boolean useItem(Vector position, BaseItem item, Direction face) {
return false;
}
@Override
public final boolean setBlockType(Vector position, int type) {
try {

View File

@ -25,11 +25,13 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.registry.WorldData;
@ -80,6 +82,15 @@ public interface World extends Extent {
*/
Mask createLiquidMask();
/**
* Use the given item on the block at the given location on the given side.
*
* @param item The item
* @param face The face
* @return Whether it succeeded
*/
boolean useItem(Vector position, BaseItem item, Direction face);
/**
* @deprecated Use {@link #getLazyBlock(Vector)}
*/

View File

@ -0,0 +1,46 @@
/*
* 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.world.registry;
import com.sk89q.worldedit.blocks.BaseItem;
import javax.annotation.Nullable;
public interface ItemRegistry {
/**
* Create a new item using its ID.
*
* @param id the id
* @return the item, which may be null if no item exists
*/
@Nullable
BaseItem createFromId(String id);
/**
* Create a new item using its legacy numeric ID.
*
* @param id the id
* @return the item, which may be null if no item exists
*/
@Nullable
BaseItem createFromId(int id);
}

View File

@ -27,6 +27,7 @@ public class LegacyWorldData implements WorldData {
private static final LegacyWorldData INSTANCE = new LegacyWorldData();
private final LegacyBlockRegistry blockRegistry = new LegacyBlockRegistry();
private final NullItemRegistry itemRegistry = new NullItemRegistry();
private final NullEntityRegistry entityRegistry = new NullEntityRegistry();
private final NullBiomeRegistry biomeRegistry = new NullBiomeRegistry();
@ -41,6 +42,11 @@ public class LegacyWorldData implements WorldData {
return blockRegistry;
}
@Override
public ItemRegistry getItemRegistry() {
return itemRegistry;
}
@Override
public EntityRegistry getEntityRegistry() {
return entityRegistry;

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.world.registry;
import com.sk89q.worldedit.blocks.BaseItem;
import javax.annotation.Nullable;
public class NullItemRegistry implements ItemRegistry {
@Nullable
@Override
public BaseItem createFromId(String id) {
return null;
}
@Nullable
@Override
public BaseItem createFromId(int id) {
return null;
}
}

View File

@ -32,6 +32,13 @@ public interface WorldData {
*/
BlockRegistry getBlockRegistry();
/**
* Get the item registry.
*
* @return the item registry
*/
ItemRegistry getItemRegistry();
/**
* Get the entity registry.
*

View File

@ -20,8 +20,10 @@
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.World;
import net.minecraft.util.Vec3;
import net.minecraftforge.common.util.ForgeDirection;
final class ForgeAdapter {
@ -36,4 +38,15 @@ final class ForgeAdapter {
return new Vector(vector.xCoord, vector.yCoord, vector.zCoord);
}
public static int adapt(Direction face) {
switch (face) {
case NORTH: return ForgeDirection.NORTH.ordinal();
case SOUTH: return ForgeDirection.SOUTH.ordinal();
case WEST: return ForgeDirection.WEST.ordinal();
case EAST: return ForgeDirection.EAST.ordinal();
case UP: return ForgeDirection.UP.ordinal();
case DOWN: return ForgeDirection.DOWN.ordinal();
default: return ForgeDirection.UNKNOWN.ordinal();
}
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.forge;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.world.registry.ItemRegistry;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import javax.annotation.Nullable;
public class ForgeItemRegistry implements ItemRegistry {
@Nullable
@Override
public BaseItem createFromId(String id) {
Item item = (Item) Item.itemRegistry.getObject(id);
if (item != null) {
return new BaseItem(Item.getIdFromItem(item), (short) item.getDamage(new ItemStack(item, 1)));
} else {
return null;
}
}
@Nullable
@Override
public BaseItem createFromId(int id) {
Item item = (Item) Item.itemRegistry.getObjectById(id);
if (item != null) {
return new BaseItem(Item.getIdFromItem(item), (short) item.getDamage(new ItemStack(item, 1)));
} else {
return null;
}
}
}

View File

@ -97,6 +97,7 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
@Override
public void reload() {
getConfiguration().load();
}
@Override

View File

@ -26,12 +26,14 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.AbstractWorld;
@ -41,11 +43,14 @@ import net.minecraft.block.Block;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.LongHashMap;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.ChunkProviderServer;
@ -129,6 +134,14 @@ public class ForgeWorld extends AbstractWorld {
return getWorld().getWorldInfo().getWorldName();
}
@Override
public boolean useItem(Vector position, BaseItem item, Direction face) {
Item nativeItem = Item.getItemById(item.getType());
ItemStack stack = new ItemStack(nativeItem, 1, item.getData());
World world = getWorld();
return stack.tryPlaceItemIntoWorld(new WorldEditFakePlayer((WorldServer) world), world, position.getBlockX(), position.getBlockY(), position.getBlockZ(), ForgeAdapter.adapt(face), 0, 0, 0);
}
@Override
public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException {
checkNotNull(position);

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import com.sk89q.worldedit.world.registry.ItemRegistry;
import com.sk89q.worldedit.world.registry.LegacyWorldData;
/**
@ -28,12 +29,12 @@ import com.sk89q.worldedit.world.registry.LegacyWorldData;
class ForgeWorldData extends LegacyWorldData {
private static final ForgeWorldData INSTANCE = new ForgeWorldData();
private final ItemRegistry itemRegistry = new ForgeItemRegistry();
private final BiomeRegistry biomeRegistry = new ForgeBiomeRegistry();
/**
* Create a new instance.
*/
ForgeWorldData() {
@Override
public ItemRegistry getItemRegistry() {
return itemRegistry;
}
@Override

View File

@ -0,0 +1,36 @@
/*
* 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.forge;
import com.mojang.authlib.GameProfile;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.FakePlayer;
import java.util.UUID;
public class WorldEditFakePlayer extends FakePlayer {
private static final GameProfile FAKE_GAME_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]");
public WorldEditFakePlayer(WorldServer world) {
super(world, FAKE_GAME_PROFILE);
}
}