some bindings

This commit is contained in:
Jesse Boyd
2019-07-22 16:02:51 +10:00
parent f5c202af6d
commit 07283af614
37 changed files with 1080 additions and 2239 deletions

View File

@ -80,6 +80,8 @@ import java.util.Locale;
import java.util.Map;
import javax.annotation.Nullable;
import javax.script.ScriptException;
import org.mozilla.javascript.NativeJavaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -633,14 +635,14 @@ public final class WorldEdit {
* @param args arguments for the script
* @throws WorldEditException
*/
public void runScript(Player player, File f, String[] args) throws WorldEditException {
public Object runScript(Player player, File f, String[] args) throws WorldEditException {
String filename = f.getPath();
int index = filename.lastIndexOf('.');
String ext = filename.substring(index + 1);
if (!ext.equalsIgnoreCase("js")) {
player.printError("Only .js scripts are currently supported");
return;
return null;
}
String script;
@ -653,7 +655,7 @@ public final class WorldEdit {
if (file == null) {
player.printError("Script does not exist: " + filename);
return;
return null;
}
} else {
file = new FileInputStream(f);
@ -666,7 +668,7 @@ public final class WorldEdit {
script = new String(data, 0, data.length, StandardCharsets.UTF_8);
} catch (IOException e) {
player.printError("Script read error: " + e.getMessage());
return;
return null;
}
LocalSession session = getSessionManager().get(player);
@ -680,7 +682,7 @@ public final class WorldEdit {
} catch (NoClassDefFoundError ignored) {
player.printError("Failed to find an installed script engine.");
player.printError("Please see https://worldedit.readthedocs.io/en/latest/usage/other/craftscripts/");
return;
return null;
}
engine.setTimeLimit(getConfiguration().scriptTimeout);
@ -691,7 +693,11 @@ public final class WorldEdit {
vars.put("player", player);
try {
engine.evaluate(script, filename, vars);
Object result = engine.evaluate(script, filename, vars);
if (result instanceof NativeJavaObject) {
result = ((NativeJavaObject) result).unwrap();
}
return result;
} catch (ScriptException e) {
player.printError("Failed to execute:");
player.printRaw(e.getMessage());
@ -708,6 +714,7 @@ public final class WorldEdit {
session.remember(editSession);
}
}
return null;
}
/**

View File

@ -30,7 +30,6 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.internal.annotation.Range;
import com.sk89q.worldedit.util.command.parametric.Optional;
import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.Switch;
@ -48,7 +47,7 @@ import java.util.zip.GZIPInputStream;
* Tool commands.
*/
@Command(aliases = {"brush", "br", "/b"}, desc = "Tool commands")
//@Command(aliases = {"brush", "br", "/b"}, desc = "Tool commands")
public class BrushOptionsCommands extends MethodCommands {
public BrushOptionsCommands(WorldEdit we) {

View File

@ -35,24 +35,26 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
@Command(aliases = {"patterns"},
desc = "Help for the various patterns. [More Info](https://git.io/vSPmA)",
descFooter = "Patterns determine what blocks are placed\n" +
" - Use [brackets] for arguments\n" +
" - Use , to OR multiple\n" +
"e.g. #surfacespread[10][#existing],andesite\n" +
"More Info: https://git.io/vSPmA"
)
//@Command(aliases = {"patterns"},
// desc = "Help for the various patterns. [More Info](https://git.io/vSPmA)",
// descFooter = "Patterns determine what blocks are placed\n" +
// " - Use [brackets] for arguments\n" +
// " - Use , to OR multiple\n" +
// "e.g. #surfacespread[10][#existing],andesite\n" +
// "More Info: https://git.io/vSPmA"
//)
public class PatternCommands extends MethodCommands {
private final WorldEdit worldEdit;
public PatternCommands(WorldEdit worldEdit) {
super(worldEdit);
this.worldEdit = worldEdit;
}
@Command(
name = "#existing",
aliases = {"#*", "*", ".*"},
desc = "Use the block that is already there",
usage = "[properties]"
descFooter = "[properties]"
)
public Pattern existing(Extent extent, @Arg(name = "properties", desc = "String", def = "") String properties) { // TODO FIXME , @Arg(name = "properties", desc = "String", def = "") String properties
if (properties == null) return new ExistingPattern(extent);
@ -73,7 +75,7 @@ public class PatternCommands extends MethodCommands {
name = "#simplex",
desc = "Use simplex noise to randomize blocks. Tutorial: https://imgur.com/a/rwVAE"
)
public Pattern simplex(@Arg() double scale, Pattern other) {
public Pattern simplex(@Arg(desc = "scale factor") double scale, Pattern other) {
if (other instanceof RandomPattern) {
scale = (1d / Math.max(1, scale));
RandomCollection<Pattern> collection = ((RandomPattern) other).getCollection();
@ -282,8 +284,7 @@ public class PatternCommands extends MethodCommands {
desc = "Apply a pattern depending on a mask"
)
public Pattern mask(Actor actor, LocalSession session, Mask mask, Pattern pass, Pattern fail) {
PatternExtent extent = new PatternExtent(pass);
return new MaskedPattern(mask, extent, fail);
return new MaskedPattern(mask, pass, fail);
}
@Command(

View File

@ -81,111 +81,20 @@ public class ScriptingCommands {
)
@CommandPermissions("fawe.setupdispatcher")
public void setupdispatcher(Player player, LocalSession session, final InjectedValueAccess args) throws WorldEditException {
PlatformCommandManager.getInstance().setupDispatcher();
}
public static <T> T runScript(Player player, File f, String[] args) throws WorldEditException {
return runScript(player, f, args, null);
}
public static <T> T runScript(Actor actor, File f, String[] args, @Nullable Function<String, String> processor) throws WorldEditException {
String filename = f.getPath();
int index = filename.lastIndexOf(".");
String ext = filename.substring(index + 1, filename.length());
if (!ext.equalsIgnoreCase("js")) {
actor.printError("Only .js scripts are currently supported");
return null;
}
String script;
try {
InputStream file;
if (!f.exists()) {
file = WorldEdit.class.getResourceAsStream("craftscripts/" + filename);
if (file == null) {
actor.printError("Script does not exist: " + filename);
return null;
}
} else {
file = new FileInputStream(f);
}
DataInputStream in = new DataInputStream(file);
byte[] data = new byte[in.available()];
in.readFully(data);
in.close();
script = new String(data, 0, data.length, StandardCharsets.UTF_8);
} catch (IOException e) {
actor.printError("Script read error: " + e.getMessage());
return null;
}
if (processor != null) {
script = processor.apply(script);
}
WorldEdit worldEdit = WorldEdit.getInstance();
LocalSession session = worldEdit.getSessionManager().get(actor);
CraftScriptEngine engine = null;
Object result = null;
try {
engine = new RhinoCraftScriptEngine();
} catch (NoClassDefFoundError e) {
actor.printError("Failed to find an installed script engine.");
actor.printError("Download: https://github.com/downloads/mozilla/rhino/rhino1_7R4.zip");
actor.printError("Extract: `js.jar` to `plugins` or `mods` directory`");
actor.printError("More info: https://github.com/boy0001/CraftScripts/");
return null;
}
engine.setTimeLimit(worldEdit.getConfiguration().scriptTimeout);
Player player = actor instanceof Player ? (Player) actor : null;
CraftScriptContext scriptContext = new CraftScriptContext(worldEdit, WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.USER_COMMANDS),
WorldEdit.getInstance().getConfiguration(), session, player, args);
Map<String, Object> vars = new HashMap<>();
vars.put("argv", args);
vars.put("context", scriptContext);
vars.put("actor", actor);
vars.put("player", player);
try {
result = engine.evaluate(script, filename, vars);
} catch (ScriptException e) {
e.printStackTrace();
actor.printError("Failed to execute:");
actor.printRaw(e.getMessage());
} catch (NumberFormatException | WorldEditException e) {
throw e;
} catch (Throwable e) {
actor.printError("Failed to execute (see console):");
actor.printRaw(e.getClass().getCanonicalName());
e.printStackTrace();
}
if (result instanceof NativeJavaObject) {
return (T) ((NativeJavaObject) result).unwrap();
}
return (T) result;
PlatformCommandManager.getInstance().registerAllCommands();
}
@Command(
name = "cs",
desc = "Execute a CraftScript"
name = "cs",
desc = "Execute a CraftScript"
)
@CommandPermissions("worldedit.scripting.execute")
@Logging(ALL)
public void execute(Player player, LocalSession session, InjectedValueAccess args) throws WorldEditException {
final String[] scriptArgs = args.getSlice(1);
final String filename = args.getString(0);
public void execute(Player player, LocalSession session,
@Arg(desc = "Filename of the CraftScript to load")
String filename,
@Arg(desc = "Arguments to the CraftScript", def = "", variable = true)
List<String> args) throws WorldEditException {
if (!player.hasPermission("worldedit.scripting.execute." + filename)) {
BBC.SCRIPTING_NO_PERM.send(player);
return;
@ -195,27 +104,20 @@ public class ScriptingCommands {
File dir = worldEdit.getWorkingDirectoryFile(worldEdit.getConfiguration().scriptsDir);
File f = worldEdit.getSafeOpenFile(player, dir, filename, "js", "js");
try {
new RhinoCraftScriptEngine();
} catch (NoClassDefFoundError e) {
player.printError("Failed to find an installed script engine.");
player.printError("Download: https://github.com/downloads/mozilla/rhino/rhino1_7R4.zip");
player.printError("Extract: `js.jar` to `plugins` or `mods` directory`");
player.printError("More info: https://github.com/boy0001/CraftScripts/");
return;
}
runScript(LocationMaskedPlayerWrapper.unwrap(player), f, scriptArgs);
worldEdit.runScript(player, f, Stream.concat(Stream.of(filename), args.stream())
.toArray(String[]::new));
}
@Command(
name = ".s",
desc = "Execute last CraftScript"
name = ".s",
desc = "Execute last CraftScript"
)
@CommandPermissions("worldedit.scripting.execute")
@Logging(ALL)
public void executeLast(Player player, LocalSession session,
@Arg(desc = "Arguments to the CraftScript", def = "", variable = true)
List<String> args) throws WorldEditException {
List<String> args) throws WorldEditException {
String lastScript = session.getLastScript();
@ -233,6 +135,6 @@ public class ScriptingCommands {
File f = worldEdit.getSafeOpenFile(player, dir, lastScript, "js", "js");
worldEdit.runScript(player, f, Stream.concat(Stream.of(lastScript), args.stream())
.toArray(String[]::new));
.toArray(String[]::new));
}
}

View File

@ -46,7 +46,7 @@ import java.util.List;
* Snapshot commands.
*/
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
@Command(aliases = {"snapshot", "snap"}, desc = "List, load and view information related to snapshots")
//@Command(aliases = {"snapshot", "snap"}, desc = "List, load and view information related to snapshots")
public class SnapshotCommands {
private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
@ -205,7 +205,7 @@ public class SnapshotCommands {
if (snapshot == null) {
player.printError("Couldn't find a snapshot before "
+ dateFormat.withZone(session.getTimeZone().toZoneId()).format(date) + ".");
+ dateFormat.withZone(session.getTimeZone()).format(date) + ".");
} else {
session.setSnapshot(snapshot);
BBC.SNAPSHOT_SET.send(player, snapshot.getName());
@ -235,7 +235,7 @@ public class SnapshotCommands {
Snapshot snapshot = config.snapshotRepo.getSnapshotAfter(date, player.getWorld().getName());
if (snapshot == null) {
player.printError("Couldn't find a snapshot after "
+ dateFormat.withZone(session.getTimeZone().toZoneId()).format(date) + ".");
+ dateFormat.withZone(session.getTimeZone()).format(date) + ".");
} else {
session.setSnapshot(snapshot);
BBC.SNAPSHOT_SET.send(player, snapshot.getName());

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.command;
import com.boydti.fawe.config.BBC;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.inject.InjectedValueAccess;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.LocalConfiguration;
@ -32,7 +33,7 @@ import com.sk89q.worldedit.command.tool.RecursivePickaxe;
import com.sk89q.worldedit.command.tool.SinglePickaxe;
import com.sk89q.worldedit.entity.Player;
@Command(aliases = {"superpickaxe", "pickaxe", "sp"}, desc = "Super-pickaxe commands: [More Info](https://goo.gl/aBtGHo)")
//@Command(aliases = {"superpickaxe", "pickaxe", "sp"}, desc = "Super-pickaxe commands: [More Info](https://goo.gl/aBtGHo)")
public class SuperPickaxeCommands {
private final WorldEdit we;
@ -56,10 +57,11 @@ public class SuperPickaxeCommands {
desc = "Enable the area super pickaxe pickaxe mode"
)
@CommandPermissions("worldedit.superpickaxe.area")
public void area(Player player, LocalSession session, InjectedValueAccess args) throws WorldEditException {
public void area(Player player, LocalSession session,
@Arg(desc = "The range of the area pickaxe")
int range) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
int range = args.getInteger(0);
if (range > config.maxSuperPickaxeSize) {
BBC.TOOL_RANGE_ERROR.send(player, config.maxSuperPickaxeSize);
@ -77,10 +79,11 @@ public class SuperPickaxeCommands {
desc = "Enable the recursive super pickaxe pickaxe mode"
)
@CommandPermissions("worldedit.superpickaxe.recursive")
public void recursive(Player player, LocalSession session, InjectedValueAccess args) throws WorldEditException {
public void recursive(Player player, LocalSession session,
@Arg(desc = "The range of the recursive pickaxe")
double range) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
double range = args.getDouble(0);
if (range > config.maxSuperPickaxeSize) {
BBC.TOOL_RANGE_ERROR.send(player, config.maxSuperPickaxeSize);

View File

@ -22,55 +22,29 @@ package com.sk89q.worldedit.extension.platform;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.command.AnvilCommands;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.task.ThrowableSupplier;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.reflect.TypeToken;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.ApplyBrushCommands;
import com.sk89q.worldedit.command.BiomeCommands;
//import com.sk89q.worldedit.command.BiomeCommandsRegistration;
import com.sk89q.worldedit.command.BrushCommands;
import com.sk89q.worldedit.command.ChunkCommands;
//import com.sk89q.worldedit.command.ChunkCommandsRegistration;
import com.sk89q.worldedit.command.ClipboardCommands;
//import com.sk89q.worldedit.command.ClipboardCommandsRegistration;
import com.sk89q.worldedit.command.ExpandCommands;
import com.sk89q.worldedit.command.GeneralCommands;
//import com.sk89q.worldedit.command.GeneralCommandsRegistration;
import com.sk89q.worldedit.command.GenerationCommands;
import com.sk89q.worldedit.command.HistoryCommands;
//import com.sk89q.worldedit.command.HistoryCommandsRegistration;
import com.sk89q.worldedit.command.NavigationCommands;
//import com.sk89q.worldedit.command.NavigationCommandsRegistration;
import com.sk89q.worldedit.command.PaintBrushCommands;
import com.sk89q.worldedit.command.RegionCommands;
import com.sk89q.worldedit.command.SchematicCommands;
//import com.sk89q.worldedit.command.SchematicCommandsRegistration;
import com.sk89q.worldedit.command.ScriptingCommands;
import com.sk89q.worldedit.command.SelectionCommands;
import com.sk89q.worldedit.command.SnapshotCommands;
//import com.sk89q.worldedit.command.SnapshotCommandsRegistration;
import com.sk89q.worldedit.command.SnapshotUtilCommands;
import com.sk89q.worldedit.command.SuperPickaxeCommands;
//import com.sk89q.worldedit.command.SuperPickaxeCommandsRegistration;
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.WorldEditCommandsRegistration;
import com.sk89q.worldedit.command.argument.Arguments;
import com.sk89q.worldedit.command.argument.BooleanConverter;
@ -84,9 +58,7 @@ import com.sk89q.worldedit.command.argument.RegionFactoryConverter;
import com.sk89q.worldedit.command.argument.RegistryConverter;
import com.sk89q.worldedit.command.argument.VectorConverter;
import com.sk89q.worldedit.command.argument.ZonedDateTimeConverter;
import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandQueued;
import com.sk89q.worldedit.command.util.CommandQueuedCondition;
import com.sk89q.worldedit.command.util.PermissionCondition;
import com.sk89q.worldedit.command.util.SubCommandPermissionCondition;
@ -94,15 +66,17 @@ import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.extension.platform.binding.AnnotatedBindings;
import com.sk89q.worldedit.extension.platform.binding.CommandBindings;
import com.sk89q.worldedit.extension.platform.binding.ConsumeBindings;
import com.sk89q.worldedit.extension.platform.binding.ProvideBindings;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.annotation.Selection;
import com.sk89q.worldedit.internal.command.CommandArgParser;
import com.sk89q.worldedit.internal.command.CommandLoggingHandler;
import com.sk89q.worldedit.internal.command.CommandRegistrationHandler;
import com.sk89q.worldedit.internal.command.exception.ExceptionConverter;
import com.sk89q.worldedit.internal.command.exception.WorldEditExceptionConverter;
import com.sk89q.worldedit.internal.util.Substring;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.scripting.CommandScriptLoader;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.auth.AuthorizationException;
@ -152,7 +126,6 @@ import org.enginehub.piston.part.SubCommandPart;
import org.enginehub.piston.suggestion.Suggestion;
import org.enginehub.piston.util.HelpGenerator;
import org.enginehub.piston.util.ValueProvider;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -246,32 +219,16 @@ public final class PlatformCommandManager {
}
private void registerAlwaysInjectedValues() {
globalInjectedValues.injectValue(Key.of(Region.class, Selection.class),
context -> {
LocalSession localSession = context.injectedValue(Key.of(LocalSession.class))
.orElseThrow(() -> new IllegalStateException("No LocalSession"));
return context.injectedValue(Key.of(Player.class))
.map(player -> {
try {
return localSession.getSelection(player.getWorld());
} catch (IncompleteRegionException e) {
exceptionConverter.convert(e);
throw new AssertionError("Should have thrown a new exception.");
}
});
});
globalInjectedValues.injectValue(Key.of(EditSession.class),
context -> {
LocalSession localSession = context.injectedValue(Key.of(LocalSession.class))
.orElseThrow(() -> new IllegalStateException("No LocalSession"));
return context.injectedValue(Key.of(Player.class))
.map(player -> {
EditSession editSession = localSession.createEditSession(player);
editSession.enableStandardMode();
return editSession;
});
});
globalInjectedValues.injectValue(Key.of(InjectedValueAccess.class), context -> Optional.of(context));
register(new AnnotatedBindings(worldEdit));
register(new CommandBindings(worldEdit));
register(new ConsumeBindings(worldEdit));
register(new ProvideBindings(worldEdit));
register(new ProvideBindings(worldEdit));
}
public void register(Object classWithMethods) {
// TODO NOT IMPLEMENTED - register the following using a custom processor / annotations
}
private <CI> void registerSubCommands(String name, List<String> aliases, String desc,
@ -306,7 +263,7 @@ public final class PlatformCommandManager {
});
}
private void registerAllCommands() {
public void registerAllCommands() {
if (Settings.IMP.ENABLED_COMPONENTS.COMMANDS) {
// TODO NOT IMPLEMENTED dunno why these have issues generating
// registerSubCommands(

View File

@ -0,0 +1,49 @@
package com.sk89q.worldedit.extension.platform.binding;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.internal.annotation.Validate;
import java.lang.annotation.Annotation;
public class AnnotatedBindings extends Bindings {
private final WorldEdit worldEdit;
public AnnotatedBindings(WorldEdit worldEdit) {
this.worldEdit = worldEdit;
}
@Validate()
public String getText(String argument, Validate modifier) {
return validate(argument, modifier);
}
/**
* Validate a string value using relevant modifiers.
*
* @param string the string
* @param modifiers the list of modifiers to scan
* @throws InputParseException on a validation error
*/
private static String validate(String string, Annotation... modifiers)
{
if (string != null) {
for (Annotation modifier : modifiers) {
if (modifier instanceof Validate) {
Validate validate = (Validate) modifier;
if (!validate.value().isEmpty()) {
if (!string.matches(validate.value())) {
throw new InputParseException(
String.format(
"The given text doesn't match the right format (technically speaking, the 'format' is %s)",
validate.value()));
}
}
}
}
}
return string;
}
}

View File

@ -0,0 +1,4 @@
package com.sk89q.worldedit.extension.platform.binding;
public class Bindings {
}

View File

@ -0,0 +1,11 @@
package com.sk89q.worldedit.extension.platform.binding;
import com.sk89q.worldedit.WorldEdit;
public class CommandBindings extends Bindings {
private final WorldEdit worldEdit;
public CommandBindings(WorldEdit worldEdit) {
this.worldEdit = worldEdit;
}
}

View File

@ -0,0 +1,13 @@
package com.sk89q.worldedit.extension.platform.binding;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.internal.annotation.Validate;
public class ConsumeBindings extends Bindings {
private final WorldEdit worldEdit;
public ConsumeBindings(WorldEdit worldEdit) {
this.worldEdit = worldEdit;
}
}

View File

@ -0,0 +1,394 @@
package com.sk89q.worldedit.extension.platform.binding;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.object.extent.NullExtent;
import com.boydti.fawe.object.extent.ResettableExtent;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.annotation.Range;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector2;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
import java.lang.annotation.Annotation;
import java.util.Locale;
public class PrimitiveBindings extends Bindings {
/*
Parsers
*/
public Expression getExpression(String argument) throws ExpressionException {
try {
return new Expression(Double.parseDouble(argument));
} catch (NumberFormatException e1) {
try {
Expression expression = Expression.compile(argument);
expression.optimize();
return expression;
} catch (EvaluationException e) {
throw new InputParseException(String.format(
"Expected '%s' to be a valid number (or a valid mathematical expression)", argument));
} catch (ExpressionException e) {
throw new InputParseException(String.format(
"Expected '%s' to be a number or valid math expression (error: %s)", argument, e.getMessage()));
}
}
}
/**
* Gets an {@link com.sk89q.worldedit.extent.Extent} from a {@link ArgumentStack}.
*
* @param context the context
* @return an extent
* @throws InputParseException on other error
*/
public ResettableExtent getResettableExtent(Actor actor, String argument) throws InputParseException {
if (argument.equalsIgnoreCase("#null")) {
return new NullExtent();
}
DefaultTransformParser parser = Fawe.get().getTransformParser();
ParserContext parserContext = new ParserContext();
if (actor instanceof Entity) {
Extent extent = ((Entity) actor).getExtent();
if (extent instanceof World) {
parserContext.setWorld((World) extent);
}
}
parserContext.setSession(WorldEdit.getInstance().getSessionManager().get(actor));
return parser.parseFromInput(argument, parserContext);
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @return the requested type
* @throws InputParseException on error
*/
public Boolean getBoolean(String argument) {
switch (argument.toLowerCase(Locale.ROOT)) {
case "":
return null;
case "true":
case "yes":
case "on":
case "y":
case "1":
case "t":
return true;
case "false":
case "no":
case "off":
case "f":
case "n":
case "0":
return false;
default:
throw new InputParseException("Invalid boolean " + argument);
}
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @return the requested type
* @throws InputParseException on error
*/
public Vector3 getVector3(String argument) {
String radiusString = argument;
String[] radii = radiusString.split(",");
final double radiusX, radiusY, radiusZ;
switch (radii.length) {
case 1:
radiusX = radiusY = radiusZ = Math.max(1, PrimitiveBindings.parseNumericInput(radii[0]));
break;
case 3:
radiusX = Math.max(1, PrimitiveBindings.parseNumericInput(radii[0]));
radiusY = Math.max(1, PrimitiveBindings.parseNumericInput(radii[1]));
radiusZ = Math.max(1, PrimitiveBindings.parseNumericInput(radii[2]));
break;
default:
throw new InputParseException("You must either specify 1 or 3 radius values.");
}
return Vector3.at(radiusX, radiusY, radiusZ);
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @return the requested type
* @throws InputParseException on error
*/
public Vector2 getVector2(String argument) {
String radiusString = argument;
String[] radii = radiusString.split(",");
final double radiusX, radiusZ;
switch (radii.length) {
case 1:
radiusX = radiusZ = Math.max(1, PrimitiveBindings.parseNumericInput(radii[0]));
break;
case 2:
radiusX = Math.max(1, PrimitiveBindings.parseNumericInput(radii[0]));
radiusZ = Math.max(1, PrimitiveBindings.parseNumericInput(radii[1]));
break;
default:
throw new InputParseException("You must either specify 1 or 2 radius values.");
}
return Vector2.at(radiusX, radiusZ);
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @return the requested type
* @throws InputParseException on error
*/
public BlockVector3 getBlockVector3(String argument) {
String radiusString = argument;
String[] radii = radiusString.split(",");
final double radiusX, radiusY, radiusZ;
switch (radii.length) {
case 1:
radiusX = radiusY = radiusZ = Math.max(1, PrimitiveBindings.parseNumericInput(radii[0]));
break;
case 3:
radiusX = Math.max(1, PrimitiveBindings.parseNumericInput(radii[0]));
radiusY = Math.max(1, PrimitiveBindings.parseNumericInput(radii[1]));
radiusZ = Math.max(1, PrimitiveBindings.parseNumericInput(radii[2]));
break;
default:
throw new InputParseException("You must either specify 1 or 3 radius values.");
}
return BlockVector3.at(radiusX, radiusY, radiusZ);
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @return the requested type
* @throws InputParseException on error
*/
public BlockVector2 getBlockVector2(String argument) {
String radiusString = argument;
String[] radii = radiusString.split(",");
final double radiusX, radiusZ;
switch (radii.length) {
case 1:
radiusX = radiusZ = Math.max(1, PrimitiveBindings.parseNumericInput(radii[0]));
break;
case 2:
radiusX = Math.max(1, PrimitiveBindings.parseNumericInput(radii[0]));
radiusZ = Math.max(1, PrimitiveBindings.parseNumericInput(radii[1]));
break;
default:
throw new InputParseException("You must either specify 1 or 2 radius values.");
}
return BlockVector2.at(radiusX, radiusZ);
}
/*
*/
public Long getLong(String argument, Annotation... modifiers) {
try {
Long v = Long.parseLong(argument);
validate(v, modifiers);
return v;
} catch (NumberFormatException ignore) {
return null;
}
}
private static void validate(long number, Annotation... modifiers) {
for (Annotation modifier : modifiers) {
if (modifier instanceof Range) {
Range range = (Range) modifier;
if (number < range.min()) {
throw new InputParseException(
String.format(
"A valid value is greater than or equal to %s " +
"(you entered %s)", range.min(), number));
} else if (number > range.max()) {
throw new InputParseException(
String.format(
"A valid value is less than or equal to %s " +
"(you entered %s)", range.max(), number));
}
}
}
}
/**
* Try to parse numeric input as either a number or a mathematical expression.
*
* @param input input
* @return a number
* @throws InputParseException thrown on parse error
*/
public static
@Nullable
Double parseNumericInput(@Nullable String input) {
if (input == null) {
return null;
}
try {
return Double.parseDouble(input);
} catch (NumberFormatException e1) {
try {
Expression expression = Expression.compile(input);
return expression.evaluate();
} catch (EvaluationException e) {
throw new InputParseException(String.format(
"Expected '%s' to be a valid number (or a valid mathematical expression)", input));
} catch (ExpressionException e) {
throw new InputParseException(String.format(
"Expected '%s' to be a number or valid math expression (error: %s)", input, e.getMessage()));
}
}
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @param modifiers a list of modifiers
* @return the requested type
* @throws InputParseException on error
*/
public Integer getInteger(String argument, Annotation[] modifiers) {
Double v = parseNumericInput(argument);
if (v != null) {
int intValue = v.intValue();
validate(intValue, modifiers);
return intValue;
} else {
return null;
}
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @param modifiers a list of modifiers
* @return the requested type
* @throws InputParseException on error
*/
public Short getShort(String argument, Annotation[] modifiers) {
Integer v = getInteger(argument, modifiers);
if (v != null) {
return v.shortValue();
}
return null;
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @param modifiers a list of modifiers
* @return the requested type
* @throws InputParseException on error
*/
public Double getDouble(String argument, Annotation[] modifiers) {
Double v = parseNumericInput(argument);
if (v != null) {
validate(v, modifiers);
return v;
} else {
return null;
}
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @param modifiers a list of modifiers
* @return the requested type
* @throws InputParseException on error
*/
public Float getFloat(String argument, Annotation[] modifiers) {
Double v = getDouble(argument, modifiers);
if (v != null) {
return v.floatValue();
}
return null;
}
/**
* Validate a number value using relevant modifiers.
*
* @param number the number
* @param modifiers the list of modifiers to scan
* @throws InputParseException on a validation error
*/
private static void validate(double number, Annotation[] modifiers)
{
for (Annotation modifier : modifiers) {
if (modifier instanceof Range) {
Range range = (Range) modifier;
if (number < range.min()) {
throw new InputParseException(
String.format("A valid value is greater than or equal to %s (you entered %s)", range.min(), number));
} else if (number > range.max()) {
throw new InputParseException(
String.format("A valid value is less than or equal to %s (you entered %s)", range.max(), number));
}
}
}
}
/**
* Validate a number value using relevant modifiers.
*
* @param number the number
* @param modifiers the list of modifiers to scan
* @throws InputParseException on a validation error
*/
private static void validate(int number, Annotation[] modifiers)
{
for (Annotation modifier : modifiers) {
if (modifier instanceof Range) {
Range range = (Range) modifier;
if (number < range.min()) {
throw new InputParseException(
String.format(
"A valid value is greater than or equal to %s (you entered %s)", range.min(), number));
} else if (number > range.max()) {
throw new InputParseException(
String.format(
"A valid value is less than or equal to %s (you entered %s)", range.max(), number));
}
}
}
}
}

View File

@ -0,0 +1,231 @@
package com.sk89q.worldedit.extension.platform.binding;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.TextureUtil;
import com.boydti.fawe.util.image.ImageUtil;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.UnknownDirectionException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player;
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.extension.platform.Capability;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.annotation.Selection;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.biome.Biomes;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.InjectedValueStore;
import org.enginehub.piston.inject.Key;
import org.enginehub.piston.util.ValueProvider;
import java.awt.image.BufferedImage;
import java.lang.annotation.Annotation;
import java.net.URI;
import java.util.Collection;
import java.util.Optional;
public class ProvideBindings extends Bindings {
private final WorldEdit worldEdit;
public ProvideBindings(WorldEdit worldEdit) {
this.worldEdit = worldEdit;
}
/*
Provided
*/
public Player getPlayer(Actor actor) {
if (actor.isPlayer()) {
return (Player) actor;
}
throw new InputParseException("This command must be used with a player.");
}
public LocalSession getLocalSession(Player player) {
return worldEdit.getSessionManager().get(player);
}
public EditSession editSession(LocalSession localSession, Player player) {
EditSession editSession = localSession.createEditSession(player);
editSession.enableStandardMode();
return editSession;
}
@Selection
public Region selection(LocalSession localSession, Player player) {
return localSession.getSelection(player.getWorld());
}
public TextureUtil getTexture(LocalSession session) {
return session.getTextureUtil();
}
public class ImageUri {
public final URI uri;
private BufferedImage image;
ImageUri(URI uri) {
this.uri = uri;
}
public BufferedImage load() {
if (image != null) {
return image;
}
return image = ImageUtil.load(uri);
}
}
public Extent getExtent(Actor actor, InjectedValueAccess access, InjectedValueStore store) {
Optional<EditSession> editSessionOpt = access.injectedValue(Key.of(EditSession.class));
if (editSessionOpt.isPresent()) {
return editSessionOpt.get();
}
Extent extent = Request.request().getExtent();
if (extent != null) {
return extent;
}
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
Player plr = getPlayer(actor);
EditSession editSession = editSession(getLocalSession(plr), plr);
store.injectValue(Key.of(EditSession.class), ValueProvider.constant(editSession));
return editSession;
}
/**
* Gets an {@link com.boydti.fawe.object.FawePlayer} from a {@link ArgumentStack}.
*
* @param context the context
* @return a FawePlayer
* @throws ParameterException on other error
*/
public FawePlayer getFawePlayer(Actor actor) throws InputParseException {
return FawePlayer.wrap(actor);
}
/*
Parsed
*/
public ImageUri getImage(String argument) {
return new ImageUri(ImageUtil.getImageURI(argument));
}
public BlockType blockType(Actor actor, String argument) {
return blockState(actor, argument).getBlockType();
}
public BlockStateHolder blockStateHolder(Actor actor, String argument) {
return blockState(actor, argument);
}
public BlockState blockState(Actor actor, String argument) {
return baseBlock(actor, argument).toBlockState();
}
public BaseBlock baseBlock(Actor actor, String argument) {
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(worldEdit.getSessionManager().get(actor));
try {
return worldEdit.getBlockFactory().parseFromInput(argument, parserContext);
} catch (NoMatchException e) {
throw new InputParseException(e.getMessage());
}
}
/**
* Get a direction from the player.
*
* @param context the context
* @param direction the direction annotation
* @return a pattern
* @throws ParameterException on error
* @throws UnknownDirectionException on an unknown direction
*/
@Direction
public BlockVector3 getDirection(Player player, Direction direction, String argument) throws UnknownDirectionException {
if (direction.includeDiagonals()) {
return worldEdit.getDiagonalDirection(player, argument);
} else {
return worldEdit.getDirection(player, argument);
}
}
/**
* Gets an {@link TreeType} from a {@link ArgumentStack}.
*
* @param context the context
* @return a pattern
* @throws ParameterException on error
* @throws WorldEditException on error
*/
public TreeGenerator.TreeType getTreeType(String argument) throws WorldEditException {
if (argument != null) {
TreeGenerator.TreeType type = TreeGenerator.lookup(argument);
if (type != null) {
return type;
} else {
throw new InputParseException(
String.format("Can't recognize tree type '%s' -- choose from: %s", argument,
TreeGenerator.TreeType.getPrimaryAliases()));
}
} else {
return TreeGenerator.TreeType.TREE;
}
}
/**
* Gets an {@link BiomeType} from a {@link ArgumentStack}.
*
* @param context the context
* @return a pattern
* @throws ParameterException on error
* @throws WorldEditException on error
*/
public BiomeType getBiomeType(String argument) throws WorldEditException {
if (argument != null) {
if (MathMan.isInteger(argument)) return BiomeTypes.getLegacy(Integer.parseInt(argument));
BiomeRegistry biomeRegistry = WorldEdit.getInstance().getPlatformManager()
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
Collection<BiomeType> knownBiomes = BiomeType.REGISTRY.values();
BiomeType biome = Biomes.findBiomeByName(knownBiomes, argument, biomeRegistry);
if (biome != null) {
return biome;
} else {
throw new InputParseException(
String.format("Can't recognize biome type '%s' -- use /biomelist to list available types", argument));
}
} else {
throw new InputParseException(
"This command takes a 'default' biome if one is not set, except there is no particular " +
"biome that should be 'default', so the command should not be taking a default biome");
}
}
}

View File

@ -31,7 +31,7 @@ import java.lang.annotation.Target;
* Annotates a {@link BlockVector3} parameter to inject a direction.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@Target({ElementType.PARAMETER, ElementType.METHOD})
@InjectAnnotation
public @interface Direction {

View File

@ -30,7 +30,7 @@ import java.lang.annotation.Target;
* Indicates that this value should come from the current selection.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@Target({ElementType.PARAMETER, ElementType.METHOD})
@InjectAnnotation
public @interface Selection {
}

View File

@ -31,7 +31,7 @@ import java.util.regex.Pattern;
* @see PrimitiveBindings where this validation is used
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@Target({ElementType.PARAMETER, ElementType.METHOD})
public @interface Validate {
/**
@ -40,6 +40,6 @@ public @interface Validate {
* @see Pattern regular expression class
* @return the pattern
*/
String regex() default "";
String value() default "";
}

View File

@ -1,379 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.internal.command;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.UnknownDirectionException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player;
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.extension.platform.Capability;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.util.command.parametric.ArgumentStack;
import com.sk89q.worldedit.util.command.parametric.BindingBehavior;
import com.sk89q.worldedit.util.command.parametric.BindingMatch;
import com.sk89q.worldedit.util.command.parametric.ParameterException;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.biome.Biomes;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import java.util.Collection;
/**
* Binds standard WorldEdit classes such as {@link Player} and {@link LocalSession}.
*/
public class WorldEditBinding {
private final WorldEdit worldEdit;
/**
* Create a new instance.
*
* @param worldEdit the WorldEdit instance to bind to
*/
public WorldEditBinding(WorldEdit worldEdit) {
this.worldEdit = worldEdit;
}
/**
* Gets a selection from a {@link ArgumentStack}.
*
* @param context the context
* @return a selection
* @throws IncompleteRegionException if no selection is available
* @throws ParameterException on other error
*/
@BindingMatch(
type = Region.class,
behavior = BindingBehavior.PROVIDES)
public Object getSelection(ArgumentStack context) throws IncompleteRegionException, ParameterException {
Player sender = getPlayer(context);
LocalSession session = worldEdit.getSessionManager().get(sender);
return session.getSelection(sender.getWorld());
}
/**
* Gets an {@link EditSession} from a {@link ArgumentStack}.
*
* @param context the context
* @return an edit session
* @throws ParameterException on other error
*/
@BindingMatch(type = EditSession.class,
behavior = BindingBehavior.PROVIDES)
public EditSession getEditSession(ArgumentStack context) throws ParameterException {
Player sender = getPlayer(context);
LocalSession session = worldEdit.getSessionManager().get(sender);
EditSession editSession = session.createEditSession(sender);
editSession.enableStandardMode();
context.getContext().getLocals().put(EditSession.class, editSession);
session.tellVersion(sender);
return editSession;
}
/**
* Gets an {@link LocalSession} from a {@link ArgumentStack}.
*
* @param context the context
* @return a local session
* @throws ParameterException on error
*/
@BindingMatch(type = LocalSession.class,
behavior = BindingBehavior.PROVIDES)
public LocalSession getLocalSession(ArgumentStack context) throws ParameterException {
Player sender = getPlayer(context);
return worldEdit.getSessionManager().get(sender);
}
/**
* Gets an {@link Actor} from a {@link ArgumentStack}.
*
* @param context the context
* @return a local player
* @throws ParameterException on error
*/
@BindingMatch(type = Actor.class,
behavior = BindingBehavior.PROVIDES)
public Actor getActor(ArgumentStack context) throws ParameterException {
Actor sender = context.getContext().getLocals().get(Actor.class);
if (sender == null) {
throw new ParameterException("Missing 'Actor'");
} else {
return sender;
}
}
/**
* Gets an {@link Player} from a {@link ArgumentStack}.
*
* @param context the context
* @return a local player
* @throws ParameterException on error
*/
@BindingMatch(type = Player.class,
behavior = BindingBehavior.PROVIDES)
public Player getPlayer(ArgumentStack context) throws ParameterException {
Actor sender = context.getContext().getLocals().get(Actor.class);
if (sender == null) {
throw new ParameterException("No player to get a session for");
} else if (sender instanceof Player) {
return (Player) sender;
} else {
throw new ParameterException("Caller is not a player");
}
}
/**
* Gets an {@link BaseBlock} from a {@link ArgumentStack}.
*
* @param context the context
* @return a pattern
* @throws ParameterException on error
* @throws WorldEditException on error
*/
@BindingMatch(type = BlockStateHolder.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public BlockStateHolder getBlockStateHolder(ArgumentStack context) throws ParameterException, WorldEditException {
Actor actor = context.getContext().getLocals().get(Actor.class);
ParserContext parserContext = new ParserContext();
parserContext.setActor(context.getContext().getLocals().get(Actor.class));
if (actor instanceof Entity) {
Extent extent = ((Entity) actor).getExtent();
if (extent instanceof World) {
parserContext.setWorld((World) extent);
}
}
parserContext.setSession(worldEdit.getSessionManager().get(actor));
try {
return worldEdit.getBlockFactory().parseFromInput(context.next(), parserContext);
} catch (NoMatchException e) {
throw new ParameterException(e.getMessage(), e);
}
}
@BindingMatch(type = BlockState.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public BlockState getBlockState(ArgumentStack context) throws ParameterException, WorldEditException {
BlockStateHolder result = getBlockStateHolder(context);
return result instanceof BlockState ? (BlockState) result : result.toImmutableState();
}
@BindingMatch(type = {BaseBlock.class, BlockState.class, BlockStateHolder.class},
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public BaseBlock getBaseBlock(ArgumentStack context) throws ParameterException, WorldEditException {
return getBlockState(context).toBaseBlock();
}
/**
* Gets an {@link BaseBlock} from a {@link ArgumentStack}.
*
* @param context the context
* @return a block type
* @throws ParameterException on error
* @throws WorldEditException on error
*/
@BindingMatch(type = BlockType.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public BlockType getBlockType(ArgumentStack context) throws ParameterException, WorldEditException {
Actor actor = context.getContext().getLocals().get(Actor.class);
ParserContext parserContext = new ParserContext();
parserContext.setActor(context.getContext().getLocals().get(Actor.class));
if (actor instanceof Entity) {
Extent extent = ((Entity) actor).getExtent();
if (extent instanceof World) {
parserContext.setWorld((World) extent);
}
}
parserContext.setSession(worldEdit.getSessionManager().get(actor));
try {
return worldEdit.getBlockFactory().parseFromInput(context.next(), parserContext).getBlockType();
} catch (NoMatchException e) {
throw new ParameterException(e.getMessage(), e);
}
}
/**
* Gets an {@link Pattern} from a {@link ArgumentStack}.
*
* @param context the context
* @return a pattern
* @throws ParameterException on error
* @throws WorldEditException on error
*/
@BindingMatch(type = Pattern.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public Pattern getPattern(ArgumentStack context) throws ParameterException, WorldEditException {
Actor actor = context.getContext().getLocals().get(Actor.class);
ParserContext parserContext = new ParserContext();
parserContext.setActor(context.getContext().getLocals().get(Actor.class));
if (actor instanceof Entity) {
Extent extent = ((Entity) actor).getExtent();
if (extent instanceof World) {
parserContext.setWorld((World) extent);
}
}
parserContext.setSession(worldEdit.getSessionManager().get(actor));
try {
return worldEdit.getPatternFactory().parseFromInput(context.next(), parserContext);
} catch (NoMatchException e) {
throw new ParameterException(e.getMessage(), e);
}
}
/**
* Gets an {@link Mask} from a {@link ArgumentStack}.
*
* @param context the context
* @return a pattern
* @throws ParameterException on error
* @throws WorldEditException on error
*/
@BindingMatch(type = Mask.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public Mask getMask(ArgumentStack context) throws ParameterException, WorldEditException {
Actor actor = context.getContext().getLocals().get(Actor.class);
ParserContext parserContext = new ParserContext();
parserContext.setActor(context.getContext().getLocals().get(Actor.class));
if (actor instanceof Entity) {
Extent extent = ((Entity) actor).getExtent();
if (extent instanceof World) {
parserContext.setWorld((World) extent);
}
}
parserContext.setSession(worldEdit.getSessionManager().get(actor));
try {
return worldEdit.getMaskFactory().parseFromInput(context.next(), parserContext);
} catch (NoMatchException e) {
throw new ParameterException(e.getMessage(), e);
}
}
/**
* Get a direction from the player.
*
* @param context the context
* @param direction the direction annotation
* @return a pattern
* @throws ParameterException on error
* @throws UnknownDirectionException on an unknown direction
*/
@BindingMatch(classifier = Direction.class,
type = BlockVector3.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public BlockVector3 getDirection(ArgumentStack context, Direction direction)
throws ParameterException, UnknownDirectionException {
Player sender = getPlayer(context);
if (direction.includeDiagonals()) {
return worldEdit.getDiagonalDirection(sender, context.next());
} else {
return worldEdit.getDirection(sender, context.next());
}
}
/**
* Gets an {@link TreeType} from a {@link ArgumentStack}.
*
* @param context the context
* @return a pattern
* @throws ParameterException on error
* @throws WorldEditException on error
*/
@BindingMatch(type = TreeType.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public TreeType getTreeType(ArgumentStack context) throws ParameterException, WorldEditException {
String input = context.next();
if (input != null) {
TreeType type = TreeGenerator.lookup(input);
if (type != null) {
return type;
} else {
throw new ParameterException(
String.format("Can't recognize tree type '%s' -- choose from: %s", input,
TreeType.getPrimaryAliases()));
}
} else {
return TreeType.TREE;
}
}
/**
* Gets an {@link BiomeType} from a {@link ArgumentStack}.
*
* @param context the context
* @return a pattern
* @throws ParameterException on error
* @throws WorldEditException on error
*/
@BindingMatch(type = BiomeType.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public BiomeType getBiomeType(ArgumentStack context) throws ParameterException, WorldEditException {
String input = context.next();
if (input != null) {
if (MathMan.isInteger(input)) return BiomeTypes.get(Integer.parseInt(input));
BiomeRegistry biomeRegistry = WorldEdit.getInstance().getPlatformManager()
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
Collection<BiomeType> knownBiomes = BiomeType.REGISTRY.values();
BiomeType biome = Biomes.findBiomeByName(knownBiomes, input, biomeRegistry);
if (biome != null) {
return biome;
} else {
throw new ParameterException(
String.format("Can't recognize biome type '%s' -- use /biomelist to list available types", input));
}
} else {
throw new ParameterException(
"This command takes a 'default' biome if one is not set, except there is no particular " +
"biome that should be 'default', so the command should not be taking a default biome");
}
}
}

View File

@ -146,12 +146,6 @@ public final class DocumentationPrinter {
stream.print(" || ");
if (cmd.flags() != null && !cmd.flags().isEmpty()) {
stream.print(cmd.flags());
}
stream.print(" || ");
if (cmd.desc() != null && !cmd.desc().isEmpty()) {
stream.print(cmd.desc());
}