some bindings

This commit is contained in:
Jesse Boyd 2019-07-22 16:02:51 +10:00
parent f5c202af6d
commit 07283af614
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
37 changed files with 1080 additions and 2239 deletions

View File

@ -19,8 +19,8 @@
package com.sk89q.bukkit.util;
import org.enginehub.piston.annotation.Command;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.CommandsManager;
import org.bukkit.command.CommandExecutor;
import org.bukkit.plugin.Plugin;

View File

@ -216,6 +216,7 @@ public class Fawe {
}
public TextureUtil getCachedTextureUtil(boolean randomize, int min, int max) {
// TODO NOT IMPLEMENTED - optimize this by caching the default true/0/100 texture util
TextureUtil tu = getTextureUtil();
try {
tu = min == 0 && max == 100 ? tu : new CleanTextureUtil(tu, min, max);

View File

@ -10,6 +10,7 @@ import com.boydti.fawe.object.collection.IterableThreadLocal;
import com.boydti.fawe.util.MemUtil;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.wrappers.WorldWrapper;
import com.google.common.util.concurrent.Futures;
import com.sk89q.worldedit.world.World;
import java.lang.ref.WeakReference;
@ -24,6 +25,7 @@ import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Supplier;
/**
* Class which handles all the queues {@link IQueueExtent}
@ -136,6 +138,10 @@ public abstract class QueueHandler implements Trimable, Runnable {
}
public <T> Future<T> sync(final Runnable run, final T value) {
if (Fawe.isMainThread()) {
run.run();
return Futures.immediateFuture(value);
}
final FutureTask<T> result = new FutureTask<>(run, value);
syncTasks.add(result);
notifySync();
@ -143,19 +149,36 @@ public abstract class QueueHandler implements Trimable, Runnable {
}
public <T> Future<T> sync(final Runnable run) {
if (Fawe.isMainThread()) {
run.run();
return Futures.immediateCancelledFuture();
}
final FutureTask<T> result = new FutureTask<>(run, null);
syncTasks.add(result);
notifySync();
return result;
}
public <T> Future<T> sync(final Callable<T> call) {
public <T> Future<T> sync(final Callable<T> call) throws Exception {
if (Fawe.isMainThread()) {
return Futures.immediateFuture(call.call());
}
final FutureTask<T> result = new FutureTask<>(call);
syncTasks.add(result);
notifySync();
return result;
}
public <T> Future<T> sync(final Supplier<T> call) {
if (Fawe.isMainThread()) {
return Futures.immediateFuture(call.get());
}
final FutureTask<T> result = new FutureTask<>(call::get);
syncTasks.add(result);
notifySync();
return result;
}
private void notifySync() {
synchronized (syncTasks) {
syncTasks.notifyAll();
@ -163,9 +186,9 @@ public abstract class QueueHandler implements Trimable, Runnable {
}
public <T extends Future<T>> T submit(final IChunk<T> chunk) {
if (MemUtil.isMemoryFree()) {
// if (MemUtil.isMemoryFree()) { TODO NOT IMPLEMENTED - optimize this
// return (T) forkJoinPoolSecondary.submit(chunk);
}
// }
return (T) blockingExecutor.submit(chunk);
}
@ -193,6 +216,10 @@ public abstract class QueueHandler implements Trimable, Runnable {
public abstract IQueueExtent create();
public abstract void startSet(boolean value);
public abstract void endSet(boolean value);
public IQueueExtent getQueue(final World world) {
final IQueueExtent queue = queuePool.get();
queue.init(getOrCreate(world));

View File

@ -1,102 +1,90 @@
package com.boydti.fawe.command;
import com.boydti.fawe.config.Commands;
import com.boydti.fawe.object.brush.visualization.cfi.HeightMapMCAGenerator;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.brush.visualization.cfi.HeightMapMCAGenerator;
import com.boydti.fawe.object.changeset.CFIChangeSet;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.inject.InjectedValueAccess;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.MethodCommands;
import com.sk89q.worldedit.util.command.SimpleDispatcher;
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import org.enginehub.piston.CommandManager;
import org.enginehub.piston.exception.StopExecutionException;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class CFICommand extends MethodCommands {
public class CFICommand extends CommandProcessor<Object, Object> {
private final CFICommands child;
private final SimpleDispatcher dispatcher;
public CFICommand(WorldEdit worldEdit, ParametricBuilder builder) {
super(worldEdit);
this.dispatcher = new SimpleDispatcher();
this.child = new CFICommands(worldEdit, dispatcher);
builder.registerMethodsAsCommands(dispatcher, child);
public CFICommand(CommandManager manager) {
super(manager);
}
@Command(
name = "cfi",
aliases = {"cfi", "createfromimage"},
desc = "Start CreateFromImage"
)
@CommandPermissions("worldedit.anvil.cfi")
public void cfi(FawePlayer fp, InjectedValueAccess context) throws CommandException, IOException {
CFICommands.CFISettings settings = child.getSettings(fp);
@Override
public List<String> preprocess(InjectedValueAccess context, List<String> args) {
FawePlayer fp = context.injectedValue(Key.of(FawePlayer.class)).orElseThrow(() -> new IllegalStateException("No player"));
CFICommands.CFISettings settings = CFICommands.getSettings(fp);
settings.popMessages(fp);
dispatch(fp, settings, context);
args = dispatch(fp, settings, args, context);
HeightMapMCAGenerator gen = settings.getGenerator();
if (gen != null && gen.isModified()) {
try {
gen.update();
CFIChangeSet set = new CFIChangeSet(gen, fp.getUUID());
LocalSession session = fp.getSession();
session.remember(fp.getPlayer(), gen, set, fp.getLimit());
} catch (IOException e) {
throw new StopExecutionException(TextComponent.of(e.getMessage()));
}
}
return args;
}
private void dispatch(FawePlayer fp, CFICommands.CFISettings settings, InjectedValueAccess context) throws CommandException {
@Override
public Object process(InjectedValueAccess context, List<String> args, Object result) {
return result;
}
private List<String> dispatch(FawePlayer fp, CFICommands.CFISettings settings, List<String> args, InjectedValueAccess context) {
if (!settings.hasGenerator()) {
if (context.argsLength() == 0) {
String hmCmd = child.alias() + " ";
if (args.size() == 0) {
String hmCmd = CFICommands.alias() + " ";
if (settings.image == null) {
hmCmd += "image";
} else {
hmCmd =
Commands.getAlias(CFICommands.class, "heightmap") + " " + settings.imageArg;
}
child.msg("What do you want to use as the base?").newline()
CFICommands.msg("What do you want to use as the base?").newline()
.text("[HeightMap]").cmdTip(hmCmd).text(" - A heightmap like ")
.text("[this]").linkTip("http://i.imgur.com/qCd30MR.jpg")
.newline()
.text("[Empty]").cmdTip(child.alias() + " empty")
.text("[Empty]").cmdTip(CFICommands.alias() + " empty")
.text("- An empty map of a specific size")
.send(fp);
} else {
String remaining = context.getJoinedStrings(0);
if (!dispatcher.contains(context.getString(0))) {
switch (context.argsLength()) {
args = new ArrayList<>(args);
switch (args.size()) {
case 1: {
String cmd =
Commands.getAlias(CFICommands.class, "heightmap") + " " + context
.getJoinedStrings(0);
dispatcher.call(cmd, context.getLocals(), new String[0]);
return;
args.add(0, "heightmap");
break;
}
case 2: {
String cmd =
Commands.getAlias(CFICommands.class, "empty") + " " + context
.getJoinedStrings(0);
dispatcher.call(cmd, context.getLocals(), new String[0]);
return;
}
case 2:
String cmd = Commands.getAlias(CFICommands.class, "empty") + " " + context.getJoinedStrings(0);
dispatcher.call(cmd, context.getLocals(), new String[0]);
return;
args.add(0, "empty");
break;
}
}
dispatcher.call(remaining, context.getLocals(), new String[0]);
return args;
}
} else {
if (context.argsLength() == 0) {
settings.setCategory("");
child.mainMenu(fp);
} else {
dispatcher.call(context.getJoinedStrings(0), context.getLocals(), new String[0]);
if (args.isEmpty()) {
settings.setCategory(null);
CFICommands.mainMenu(fp);
return null;
}
}
return args;
}
}

View File

@ -2,6 +2,7 @@ package com.boydti.fawe.command;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.SingleFilterBlock;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Commands;
@ -19,8 +20,14 @@ import com.boydti.fawe.util.TextureUtil;
import com.boydti.fawe.util.chat.Message;
import com.boydti.fawe.util.image.ImageUtil;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import java.nio.file.Path;
import java.util.function.Consumer;
import java.util.stream.IntStream;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.exception.StopExecutionException;
import org.enginehub.piston.inject.InjectedValueAccess;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.command.util.CommandPermissions;
@ -75,23 +82,34 @@ import static com.boydti.fawe.util.image.ImageUtil.load;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class CFICommands extends MethodCommands {
private final Dispatcher dispathcer;
private final WorldEdit worldEdit;
/**
* Create a new instance.
*
* @param worldEdit reference to WorldEdit
*/
public CFICommands(WorldEdit worldEdit, Dispatcher dispatcher) {
super(worldEdit);
this.dispathcer = dispatcher;
public CFICommands(WorldEdit worldEdit) {
this.worldEdit = worldEdit;
}
public static File getFolder(String worldName) {
Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING);
List<? extends World> worlds = platform.getWorlds();
IQueueExtent queue = SetQueue.IMP.getNewQueue(worlds.get(0), true, false);
return new File(queue.getSaveFolder().getParentFile().getParentFile(), worldName + File.separator + "region");
Path path = worlds.get(0).getStoragePath();
return new File(path.toFile().getParentFile().getParentFile(), worldName + File.separator + "region");
}
@Command(
name = "",
desc = "CFI command"
)
@CommandPermissions("worldedit.anvil.cfi")
public void cfi(FawePlayer fp, List<String> args) {
CFISettings settings = getSettings(fp);
if (!settings.hasGenerator()) {
}
}
@Command(
@ -99,7 +117,7 @@ public class CFICommands extends MethodCommands {
desc = "Start CFI with a height map as a base"
)
@CommandPermissions("worldedit.anvil.cfi")
public void heightmap(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Arg(name = "yscale", desc = "double", def = "1") double yscale) throws ParameterException {
public void heightmap(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Arg(name = "yscale", desc = "double", def = "1") double yscale) {
if (yscale != 0) {
int[] raw = ((DataBufferInt) image.load().getRaster().getDataBuffer()).getData();
int[] table = IntStream.range(0, 256).map(i -> Math.min(255, (int) (i * yscale)))
@ -145,7 +163,7 @@ public class CFICommands extends MethodCommands {
desc = "Info about using brushes with CFI"
)
@CommandPermissions("worldedit.anvil.cfi")
public void brush(FawePlayer fp) throws ParameterException {
public void brush(FawePlayer fp) {
CFISettings settings = assertSettings(fp);
settings.popMessages(fp);
Message msg;
@ -232,7 +250,7 @@ public class CFICommands extends MethodCommands {
desc = "Set the floor and main block"
)
@CommandPermissions("worldedit.anvil.cfi")
public void column(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
public void column(FawePlayer fp, Pattern pattern, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly){
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) {
gen.setColumn(load(image), pattern, !disableWhiteOnly);
@ -251,14 +269,14 @@ public class CFICommands extends MethodCommands {
desc = "Set the floor (default: grass)"
)
@CommandPermissions("worldedit.anvil.cfi")
public void floorCmd(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
public void floorCmd(FawePlayer fp, Pattern pattern, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly){
floor(fp, pattern, image, mask, disableWhiteOnly);
fp.sendMessage("Set floor!");
assertSettings(fp).resetComponent();
component(fp);
}
private void floor(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException {
private void floor(FawePlayer fp, Pattern pattern, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) {
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) {
gen.setFloor(load(image), pattern, !disableWhiteOnly);
@ -274,14 +292,14 @@ public class CFICommands extends MethodCommands {
desc = "Set the main block (default: stone)"
)
@CommandPermissions("worldedit.anvil.cfi")
public void mainCmd(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
public void mainCmd(FawePlayer fp, Pattern pattern, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly){
main(fp, pattern, image, mask, disableWhiteOnly);
fp.sendMessage("Set main!");
assertSettings(fp).resetComponent();
component(fp);
}
public void main(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
public void main(FawePlayer fp, Pattern pattern, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly){
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) {
gen.setMain(load(image), pattern, !disableWhiteOnly);
@ -300,7 +318,7 @@ public class CFICommands extends MethodCommands {
"e.g. Tallgrass"
)
@CommandPermissions("worldedit.anvil.cfi")
public void overlay(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
public void overlay(FawePlayer fp, Pattern pattern, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly){
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) {
gen.setOverlay(load(image), pattern, !disableWhiteOnly);
@ -322,13 +340,13 @@ public class CFICommands extends MethodCommands {
" - A good value for radius and iterations would be 1 8."
)
@CommandPermissions("worldedit.anvil.cfi")
public void smoothCmd(FawePlayer fp, int radius, int iterations, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
public void smoothCmd(FawePlayer fp, int radius, int iterations, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly){
smooth(fp, radius, iterations, image, mask, disableWhiteOnly);
assertSettings(fp).resetComponent();
component(fp);
}
private void smooth(FawePlayer fp, int radius, int iterations, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
private void smooth(FawePlayer fp, int radius, int iterations, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly){
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) {
gen.smooth(load(image), !disableWhiteOnly, radius, iterations);
@ -342,7 +360,7 @@ public class CFICommands extends MethodCommands {
desc = "Create some snow"
)
@CommandPermissions("worldedit.anvil.cfi")
public void snow(FawePlayer fp, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
public void snow(FawePlayer fp, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly){
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
floor(fp, BlockTypes.SNOW.getDefaultState().with(PropertyKey.LAYERS, 7), image, mask, disableWhiteOnly);
main(fp, BlockTypes.SNOW_BLOCK, image, mask, disableWhiteOnly);
@ -361,7 +379,7 @@ public class CFICommands extends MethodCommands {
"Below 50 will prefer to color with blocks"
)
@CommandPermissions("worldedit.anvil.cfi")
public void biomepriority(FawePlayer fp, int value) throws ParameterException {
public void biomepriority(FawePlayer fp, int value) {
assertSettings(fp).getGenerator().setBiomePriority(value);
coloring(fp);
}
@ -374,7 +392,7 @@ public class CFICommands extends MethodCommands {
"`#clipboard` will only use the blocks present in your clipboard."
)
@CommandPermissions("worldedit.anvil.cfi")
public void paletteblocks(FawePlayer fp, Player player, LocalSession session, @Arg(name = "arg", desc = "String", def = "") String arg) throws ParameterException, EmptyClipboardException, InputParseException, FileNotFoundException {
public void paletteblocks(FawePlayer fp, Player player, LocalSession session, @Arg(name = "arg", desc = "String", def = "") String arg) throws EmptyClipboardException, InputParseException, FileNotFoundException {
if (arg == null) {
msg("What blocks do you want to color with?").newline()
.text("[All]").cmdTip(alias() + " PaletteBlocks *").text(" - All available blocks")
@ -452,7 +470,7 @@ public class CFICommands extends MethodCommands {
"Randomization will allow mixing biomes when coloring with biomes"
)
@CommandPermissions("worldedit.anvil.cfi")
public void randomization(FawePlayer fp, boolean enabled) throws ParameterException {
public void randomization(FawePlayer fp, boolean enabled) {
assertSettings(fp).getGenerator().setTextureRandomVariation(enabled);
coloring(fp);
}
@ -466,7 +484,7 @@ public class CFICommands extends MethodCommands {
"Using 0 73 for the min/max would use the simplest 73% of blocks for coloring, and is a reasonable value."
)
@CommandPermissions("worldedit.anvil.cfi")
public void complexity(FawePlayer fp, int min, int max) throws ParameterException, FileNotFoundException {
public void complexity(FawePlayer fp, int min, int max) throws FileNotFoundException {
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (min == 0 && max == 100) {
gen.setTextureUtil(Fawe.get().getTextureUtil());
@ -485,7 +503,7 @@ public class CFICommands extends MethodCommands {
" - The distance is the spacing between each schematic"
)
@CommandPermissions("worldedit.anvil.cfi")
public void schem(FawePlayer fp, @Optional FawePrimitiveBinding.ImageUri imageMask, Mask mask, String schematic, int rarity, int distance, boolean rotate) throws ParameterException, IOException, WorldEditException {
public void schem(FawePlayer fp, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri imageMask, Mask mask, String schematic, int rarity, int distance, boolean rotate)throws IOException, WorldEditException {
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
World world = fp.getWorld();
@ -511,7 +529,7 @@ public class CFICommands extends MethodCommands {
" - If a mask is used, the biome will be set anywhere the mask applies"
)
@CommandPermissions("worldedit.anvil.cfi")
public void biome(FawePlayer fp, BiomeType biome, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
public void biome(FawePlayer fp, BiomeType biome, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly){
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) {
gen.setBiome(load(image), biome, !disableWhiteOnly);
@ -530,7 +548,7 @@ public class CFICommands extends MethodCommands {
desc = "Generate vanilla caves"
)
@CommandPermissions("worldedit.anvil.cfi")
public void caves(FawePlayer fp) throws ParameterException, WorldEditException {
public void caves(FawePlayer fp) throws WorldEditException {
assertSettings(fp).getGenerator().addCaves();
msg("Added caves!").send(fp);
populate(fp);
@ -542,7 +560,7 @@ public class CFICommands extends MethodCommands {
descFooter = "Use a specific pattern and settings to generate ore"
)
@CommandPermissions("worldedit.anvil.cfi")
public void ore(FawePlayer fp, Mask mask, Pattern pattern, int size, int frequency, int rariry, int minY, int maxY) throws ParameterException, WorldEditException {
public void ore(FawePlayer fp, Mask mask, Pattern pattern, int size, int frequency, int rariry, int minY, int maxY) throws WorldEditException {
assertSettings(fp).getGenerator().addOre(mask, pattern, size, frequency, rariry, minY, maxY);
msg("Added ore!").send(fp);
populate(fp);
@ -553,7 +571,7 @@ public class CFICommands extends MethodCommands {
desc = "Generate the vanilla ores"
)
@CommandPermissions("worldedit.anvil.cfi")
public void ores(FawePlayer fp, Mask mask) throws ParameterException, WorldEditException {
public void ores(FawePlayer fp, Mask mask) throws WorldEditException {
assertSettings(fp).getGenerator().addDefaultOres(mask);
msg("Added ores!").send(fp);
populate(fp);
@ -565,7 +583,7 @@ public class CFICommands extends MethodCommands {
descFooter = "Set the terrain height either based on an image heightmap, or a numeric value."
)
@CommandPermissions("worldedit.anvil.cfi")
public void height(FawePlayer fp, String arg) throws ParameterException, WorldEditException {
public void height(FawePlayer fp, String arg) throws WorldEditException {
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (!MathMan.isInteger(arg)) {
gen.setHeight(ImageUtil.getImage(arg));
@ -581,7 +599,7 @@ public class CFICommands extends MethodCommands {
desc = "Change the block used for water\ne.g. Lava"
)
@CommandPermissions("worldedit.anvil.cfi")
public void waterId(FawePlayer fp, BlockStateHolder block) throws ParameterException, WorldEditException {
public void waterId(FawePlayer fp, BlockStateHolder block) throws WorldEditException {
CFISettings settings = assertSettings(fp);
settings.getGenerator().setWaterId(block.getBlockType().getInternalId());
msg("Set water id!").send(fp);
@ -595,7 +613,7 @@ public class CFICommands extends MethodCommands {
desc = "Change the block used for the base\ne.g. Bedrock"
)
@CommandPermissions("worldedit.anvil.cfi")
public void baseId(FawePlayer fp, BlockStateHolder block) throws ParameterException, WorldEditException {
public void baseId(FawePlayer fp, BlockStateHolder block) throws WorldEditException {
CFISettings settings = assertSettings(fp);
settings.getGenerator().setBedrockId(block.getBlockType().getInternalId());
msg("Set base id!").send(fp);
@ -610,7 +628,7 @@ public class CFICommands extends MethodCommands {
" - A value of 0 is the default and will not modify the height"
)
@CommandPermissions("worldedit.anvil.cfi")
public void worldthickness(FawePlayer fp, int height) throws ParameterException, WorldEditException {
public void worldthickness(FawePlayer fp, int height) throws WorldEditException {
assertSettings(fp).getGenerator().setWorldThickness(height);
msg("Set world thickness!").send(fp);
component(fp);
@ -623,7 +641,7 @@ public class CFICommands extends MethodCommands {
" - A value of 0 is the default and will only set the top block"
)
@CommandPermissions("worldedit.anvil.cfi")
public void floorthickness(FawePlayer fp, int height) throws ParameterException, WorldEditException {
public void floorthickness(FawePlayer fp, int height) throws WorldEditException {
assertSettings(fp).getGenerator().setFloorThickness(height);
msg("Set floor thickness!").send(fp);
component(fp);
@ -635,7 +653,7 @@ public class CFICommands extends MethodCommands {
desc = "Resend the CFI chunks"
)
@CommandPermissions("worldedit.anvil.cfi")
public void update(FawePlayer fp) throws ParameterException, WorldEditException {
public void update(FawePlayer fp) throws WorldEditException {
assertSettings(fp).getGenerator().update();
msg("Chunks refreshed!").send(fp);
mainMenu(fp);
@ -647,7 +665,7 @@ public class CFICommands extends MethodCommands {
desc = "Teleport to the CFI virtual world"
)
@CommandPermissions("worldedit.anvil.cfi")
public void tp(FawePlayer fp) throws ParameterException, WorldEditException {
public void tp(FawePlayer fp) throws WorldEditException {
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
msg("Teleporting...").send(fp);
Vector3 origin = gen.getOrigin();
@ -665,7 +683,7 @@ public class CFICommands extends MethodCommands {
" - By default water is disabled (with a value of 0)"
)
@CommandPermissions("worldedit.anvil.cfi")
public void waterheight(FawePlayer fp, int height) throws ParameterException, WorldEditException {
public void waterheight(FawePlayer fp, int height) throws WorldEditException {
assertSettings(fp).getGenerator().setWaterHeight(height);
msg("Set water height!").send(fp);
component(fp);
@ -678,7 +696,7 @@ public class CFICommands extends MethodCommands {
)
// ![79,174,212,5:3,5:4,18,161,20]
@CommandPermissions("worldedit.anvil.cfi")
public void glass(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Optional FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException, WorldEditException {
public void glass(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws WorldEditException {
CFISettings settings = assertSettings(fp);
settings.getGenerator().setColorWithGlass(load(image));
msg("Set color with glass!").send(fp);
@ -695,7 +713,7 @@ public class CFICommands extends MethodCommands {
"The -w (disableWhiteOnly) will randomly apply depending on the pixel luminance"
)
@CommandPermissions("worldedit.anvil.cfi")
public void color(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Optional FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException, WorldEditException {
public void color(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws WorldEditException {
CFISettings settings = assertSettings(fp);
HeightMapMCAGenerator gen = settings.getGenerator();
if (imageMask != null) {
@ -719,7 +737,7 @@ public class CFICommands extends MethodCommands {
"The -w (disableWhiteOnly) will randomly apply depending on the pixel luminance"
)
@CommandPermissions("worldedit.anvil.cfi")
public void blockbiome(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Optional FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException, WorldEditException {
public void blockbiome(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws WorldEditException {
CFISettings settings = assertSettings(fp);
settings.getGenerator().setBlockAndBiomeColor(load(image), mask, load(imageMask), !disableWhiteOnly);
msg("Set color with blocks and biomes!").send(fp);
@ -735,7 +753,7 @@ public class CFICommands extends MethodCommands {
" - If you changed the block to something other than grass you will not see anything."
)
@CommandPermissions("worldedit.anvil.cfi")
public void biomecolor(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Optional FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException, WorldEditException {
public void biomecolor(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws WorldEditException {
CFISettings settings = assertSettings(fp);
settings.getGenerator().setBiomeColor(load(image));
msg("Set color with biomes!").send(fp);
@ -750,10 +768,10 @@ public class CFICommands extends MethodCommands {
desc = "Color the world using an image"
)
@CommandPermissions("worldedit.anvil.cfi")
public void coloring(FawePlayer fp) throws ParameterException {
public void coloring(FawePlayer fp) {
CFISettings settings = assertSettings(fp);
settings.popMessages(fp);
settings.setCategory("coloring");
settings.setCategory(this::coloring);
HeightMapMCAGenerator gen = settings.getGenerator();
boolean rand = gen.getTextureRandomVariation();
String mask;
@ -834,7 +852,7 @@ public class CFICommands extends MethodCommands {
desc = "Select a mask"
)
@CommandPermissions("worldedit.anvil.cfi")
public void mask(FawePlayer fp, @Optional FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly, InjectedValueAccess context) throws ParameterException{
public void mask(FawePlayer fp, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly, InjectedValueAccess context){
CFISettings settings = assertSettings(fp);
String[] split = getArguments(context).split(" ");
int index = 2;
@ -859,7 +877,7 @@ public class CFICommands extends MethodCommands {
desc = "Select a pattern"
)
@CommandPermissions("worldedit.anvil.cfi")
public void pattern(FawePlayer fp, @Arg(name = "pattern", desc = "Pattern", def = "") Pattern pattern, InjectedValueAccess context) throws ParameterException, CommandException {
public void pattern(FawePlayer fp, @Arg(name = "pattern", desc = "Pattern", def = "") Pattern pattern, InjectedValueAccess context)throws CommandException {
CFISettings settings = assertSettings(fp);
String[] split = getArguments(context).split(" ");
int index = 2;
@ -869,7 +887,7 @@ public class CFICommands extends MethodCommands {
StringBuilder cmd = new StringBuilder(alias() + " pattern ");
if (pattern != null) {
dispathcer.call(settings.getCategory(), context.getLocals(), new String[0]);
settings.getCategory().accept(fp);
} else {
msg(">> Current Settings <<").newline()
.text("Pattern ").text("[Click Here]").suggestTip(cmd + " stone")
@ -883,7 +901,7 @@ public class CFICommands extends MethodCommands {
desc = "Download the current image"
)
@CommandPermissions("worldedit.anvil.cfi")
public void download(FawePlayer fp) throws ParameterException, IOException {
public void download(FawePlayer fp)throws IOException {
CFISettings settings = assertSettings(fp);
BufferedImage image = settings.getGenerator().draw();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@ -899,14 +917,13 @@ public class CFICommands extends MethodCommands {
desc = "Select an image"
)
@CommandPermissions("worldedit.anvil.cfi")
public void image(FawePlayer fp, @Optional FawePrimitiveBinding.ImageUri image, InjectedValueAccess context) throws ParameterException, CommandException {
public void image(FawePlayer fp, @Arg(def = "", desc = "image url or filename") FawePrimitiveBinding.ImageUri image, InjectedValueAccess context)throws CommandException {
CFISettings settings = getSettings(fp);
String[] split = getArguments(context).split(" ");
int index = 2;
settings.image = image;
settings.imageArg = image != null ? split[index++] : null;
String maskArg = settings.maskArg == null ? "Click Here" : settings.maskArg;
StringBuilder cmd = new StringBuilder(alias() + " image ");
if (image == null) {
@ -920,8 +937,7 @@ public class CFICommands extends MethodCommands {
coloring(fp);
return;
} else {
String next = Commands.getAlias(CFICommands.class, "heightmap " + settings.imageArg);
dispathcer.call(next, context.getLocals(), new String[0]);
heightmap(fp, image, 1);
return;
}
}
@ -932,10 +948,10 @@ public class CFICommands extends MethodCommands {
desc = ""
)
@CommandPermissions("worldedit.anvil.cfi")
public void populate(FawePlayer fp) throws ParameterException {
public void populate(FawePlayer fp) {
CFISettings settings = assertSettings(fp);
settings.popMessages(fp);
settings.setCategory("populate");
settings.setCategory(this::populate);
msg("What would you like to populate?").newline()
.text("(You will need to type these commands)").newline()
.cmdOptions(alias() + " ", "", "Ores", "Ore", "Caves", "Schematics", "Smooth")
@ -949,10 +965,10 @@ public class CFICommands extends MethodCommands {
desc = "Components menu"
)
@CommandPermissions("worldedit.anvil.cfi")
public void component(FawePlayer fp) throws ParameterException {
public void component(FawePlayer fp) {
CFISettings settings = assertSettings(fp);
settings.popMessages(fp);
settings.setCategory("component");
settings.setCategory(this::component);
String mask;
if (settings.imageMask != null) {
@ -1027,16 +1043,16 @@ public class CFICommands extends MethodCommands {
}
private CFISettings assertSettings(FawePlayer fp) throws ParameterException {
private static CFISettings assertSettings(FawePlayer fp) {
CFISettings settings = getSettings(fp);
if (!settings.hasGenerator()) {
throw new ParameterException("Please use /" + alias());
throw new StopExecutionException(TextComponent.of("Please use /" + alias()));
}
return settings;
}
protected CFISettings getSettings(FawePlayer fp) {
protected static CFISettings getSettings(FawePlayer fp) {
CFISettings settings = fp.getMeta("CFISettings");
return settings == null ? new CFISettings(fp) : settings;
}
@ -1057,7 +1073,7 @@ public class CFICommands extends MethodCommands {
protected Pattern pattern;
protected String patternArg;
protected String category;
protected Consumer<FawePlayer> category;
private boolean bound;
@ -1108,11 +1124,11 @@ public class CFICommands extends MethodCommands {
pattern = null;
}
public String getCategory() {
public Consumer<FawePlayer> getCategory() {
return category;
}
public void setCategory(String category) {
public void setCategory(Consumer<FawePlayer> methodRef) {
this.category = category;
}
@ -1162,21 +1178,21 @@ public class CFICommands extends MethodCommands {
}
}
protected String alias() {
protected static String alias() {
return Commands.getAlias(CFICommand.class, "/cfi");
}
protected String alias(String command) {
protected static String alias(String command) {
return Commands.getAlias(CFICommands.class, command);
}
protected Message msg(String text) {
protected static Message msg(String text) {
return new Message().newline()
.text(BBC.getPrefix())
.text(text);
}
protected void mainMenu(FawePlayer fp) {
protected static void mainMenu(FawePlayer fp) {
msg("What do you want to do now?").newline()
.cmdOptions(alias() + " ", "", "Coloring", "Component", "Populate", "Brush")
.newline().text("<> [View]").command(alias() + " " + Commands.getAlias(CFICommands.class, "download")).tooltip("View full resolution image")

View File

@ -14,7 +14,7 @@ import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Stream;
public class CommandProcessor implements CommandManager {
public abstract class CommandProcessor<I, O> implements CommandManager {
private final CommandManager parent;
public CommandProcessor(CommandManager parent) {
@ -22,62 +22,72 @@ public class CommandProcessor implements CommandManager {
}
@Override
public Command.Builder newCommand(String s) {
public final Command.Builder newCommand(String s) {
return parent.newCommand(s);
}
@Override
public void register(Command command) {
public final void register(Command command) {
parent.register(command);
}
@Override
public void register(String name, Consumer<Command.Builder> registrationProcess) {
public final void register(String name, Consumer<Command.Builder> registrationProcess) {
parent.register(name, registrationProcess);
}
@Override
public void registerManager(CommandManager manager) {
public final void registerManager(CommandManager manager) {
parent.registerManager(manager);
}
@Override
public Stream<Command> getAllCommands() {
public final Stream<Command> getAllCommands() {
return parent.getAllCommands();
}
@Override
public boolean containsCommand(String name) {
public final boolean containsCommand(String name) {
return parent.containsCommand(name);
}
@Override
public Optional<Command> getCommand(String s) {
public final Optional<Command> getCommand(String s) {
return parent.getCommand(s);
}
@Override
public ImmutableSet<Suggestion> getSuggestions(InjectedValueAccess injectedValueAccess, List<String> list) {
public final ImmutableSet<Suggestion> getSuggestions(InjectedValueAccess injectedValueAccess, List<String> list) {
return parent.getSuggestions(injectedValueAccess, list);
}
@Override
public CommandParseResult parse(InjectedValueAccess injectedValueAccess, List<String> list) {
public final CommandParseResult parse(InjectedValueAccess injectedValueAccess, List<String> list) {
return parent.parse(injectedValueAccess, list);
}
@Override
public int execute(InjectedValueAccess context, List<String> args) {
return parent.execute(context, args);
public final O /* Need to recompile with FAWE-piston */ execute(InjectedValueAccess context, List<String> args) {
args = preprocess(context, args);
if (args != null) {
I result = (I) (Object) parent.execute(context, args);
return process(context, args, result); // TODO NOT IMPLEMENTED (recompile piston)
} else {
return null;
}
}
@Override
public <T> void registerConverter(Key<T> key, ArgumentConverter<T> argumentConverter) {
public final <T> void registerConverter(Key<T> key, ArgumentConverter<T> argumentConverter) {
parent.registerConverter(key, argumentConverter);
}
@Override
public <T> Optional<ArgumentConverter<T>> getConverter(Key<T> key) {
public final <T> Optional<ArgumentConverter<T>> getConverter(Key<T> key) {
return parent.getConverter(key);
}
public abstract List<String> preprocess(InjectedValueAccess context, List<String> args);
public abstract O process(InjectedValueAccess context, List<String> args, I result);
}

View File

@ -1,586 +0,0 @@
package com.boydti.fawe.command;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.extent.NullExtent;
import com.boydti.fawe.object.extent.ResettableExtent;
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.WorldEdit;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player;
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.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.session.request.Request;
import com.sk89q.worldedit.internal.annotation.Range;
import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.internal.annotation.Validate;
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 javax.annotation.Nullable;
import java.awt.image.BufferedImage;
import java.lang.annotation.Annotation;
import java.net.URI;
public class FawePrimitiveBinding {
@BindingMatch(type = {Long.class, long.class},
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true)
public Long getLong(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
try {
Long v = Long.parseLong(context.next());
validate(v, modifiers);
return v;
} catch (NumberFormatException ignore) {
return null;
}
}
private static void validate(long number, Annotation[] modifiers) throws ParameterException {
for (Annotation modifier : modifiers) {
if (modifier instanceof Range) {
Range range = (Range) modifier;
if (number < range.min()) {
throw new ParameterException(
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 ParameterException(
String.format(
"A valid value is less than or equal to %s " +
"(you entered %s)", range.max(), number));
}
}
}
}
public class ImageUri {
public final URI uri;
private BufferedImage image;
ImageUri(URI uri) {
this.uri = uri;
}
public BufferedImage load() throws ParameterException {
if (image != null) {
return image;
}
return image = ImageUtil.load(uri);
}
}
@BindingMatch(
type = {ImageUri.class},
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true
)
public ImageUri getImage(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
return new ImageUri(ImageUtil.getImageURI(context.next()));
}
@BindingMatch(
type = {TextureUtil.class},
behavior = BindingBehavior.PROVIDES
)
public TextureUtil getTexture(ArgumentStack context) {
Actor actor = context.getContext().getLocals().get(Actor.class);
if (actor == null) {
return Fawe.get().getCachedTextureUtil(true, 0, 100);
}
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
return session.getTextureUtil();
}
@BindingMatch(
type = {Extent.class},
behavior = BindingBehavior.PROVIDES
)
public Extent getExtent(ArgumentStack context) throws ParameterException {
Extent extent = context.getContext().getLocals().get(EditSession.class);
if (extent != null) {
return extent;
}
extent = Request.request().getExtent();
if (extent != null) {
return extent;
}
Actor actor = context.getContext().getLocals().get(Actor.class);
if (actor == null) {
throw new ParameterException("No player to get a session for");
}
if (!(actor instanceof Player)) {
throw new ParameterException("Caller is not a player");
}
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
EditSession editSession = session.createEditSession((Player) actor);
editSession.enableQueue();
context.getContext().getLocals().put(EditSession.class, editSession);
session.tellVersion(actor);
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
*/
@BindingMatch(type = FawePlayer.class,
behavior = BindingBehavior.PROVIDES)
public FawePlayer getFawePlayer(ArgumentStack context) throws ParameterException, InputParseException {
Actor sender = context.getContext().getLocals().get(Actor.class);
if (sender == null) {
throw new ParameterException("Missing 'Actor'");
} else {
return FawePlayer.wrap(sender);
}
}
/**
* Gets an {@link com.sk89q.worldedit.extent.Extent} from a {@link ArgumentStack}.
*
* @param context the context
* @return an extent
* @throws ParameterException on other error
*/
@BindingMatch(type = ResettableExtent.class,
behavior = BindingBehavior.PROVIDES)
public ResettableExtent getResettableExtent(ArgumentStack context) throws ParameterException, InputParseException {
String input = context.next();
if (input.equalsIgnoreCase("#null")) {
return new NullExtent();
}
DefaultTransformParser parser = Fawe.get().getTransformParser();
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.getInstance().getSessionManager().get(actor));
return parser.parseFromInput(input, parserContext);
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @param text the text annotation
* @param modifiers a list of modifiers
* @return the requested type
* @throws ParameterException on error
*/
@BindingMatch(classifier = Text.class,
type = String.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = -1,
provideModifiers = true)
public String getText(ArgumentStack context, Text text, Annotation[] modifiers)
throws ParameterException {
String v = context.remaining();
validate(v, modifiers);
return v;
}
@BindingMatch(type = {Expression.class},
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public Expression getExpression(ArgumentStack context) throws ParameterException, ExpressionException {
String input = context.next();
try {
return new Expression(Double.parseDouble(input));
} catch (NumberFormatException e1) {
try {
Expression expression = Expression.compile(input);
expression.optimize();
return expression;
} catch (EvaluationException e) {
throw new ParameterException(String.format(
"Expected '%s' to be a valid number (or a valid mathematical expression)", input));
} catch (ExpressionException e) {
throw new ParameterException(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 ParameterException on error
*/
@BindingMatch(type = String.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true)
public String getString(ArgumentStack context, Annotation[] modifiers)
throws ParameterException {
String v = context.next();
validate(v, modifiers);
return v;
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @return the requested type
* @throws ParameterException on error
*/
@BindingMatch(type = {Boolean.class, boolean.class},
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public Boolean getBoolean(ArgumentStack context) throws ParameterException {
return context.nextBoolean();
}
/**
* Gets a type from a {@link ArgumentStack}.
*
* @param context the context
* @return the requested type
* @throws ParameterException on error
*/
@BindingMatch(type = Vector3.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true)
public Vector3 getVector3(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
String radiusString = context.next();
String[] radii = radiusString.split(",");
final double radiusX, radiusY, radiusZ;
switch (radii.length) {
case 1:
radiusX = radiusY = radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0]));
break;
case 3:
radiusX = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0]));
radiusY = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[1]));
radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[2]));
break;
default:
throw new ParameterException("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 ParameterException on error
*/
@BindingMatch(type = Vector2.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true)
public Vector2 getVector2(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
String radiusString = context.next();
String[] radii = radiusString.split(",");
final double radiusX, radiusZ;
switch (radii.length) {
case 1:
radiusX = radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0]));
break;
case 2:
radiusX = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0]));
radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[1]));
break;
default:
throw new ParameterException("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 ParameterException on error
*/
@BindingMatch(type = BlockVector3.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true)
public BlockVector3 getBlockVector3(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
String radiusString = context.next();
String[] radii = radiusString.split(",");
final double radiusX, radiusY, radiusZ;
switch (radii.length) {
case 1:
radiusX = radiusY = radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0]));
break;
case 3:
radiusX = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0]));
radiusY = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[1]));
radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[2]));
break;
default:
throw new ParameterException("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 ParameterException on error
*/
@BindingMatch(type = BlockVector2.class,
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true)
public BlockVector2 getBlockVector2(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
String radiusString = context.next();
String[] radii = radiusString.split(",");
final double radiusX, radiusZ;
switch (radii.length) {
case 1:
radiusX = radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0]));
break;
case 2:
radiusX = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0]));
radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[1]));
break;
default:
throw new ParameterException("You must either specify 1 or 2 radius values.");
}
return BlockVector2.at(radiusX, radiusZ);
}
/**
* Try to parse numeric input as either a number or a mathematical expression.
*
* @param input input
* @return a number
* @throws ParameterException thrown on parse error
*/
public static
@Nullable
Double parseNumericInput(@Nullable String input) throws ParameterException {
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 ParameterException(String.format(
"Expected '%s' to be a valid number (or a valid mathematical expression)", input));
} catch (ExpressionException e) {
throw new ParameterException(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 ParameterException on error
*/
@BindingMatch(type = {Integer.class, int.class},
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true)
public Integer getInteger(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
Double v = parseNumericInput(context.next());
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 ParameterException on error
*/
@BindingMatch(type = {Short.class, short.class},
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true)
public Short getShort(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
Integer v = getInteger(context, 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 ParameterException on error
*/
@BindingMatch(type = {Double.class, double.class},
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true)
public Double getDouble(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
Double v = parseNumericInput(context.next());
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 ParameterException on error
*/
@BindingMatch(type = {Float.class, float.class},
behavior = BindingBehavior.CONSUMES,
consumedCount = 1,
provideModifiers = true)
public Float getFloat(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
Double v = getDouble(context, 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 ParameterException on a validation error
*/
private static void validate(double number, Annotation[] modifiers)
throws ParameterException {
for (Annotation modifier : modifiers) {
if (modifier instanceof Range) {
Range range = (Range) modifier;
if (number < range.min()) {
throw new ParameterException(
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 ParameterException(
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 ParameterException on a validation error
*/
private static void validate(int number, Annotation[] modifiers)
throws ParameterException {
for (Annotation modifier : modifiers) {
if (modifier instanceof Range) {
Range range = (Range) modifier;
if (number < range.min()) {
throw new ParameterException(
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 ParameterException(
String.format(
"A valid value is less than or equal to %s (you entered %s)", range.max(), number));
}
}
}
}
/**
* Validate a string value using relevant modifiers.
*
* @param string the string
* @param modifiers the list of modifiers to scan
* @throws ParameterException on a validation error
*/
private static void validate(String string, Annotation[] modifiers)
throws ParameterException {
if (string == null) {
return;
}
for (Annotation modifier : modifiers) {
if (modifier instanceof Validate) {
Validate validate = (Validate) modifier;
if (!validate.regex().isEmpty()) {
if (!string.matches(validate.regex())) {
throw new ParameterException(
String.format(
"The given text doesn't match the right format (technically speaking, the 'format' is %s)",
validate.regex()));
}
}
}
}
}
}

View File

@ -1,170 +0,0 @@
package com.boydti.fawe.object.extent;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.object.HasIQueueExtent;
import com.boydti.fawe.util.ReflectionUtils;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.FloatTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
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.block.BlockTypes;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FastWorldEditExtent extends AbstractDelegateExtent implements HasIQueueExtent {
private final World world;
private IQueueExtent queue;
public FastWorldEditExtent(final World world, IQueueExtent queue) {
super(queue);
this.world = world;
this.queue = queue;
}
@Override
public IQueueExtent getQueue() {
return queue;
}
@Override
public int getMaxY() {
return queue.getMaxY();
}
@Override
public int getLight(int x, int y, int z) {
return queue.getLight(x, y, z);
}
@Override
public int getBlockLight(int x, int y, int z) {
return queue.getEmmittedLight(x, y, z);
}
@Override
public int getSkyLight(int x, int y, int z) {
return queue.getSkyLight(x, y, z);
}
@Override
public int getBrightness(int x, int y, int z) {
return queue.getBrightness(x, y, z);
}
@Override
public int getOpacity(int x, int y, int z) {
return queue.getOpacity(x, y, z);
}
@Override
public Entity createEntity(final Location loc, final BaseEntity entity) {
if (entity != null) {
CompoundTag tag = entity.getNbtData();
if (tag == null) {
HashMap<String, Tag> map = new HashMap<>();
tag = new CompoundTag(map);
}
Map<String, Tag> map = ReflectionUtils.getMap(tag.getValue());
map.put("Id", new StringTag(entity.getType().getId()));
ListTag pos = (ListTag) map.get("Pos");
if (pos == null) {
map.put("Pos", new ListTag(DoubleTag.class, Arrays.asList(new DoubleTag(loc.getX()), new DoubleTag(loc.getY()), new DoubleTag(loc.getZ()))));
} else {
List<Tag> posList = ReflectionUtils.getList(pos.getValue());
posList.set(0, new DoubleTag(loc.getX()));
posList.set(1, new DoubleTag(loc.getY()));
posList.set(2, new DoubleTag(loc.getZ()));
}
ListTag rot = (ListTag) map.get("Rotation");
if (rot == null) {
map.put("Rotation", new ListTag(FloatTag.class, Arrays.asList(new FloatTag(loc.getYaw()), new DoubleTag(loc.getPitch()))));
}
queue.setEntity(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), tag);
}
return null;
}
@Override
public String toString() {
return super.toString() + ":" + queue + "(" + getExtent() + ")";
}
@Override
public BiomeType getBiome(final BlockVector2 position) {
return queue.getBiomeType(position.getBlockX(), position.getBlockZ());
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(final BlockVector3 location, final B block) throws WorldEditException {
return setBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block);
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, final B block) throws WorldEditException {
return queue.setBlock(x, y, z, block);
}
@Override
public BlockState getBlock(BlockVector3 location) {
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
@Override
public BlockState getBlock(int x, int y, int z) {
int combinedId4Data = queue.getCombinedId4Data(x, y, z, 0);
BlockType type = BlockTypes.getFromStateId(combinedId4Data);
return type.withStateId(combinedId4Data);
}
@Override
public BaseBlock getFullBlock(BlockVector3 pos) {
int combinedId4Data = queue.getCombinedId4Data(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(), 0);
BlockType type = BlockTypes.getFromStateId(combinedId4Data);
BaseBlock base = type.withStateId(combinedId4Data).toBaseBlock();
if (type.getMaterial().hasContainer()) {
CompoundTag tile = queue.getTileEntity(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
if (tile != null) {
return base.toBaseBlock(tile);
}
}
return base;
}
@Override
public List<? extends Entity> getEntities() {
return world.getEntities();
}
@Override
public List<? extends Entity> getEntities(final Region region) {
return world.getEntities(region);
}
@Override
public boolean setBiome(final BlockVector2 position, final BiomeType biome) {
queue.setBiome(position.getBlockX(), position.getBlockZ(), biome);
return true;
}
}

View File

@ -1,100 +0,0 @@
package com.boydti.fawe.object.visitor;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.example.MappedIQueueExtent;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.object.HasIQueueExtent;
import com.boydti.fawe.util.ExtentTraverser;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector2;
import java.util.Iterator;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class Fast2DIterator implements Iterable<BlockVector2> {
private final Iterable<? extends BlockVector2> iterable;
private final MappedIQueueExtent queue;
public Fast2DIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable EditSession extent) {
this(iter, (HasIQueueExtent) extent);
}
public Fast2DIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable Extent extent) {
this(iter, (HasIQueueExtent) (extent != null ? (extent instanceof HasIQueueExtent ? extent : new ExtentTraverser(extent).findAndGet(HasIQueueExtent.class)) : null));
}
public Fast2DIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable HasIQueueExtent editSession) {
this(iter, editSession != null ? editSession.getQueue() : null);
}
public Fast2DIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable IQueueExtent IQueueExtent) {
this.iterable = iter;
this.queue = IQueueExtent instanceof MappedIQueueExtent ? (MappedIQueueExtent) IQueueExtent : null;
}
public Iterable<? extends BlockVector2> getIterable() {
return iterable;
}
@Override
public Iterator<BlockVector2> iterator() {
if (queue == null || Settings.IMP.QUEUE.PRELOAD_CHUNKS <= 1) {
return (Iterator<BlockVector2>) iterable.iterator();
}
return new Iterator<BlockVector2>() {
Iterator<? extends BlockVector2> trailIter = iterable.iterator();
Iterator<? extends BlockVector2> leadIter = iterable.iterator();
int lastTrailChunkX = Integer.MIN_VALUE;
int lastTrailChunkZ = Integer.MIN_VALUE;
int lastLeadChunkX = Integer.MIN_VALUE;
int lastLeadChunkZ = Integer.MIN_VALUE;
int loadingTarget = Settings.IMP.QUEUE.PRELOAD_CHUNKS;
int cx, cz;
@Override
public void remove() {
trailIter.remove();
}
@Override
public boolean hasNext() {
return trailIter.hasNext();
}
@Override
public BlockVector2 next() {
BlockVector2 pt = trailIter.next();
if (lastTrailChunkX != (lastTrailChunkX = pt.getBlockX() >> 4) || lastTrailChunkZ != (lastTrailChunkZ = pt.getBlockZ() >> 4)) {
if (leadIter.hasNext()) {
try {
int amount;
if (lastLeadChunkX == Integer.MIN_VALUE) {
lastLeadChunkX = cx;
lastLeadChunkZ = cz;
amount = loadingTarget;
} else {
amount = 1;
}
for (int count = 0; count < amount; ) {
BlockVector2 v = leadIter.next();
int vcx = v.getBlockX() >> 4;
int vcz = v.getBlockZ() >> 4;
if (vcx != lastLeadChunkX || vcz != lastLeadChunkZ) {
lastLeadChunkX = vcx;
lastLeadChunkZ = vcz;
queue.queueChunkLoad(vcx, vcz);
count++;
}
}
} catch (Throwable ignore) {
}
}
}
return pt;
}
};
}
}

View File

@ -1,80 +0,0 @@
package com.boydti.fawe.object.visitor;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.example.MappedIQueueExtent;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.object.HasIQueueExtent;
import com.boydti.fawe.util.ExtentTraverser;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector2;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class FastChunkIterator implements Iterable<BlockVector2> {
private final Iterable<? extends BlockVector2> iterable;
private final MappedIQueueExtent queue;
public FastChunkIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable EditSession extent) {
this(iter, (HasIQueueExtent) extent);
}
public FastChunkIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable Extent extent) {
this(iter, (HasIQueueExtent) (extent != null ? (extent instanceof HasIQueueExtent ? extent : new ExtentTraverser(extent).findAndGet(HasIQueueExtent.class)) : null));
}
public FastChunkIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable HasIQueueExtent editSession) {
this(iter, editSession != null ? editSession.getQueue() : null);
}
public FastChunkIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable IQueueExtent IQueueExtent) {
this.iterable = iter;
this.queue = IQueueExtent instanceof MappedIQueueExtent ? (MappedIQueueExtent) IQueueExtent : null;
}
public Iterable<? extends BlockVector2> getIterable() {
return iterable;
}
@NotNull
@Override
public Iterator<BlockVector2> iterator() {
if (queue == null || Settings.IMP.QUEUE.PRELOAD_CHUNKS <= 1) {
return (Iterator<BlockVector2>) iterable.iterator();
}
final Iterator<? extends BlockVector2> trailIter = iterable.iterator();
final Iterator<? extends BlockVector2> leadIter = iterable.iterator();
int amount = Settings.IMP.QUEUE.PRELOAD_CHUNKS;
for (int i = 0; i < Settings.IMP.QUEUE.PRELOAD_CHUNKS && leadIter.hasNext(); i++) {
BlockVector2 toLoad = leadIter.next();
queue.queueChunkLoad(toLoad.getBlockX(), toLoad.getBlockZ());
}
if (!leadIter.hasNext()) {
return (Iterator<BlockVector2>) trailIter;
}
return new Iterator<BlockVector2>() {
@Override
public void remove() {
trailIter.remove();
}
@Override
public boolean hasNext() {
return trailIter.hasNext();
}
@Override
public BlockVector2 next() {
if (leadIter.hasNext()) {
BlockVector2 toLoad = leadIter.next();
queue.queueChunkLoad(toLoad.getBlockX(), toLoad.getBlockZ());
}
return trailIter.next();
}
};
}
}

View File

@ -1,100 +0,0 @@
package com.boydti.fawe.object.visitor;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.example.MappedIQueueExtent;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.object.HasIQueueExtent;
import com.boydti.fawe.util.ExtentTraverser;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import java.util.Iterator;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class FastIterator implements Iterable<BlockVector3> {
private final Iterable<? extends BlockVector3> iterable;
private final MappedIQueueExtent queue;
public FastIterator(@Nonnull Iterable<? extends BlockVector3> iter, @Nullable EditSession extent) {
this(iter, (HasIQueueExtent) extent);
}
public FastIterator(@Nonnull Iterable<? extends BlockVector3> iter, @Nullable Extent extent) {
this(iter, (HasIQueueExtent) (extent != null ? (extent instanceof HasIQueueExtent ? extent : new ExtentTraverser(extent).findAndGet(HasIQueueExtent.class)) : null));
}
public FastIterator(@Nonnull Iterable<? extends BlockVector3> iter, @Nullable HasIQueueExtent editSession) {
this(iter, (IQueueExtent) (editSession != null ? editSession.getQueue() : null));
}
public FastIterator(@Nonnull Iterable<? extends BlockVector3> iter, @Nullable IQueueExtent IQueueExtent) {
this.iterable = iter;
this.queue = IQueueExtent != null && IQueueExtent instanceof MappedIQueueExtent ? (MappedIQueueExtent) IQueueExtent : null;
}
public Iterable<? extends BlockVector3> getIterable() {
return iterable;
}
@Override
public Iterator<BlockVector3> iterator() {
if (queue == null || Settings.IMP.QUEUE.PRELOAD_CHUNKS <= 1) {
return (Iterator<BlockVector3>) iterable.iterator();
}
return new Iterator<BlockVector3>() {
Iterator<? extends BlockVector3> trailIter = iterable.iterator();
Iterator<? extends BlockVector3> leadIter = iterable.iterator();
int lastTrailChunkX = Integer.MIN_VALUE;
int lastTrailChunkZ = Integer.MIN_VALUE;
int lastLeadChunkX = Integer.MIN_VALUE;
int lastLeadChunkZ = Integer.MIN_VALUE;
int loadingTarget = Settings.IMP.QUEUE.PRELOAD_CHUNKS;
int cx, cz;
@Override
public void remove() {
trailIter.remove();
}
@Override
public boolean hasNext() {
return trailIter.hasNext();
}
@Override
public BlockVector3 next() {
BlockVector3 pt = trailIter.next();
if (lastTrailChunkX != (lastTrailChunkX = pt.getBlockX() >> 4) || lastTrailChunkZ != (lastTrailChunkZ = pt.getBlockZ() >> 4)) {
if (leadIter.hasNext()) {
try {
int amount;
if (lastLeadChunkX == Integer.MIN_VALUE) {
lastLeadChunkX = cx;
lastLeadChunkZ = cz;
amount = loadingTarget;
} else {
amount = 1;
}
for (int count = 0; count < amount; ) {
BlockVector3 v = leadIter.next();
int vcx = v.getBlockX() >> 4;
int vcz = v.getBlockZ() >> 4;
if (vcx != lastLeadChunkX || vcz != lastLeadChunkZ) {
lastLeadChunkX = vcx;
lastLeadChunkZ = vcz;
queue.queueChunkLoad(vcx, vcz);
count++;
}
}
} catch (Throwable ignore) {
}
}
}
return pt;
}
};
}
}

View File

@ -1,13 +0,0 @@
package com.boydti.fawe.object.visitor;
public interface FaweChunkVisitor {
/**
* The will run for each set block in the chunk
*
* @param localX The x position in the chunk (0-15)
* @param y The y position (0 - 255)
* @param localZ The z position in the chunk (0-15)
* @param combined The combined id
*/
void run(int localX, int y, int localZ, int combined);
}

View File

@ -3,24 +3,20 @@ package com.boydti.fawe.regions.general.plot;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.util.SetQueue;
import com.github.intellectualsites.plotsquared.plot.object.PlotBlock;
import com.github.intellectualsites.plotsquared.plot.util.StringMan;
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Capability;
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.BlockTypes;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.util.Collection;
import java.util.List;
// TODO FIXME
public class FaweLocalBlockQueue extends LocalBlockQueue {

View File

@ -1,194 +0,0 @@
package com.boydti.fawe.regions.general.plot;
import com.boydti.fawe.jnbt.anvil.MCAChunk;
import com.boydti.fawe.jnbt.anvil.MCAFile;
import com.boydti.fawe.jnbt.anvil.MCAFilter;
import com.boydti.fawe.jnbt.anvil.MCAQueue;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.SetQueue;
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.object.ChunkLoc;
import com.github.intellectualsites.plotsquared.plot.object.Location;
import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import com.github.intellectualsites.plotsquared.plot.util.expiry.ExpireManager;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class PlotTrim {
private final MCAQueue queue;
private final PlotArea area;
private final PlotPlayer player;
private final MCAQueue originalQueue;
private final File root;
private int[][] ids;
private boolean deleteUnowned;
public PlotTrim(PlotPlayer player, PlotArea area, String worldName, boolean deleteUnowned) {
IQueueExtent tmpQueue = SetQueue.IMP.getNewQueue(worldName, true, false);
File saveFolder = tmpQueue.getSaveFolder();
this.root = new File(saveFolder.getParentFile().getParentFile(), worldName + "-Copy" + File.separator + "region");
this.originalQueue = new MCAQueue(worldName, saveFolder, true);
this.queue = new MCAQueue(worldName + "-Copy", root, true);
this.area = area;
this.player = player;
this.deleteUnowned = deleteUnowned;
}
public void setChunk(int[][] ids) {
checkNotNull(ids);
this.ids = ids;
}
public void setChunk(int x, int z) {
this.ids = ((MCAChunk) originalQueue.getFaweChunk(x, z)).ids;
}
private Map<Long, Object> chunks = new ConcurrentHashMap<>();
private Object PRESENT = new Object();
private void removeChunks(Plot plot) {
Location pos1 = plot.getBottom();
Location pos2 = plot.getTop();
int ccx1 = pos1.getX() >> 4;
int ccz1 = pos1.getZ() >> 4;
int ccx2 = pos2.getX() >> 4;
int ccz2 = pos2.getZ() >> 4;
for (int x = ccx1; x <= ccx2; x++) {
for (int z = ccz1; z <= ccz2; z++) {
long pair = MathMan.pairInt(x, z);
chunks.remove(pair);
}
}
}
public void run() {
final Set<ChunkLoc> mcas = new HashSet<>();
if (deleteUnowned && area != null) {
originalQueue.filterWorld(new MCAFilter() {
@Override
public boolean appliesFile(int mcaX, int mcaZ) {
mcas.add(new ChunkLoc(mcaX, mcaZ));
return false;
}
});
ArrayList<Plot> plots = new ArrayList<>(PlotSquared.get().getPlots(area));
if (ExpireManager.IMP != null) {
plots.removeAll(ExpireManager.IMP.getPendingExpired());
}
for (Plot plot : plots) {
Location pos1 = plot.getBottom();
Location pos2 = plot.getTop();
int ccx1 = pos1.getX() >> 9;
int ccz1 = pos1.getZ() >> 9;
int ccx2 = pos2.getX() >> 9;
int ccz2 = pos2.getZ() >> 9;
for (int x = ccx1; x <= ccx2; x++) {
for (int z = ccz1; z <= ccz2; z++) {
ChunkLoc loc = new ChunkLoc(x, z);
mcas.remove(loc);
}
}
}
for (ChunkLoc mca : mcas) {
int bx = mca.x << 5;
int bz = mca.z << 5;
for (int x = 0; x < 32; x++) {
for (int z = 0; z < 32; z++) {
long pair = MathMan.pairInt(bx + x, bz + z);
chunks.put(pair, PRESENT);
}
}
}
for (Plot plot : plots) {
removeChunks(plot);
}
}
originalQueue.filterWorld(new MCAFilter() {
@Override
public boolean appliesFile(int mcaX, int mcaZ) {
ChunkLoc loc = new ChunkLoc(mcaX, mcaZ);
return !mcas.contains(loc);
}
@Override
public MCAFile applyFile(MCAFile mca) {
int mcaX = mca.getX();
int mcaZ = mca.getZ();
ChunkLoc loc = new ChunkLoc(mcaX, mcaZ);
if (mcas.contains(loc)) {
player.sendMessage("Delete MCA " + mca);
mca.setDeleted(true);
return null;
}
try {
File copy = new File(root, mca.getFile().getName());
if (!copy.exists()) {
copy = MainUtil.copyFile(mca.getFile(), copy);
player.sendMessage("Filter copy -> " + copy);
} else {
player.sendMessage("Filter existing: " + mcaX + "," + mcaZ);
}
return new MCAFile(mca.getParent(), copy);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
public MCAChunk applyChunk(MCAChunk chunk, Object ignore) {
long pair = MathMan.pairInt(chunk.getX(), chunk.getZ());
if (chunks.containsKey(pair)) {
chunk.setDeleted(true);
return null;
}
if (ids != null) {
for (int i = 0; i < ids.length; i++) {
if (!isEqual(ids[i], chunk.ids[i])) {
return null;
}
}
chunk.setDeleted(true);
}
return null;
}
});
player.sendMessage("Done!");
}
private boolean isEqual(int[] a, int[] b) {
if (a == b) {
return true;
}
if (a != null) {
if (b != null) {
return Arrays.equals(a, b);
}
return isEmpty(a);
}
return isEmpty(b);
}
private boolean isEmpty(int[] a) {
for (int b : a) {
if (!BlockTypes.getFromStateId(b).getMaterial().isAir()) {
return false;
}
}
return true;
}
}

View File

@ -21,6 +21,9 @@ package com.boydti.fawe.util;
import com.boydti.fawe.command.AnvilCommands;
import com.boydti.fawe.command.CFICommands;
import com.sk89q.minecraft.util.commands.Step;
import com.sk89q.worldedit.command.ToolUtilCommands;
import com.sk89q.worldedit.internal.annotation.Range;
import org.enginehub.piston.annotation.Command;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.minecraft.util.commands.NestedCommand;
@ -33,7 +36,6 @@ import com.sk89q.worldedit.command.GenerationCommands;
import com.sk89q.worldedit.command.HistoryCommands;
import com.sk89q.worldedit.command.MaskCommands;
import com.sk89q.worldedit.command.NavigationCommands;
import com.sk89q.worldedit.command.OptionsCommands;
import com.sk89q.worldedit.command.PatternCommands;
import com.sk89q.worldedit.command.RegionCommands;
import com.sk89q.worldedit.command.SchematicCommands;
@ -46,10 +48,19 @@ import com.sk89q.worldedit.command.ToolCommands;
import com.sk89q.worldedit.command.TransformCommands;
import com.sk89q.worldedit.command.UtilityCommands;
import com.sk89q.worldedit.command.WorldEditCommands;
import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@SuppressWarnings("UseOfSystemOutOrSystemErr")
public final class DocumentationPrinter {
@ -113,7 +124,7 @@ public final class DocumentationPrinter {
writePermissionsWikiTable(stream, builder, "/", SnapshotUtilCommands.class);
writePermissionsWikiTable(stream, builder, "/", ScriptingCommands.class);
writePermissionsWikiTable(stream, builder, "/", ChunkCommands.class);
writePermissionsWikiTable(stream, builder, "/", OptionsCommands.class);
writePermissionsWikiTable(stream, builder, "/", ToolUtilCommands.class);
writePermissionsWikiTable(stream, builder, "/", BrushOptionsCommands.class);
writePermissionsWikiTable(stream, builder, "/tool ", ToolCommands.class);
writePermissionsWikiTable(stream, builder, "/brush ", BrushCommands.class);
@ -153,7 +164,6 @@ public final class DocumentationPrinter {
}
private static void writePermissionsWikiTable(StringBuilder stream, String prefix, Class<?> cls, String name, boolean title) {
// //setbiome || worldedit.biome.set || //setbiome || p || Sets the biome of the player's current block or region.
if (title) {
String path = "https://github.com/boy0001/FastAsyncWorldedit/edit/master/core/src/main/java/" + cls.getName().replaceAll("\\.", "/") + ".java";
stream.append("### **" + name + "** `[`[`edit`](" + path + ")`|`[`top`](#overview)`]`");
@ -163,8 +173,8 @@ public final class DocumentationPrinter {
if (!cmd.desc().isEmpty()) {
stream.append("> (" + (cmd.desc()) + ") \n");
}
if (!cmd.help().isEmpty()) {
stream.append("" + (cmd.help()) + " \n");
if (!cmd.descFooter().isEmpty()) {
stream.append("" + (cmd.descFooter()) + " \n");
}
}
stream.append("\n");
@ -176,22 +186,16 @@ public final class DocumentationPrinter {
if (!method.isAnnotationPresent(Command.class)) {
continue;
}
Command cmd = method.getAnnotation(Command.class);
String[] aliases = cmd.aliases();
String usage = prefix + aliases[0] + " " + cmd.usage();
if (!cmd.flags().isEmpty()) {
for (char c : cmd.flags().toCharArray()) {
usage += " [-" + c + "]";
}
}
// stream.append("#### [`" + usage + "`](" + "https://github.com/boy0001/FastAsyncWorldedit/wiki/" + aliases[0] + ")\n");
String usage = prefix + aliases[0] + " " + getUsage(cmd, method);
stream.append("#### `" + usage + "`\n");
if (method.isAnnotationPresent(CommandPermissions.class)) {
CommandPermissions perms = method.getAnnotation(CommandPermissions.class);
stream.append("**Perm**: `" + StringMan.join(perms.value(), "`, `") + "` \n");
}
String help = cmd.help() == null || cmd.help().isEmpty() ? cmd.desc() : cmd.help();
String help = getDesc(cmd, method);
stream.append("**Desc**: " + help.trim().replaceAll("\n", "<br />") + " \n");
if (method.isAnnotationPresent(NestedCommand.class)) {
@ -209,4 +213,78 @@ public final class DocumentationPrinter {
stream.append("\n");
stream.append("\n");
}
public static String getDesc(Command command, Method method) {
Parameter[] params = method.getParameters();
List<String> desc = new ArrayList<>();
for (Parameter param : params) {
String[] info = getParamInfo(param);
if (info != null) {
desc.add(info[0].replace("%s0", info[1]) + " - " + info[2] + ": " + info[3]);
}
}
String footer = command.descFooter();
if (!footer.isEmpty()) footer += "\n";
return footer + StringMan.join(desc, "\n");
}
public static String getUsage(Command command, Method method) {
Parameter[] params = method.getParameters();
List<String> usage = new ArrayList<>();
for (Parameter param : params) {
String[] info = getParamInfo(param);
if (info != null) {
usage.add(info[0].replace("%s0", info[1]));
}
}
return StringMan.join(usage, " ");
}
/*
Return format, name, type, description
*/
public static String[] getParamInfo(Parameter param) {
Switch switchAnn = param.getAnnotation(Switch.class);
Arg argAnn = param.getAnnotation(Arg.class);
Range rangeAnn = param.getAnnotation(Range.class);
Step stepAnn = param.getAnnotation(Step.class);
if (switchAnn != null || argAnn != null || rangeAnn != null || stepAnn != null) {
String[] result = new String[] { "[%s0]", param.getName(), param.getType().getSimpleName(), ""};
boolean optional = argAnn != null && argAnn.def().length != 0;
if (optional) {
result[0] = "<%s0>";
}
if (argAnn != null) result[1] = argAnn.name();
if (argAnn != null) {
if (argAnn.def().length != 0) {
result[0] = result[0].replace("%s0", "%s0=" + argAnn.def());
}
result[3] = argAnn.desc();
} else if (switchAnn != null) {
result[0] = result[0].replace("%s0", "-" + switchAnn.name() + " %s0");
}
if (switchAnn != null) result[3] = switchAnn.desc();
if (rangeAnn != null) {
String step;
String min = rangeAnn.min() == Double.MIN_VALUE ? "(-∞" : ("[" + rangeAnn.min());
String max = rangeAnn.max() == Double.MAX_VALUE ? "∞)" : (rangeAnn.max() + "]");
result[0] += min + "," + max;
}
if (stepAnn != null) {
result[0] += "" + stepAnn.value();
}
return result;
}
return null;
}
public static Collection<ArgFlag> getFlags(Command command, Method method) {
Parameter[] params = method.getParameters();
List<ArgFlag> flags = new ArrayList<>();
for (Parameter param : params) {
ArgFlag flagAnn = param.getAnnotation(ArgFlag.class);
if (flagAnn != null) flags.add(flagAnn);
}
return flags;
}
}

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.util;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.implementation.QueueHandler;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.object.RunnableVal;
@ -10,7 +11,9 @@ import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
@ -138,7 +141,8 @@ public abstract class TaskManager {
* @param queue
* @param run
*/
public void runUnsafe(IQueueExtent queue, Runnable run) {
public void runUnsafe(Runnable run) {
QueueHandler queue = Fawe.get().getQueueHandler();
queue.startSet(true);
try {
run.run();
@ -254,23 +258,6 @@ public abstract class TaskManager {
});
}
/**
* Quickly run a task on the main thread, and wait for execution to finish:<br>
* - Useful if you need to access something from the Bukkit API from another thread<br>
* - Usualy wait time is around 25ms<br>
*
* @param function
* @param <T>
* @return
*/
public <T> T sync(final RunnableVal<T> function) {
return sync(function, Integer.MAX_VALUE);
}
public <T> T sync(final Supplier<T> function) {
return sync(function, Integer.MAX_VALUE);
}
public void wait(AtomicBoolean running, int timout) {
try {
long start = System.currentTimeMillis();
@ -295,15 +282,11 @@ public abstract class TaskManager {
}
}
public <T> T syncWhenFree(@NotNull final RunnableVal<T> function) {
return syncWhenFree(function, Integer.MAX_VALUE);
}
public void taskWhenFree(@NotNull Runnable run) {
if (Fawe.isMainThread()) {
run.run();
} else {
SetQueue.IMP.addTask(run);
Fawe.get().getQueueHandler().sync(run);
}
}
@ -317,43 +300,16 @@ public abstract class TaskManager {
* @param <T>
* @return
*/
public <T> T syncWhenFree(@NotNull final RunnableVal<T> function, int timeout) {
public <T> T syncWhenFree(@NotNull final RunnableVal<T> function) {
if (Fawe.isMainThread()) {
function.run();
return function.value;
}
final AtomicBoolean running = new AtomicBoolean(true);
RunnableVal<RuntimeException> run = new RunnableVal<RuntimeException>() {
@Override
public void run(RuntimeException value) {
try {
function.run();
} catch (RuntimeException e) {
this.value = e;
} catch (Throwable neverHappens) {
neverHappens.printStackTrace();
} finally {
running.set(false);
return Fawe.get().getQueueHandler().sync((Supplier<T>) function).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
synchronized (function) {
function.notifyAll();
}
}
};
SetQueue.IMP.addTask(run);
try {
synchronized (function) {
while (running.get()) {
function.wait(timeout);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if (run.value != null) {
throw run.value;
}
return function.value;
}
/**
@ -366,45 +322,27 @@ public abstract class TaskManager {
* @param <T>
* @return
*/
public <T> T sync(@NotNull final RunnableVal<T> function, int timeout) {
return sync((Supplier<T>) function, timeout);
public <T> T sync(@NotNull final RunnableVal<T> function) {
return sync((Supplier<T>) function);
}
public <T> T sync(final Supplier<T> function, int timeout) {
/**
* Quickly run a task on the main thread, and wait for execution to finish:<br>
* - Useful if you need to access something from the Bukkit API from another thread<br>
* - Usually wait time is around 25ms<br>
*
* @param function
* @param <T>
* @return
*/
public <T> T sync(final Supplier<T> function) {
if (Fawe.isMainThread()) {
return function.get();
}
final AtomicBoolean running = new AtomicBoolean(true);
RunnableVal<Object> run = new RunnableVal<Object>() {
@Override
public void run(Object value) {
try {
this.value = function.get();
} catch (RuntimeException e) {
this.value = e;
} catch (Throwable neverHappens) {
neverHappens.printStackTrace();
} finally {
running.set(false);
synchronized (function) {
function.notifyAll();
return Fawe.get().getQueueHandler().sync(function).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}
};
SetQueue.IMP.addTask(run);
try {
synchronized (function) {
while (running.get()) {
function.wait(timeout);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if (run.value instanceof RuntimeException) {
throw (RuntimeException) run.value;
}
return (T) run.value;
}
}

View File

@ -1,156 +0,0 @@
package com.boydti.fawe.util.chat;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Commands;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.StringMan;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.minecraft.util.commands.Link;
import com.sk89q.worldedit.extension.platform.PlatformCommandManager;
import com.sk89q.worldedit.util.command.CommandCallable;
import com.sk89q.worldedit.util.command.CommandMapping;
import com.sk89q.worldedit.util.command.Description;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.Parameter;
import com.sk89q.worldedit.util.command.PrimaryAliasComparator;
import com.sk89q.worldedit.internal.annotation.Range;
import com.sk89q.worldedit.util.command.parametric.ParameterData;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public class UsageMessage extends Message {
/**
* Create a new usage box.
*
* @param command the command to describe
* @param commandString the command that was used, such as "/we" or "/brush sphere"
*/
public UsageMessage(CommandCallable command, String commandString) {
this(command, commandString, null);
}
/**
* Create a new usage box.
*
* @param command the command to describe
* @param commandString the command that was used, such as "/we" or "/brush sphere"
* @param locals list of locals to use
*/
public UsageMessage(CommandCallable command, String commandString, @Nullable CommandLocals locals) {
checkNotNull(command);
checkNotNull(commandString);
if (command instanceof Dispatcher) {
attachDispatcherUsage((Dispatcher) command, commandString, locals);
} else {
attachCommandUsage(command.getDescription(), commandString);
}
}
private void attachDispatcherUsage(Dispatcher dispatcher, String commandString, @Nullable CommandLocals locals) {
prefix();
text(BBC.HELP_HEADER_SUBCOMMANDS.f());
String prefix = !commandString.isEmpty() ? commandString + " " : "";
List<CommandMapping> list = new ArrayList<>(dispatcher.getCommands());
list.sort(new PrimaryAliasComparator(PlatformCommandManager.COMMAND_CLEAN_PATTERN));
for (CommandMapping mapping : list) {
boolean perm = locals == null || mapping.getCallable().testPermission(locals);
newline();
String cmd = prefix + mapping.getPrimaryAlias();
text((perm ? BBC.HELP_ITEM_ALLOWED : BBC.HELP_ITEM_DENIED).format(cmd, mapping.getDescription().getDescription()));
command(cmd);
}
}
protected String separateArg(String arg) {
return " " + arg;
}
private void attachCommandUsage(Description description, String commandString) {
List<Parameter> params = description.getParameters();
String[] usage;
if (description.getUsage() != null) {
usage = description.getUsage().split(" ", params.size());
} else {
usage = new String[params.size()];
for (int i = 0; i < usage.length; i++) {
Parameter param = params.get(i);
boolean optional = param.isValueFlag() || param.isOptional();
String arg;
if (param.getFlag() != null) {
arg = "-" + param.getFlag();
if (param.isValueFlag())
arg += param.getName();
} else {
arg = param.getName();
if (param.getDefaultValue() != null && param.getDefaultValue().length > 0)
arg += "=" + StringMan.join(param.getDefaultValue(), ",");
}
usage[i] = optional ? ("[" + arg + "]") : ("<" + arg + ">");
}
}
prefix();
text("&cUsage: ");
text("&7" + commandString);
suggestTip(commandString + " ");
for (int i = 0; i < usage.length; i++) {
String argStr = usage[i];
text(separateArg(argStr.replaceAll("[\\[|\\]|<|>]", "&0$0&7")));
if (params.isEmpty()) continue;
Parameter param = params.get(i);
StringBuilder tooltip = new StringBuilder();
String command = null;
tooltip.append("Name: " + param.getName());
if (param instanceof ParameterData) {
ParameterData pd = (ParameterData) param;
Type type = pd.getType();
if (type instanceof Class) {
tooltip.append("\nType: " + ((Class) type).getSimpleName());
}
Range range = MainUtil.getOf(pd.getModifiers(), Range.class);
if (range != null) {
String min = range.min() == Double.MIN_VALUE ? "(-∞" : ("[" + range.min());
String max = range.max() == Double.MAX_VALUE ? "∞)" : (range.max() + "]");
tooltip.append("\nRange: " + min + "," + max);
}
if (type instanceof Class) {
Link link = (Link) ((Class) type).getAnnotation(Link.class);
if (link != null) {
command = Commands.getAlias(link.clazz(), link.value());
}
}
}
tooltip.append("\nOptional: " + (param.isOptional() || param.isValueFlag()));
if (param.getDefaultValue() != null) {
tooltip.append("\nDefault: " + param.getDefaultValue()[0]);
} else if (argStr.contains("=")) {
tooltip.append("\nDefault: " + argStr.split("[=|\\]|>]")[1]);
}
if (command != null) {
tooltip.append("\nClick for more info");
}
tooltip(tooltip.toString());
if (command != null) command(command);
}
newline();
if (description.getHelp() != null) {
text("&cHelp: &7" + description.getHelp());
} else if (description.getDescription() != null) {
text("&cDescription: &7" + description.getDescription());
} else {
text("No further help is available.");
}
}
}

View File

@ -2,9 +2,9 @@ package com.boydti.fawe.util.task;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.QueueHandler;
import com.boydti.fawe.object.Metadatable;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager;
import java.util.ArrayDeque;
import java.util.ArrayList;
@ -430,7 +430,7 @@ public class TaskBuilder extends Metadatable {
public static abstract class SplitTask extends RunnableTask {
private final long allocation;
private final IQueueExtent queue;
private final QueueHandler queue;
private long last;
private long start;
private Object asyncWaitLock = new Object();
@ -447,7 +447,7 @@ public class TaskBuilder extends Metadatable {
public SplitTask(long allocation) {
super(TaskType.SYNC_WHEN_FREE);
this.allocation = allocation;
this.queue = SetQueue.IMP.getNewQueue((String) null, true, false);
this.queue = Fawe.get().getQueueHandler();
}
public Object execSplit(final Object previous) {

View File

@ -489,7 +489,7 @@ public abstract class CommandsManager<T> {
newFlags.add(flags[i]);
}
InjectedValueAccess context = new InjectedValueAccess(newArgs, valueFlags);
CommandContext context = new CommandContext(newArgs, valueFlags);
if (context.argsLength() < cmd.min()) {
throw new CommandUsageException("Too few arguments.", getUsage(args, level, cmd));

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,99 +81,7 @@ 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(
@ -182,10 +90,11 @@ public class ScriptingCommands {
)
@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,16 +104,9 @@ 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(

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());
}