Merge remote-tracking branch 'upstream/master' into merge

This commit is contained in:
Jesse Boyd
2019-11-19 21:23:47 +00:00
272 changed files with 16041 additions and 6107 deletions

View File

@ -27,6 +27,7 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.entity.Player;
@ -81,6 +82,7 @@ public class BiomeCommands {
public void biomeList(Actor actor,
@ArgFlag(name = 'p', desc = "Page number.", def = "1")
int page) {
WorldEditAsyncCommandBuilder.createAndSendMessage(actor, () -> {
BiomeRegistry biomeRegistry = WorldEdit.getInstance().getPlatformManager()
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
@ -97,7 +99,8 @@ public class BiomeCommands {
}
})
.collect(Collectors.toList()));
actor.print(paginationBox.create(page));
return paginationBox.create(page);
}, null);
}
@Command(
@ -180,7 +183,8 @@ public class BiomeCommands {
Mask2D mask2d = mask != null ? mask.toMask2D() : null;
if (atPosition) {
region = new CuboidRegion(player.getLocation().toVector().toBlockPoint(), player.getLocation().toVector().toBlockPoint());
final BlockVector3 pos = player.getLocation().toVector().toBlockPoint();
region = new CuboidRegion(pos, pos);
} else {
region = session.getSelection(world);
}

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.command;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
@ -67,6 +65,7 @@ import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.factory.ReplaceFactory;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.command.argument.Arguments;
import com.sk89q.worldedit.command.factory.TreeGeneratorFactory;
@ -127,6 +126,7 @@ import java.nio.file.FileSystems;
import java.util.List;
import java.util.zip.GZIPInputStream;
import org.enginehub.piston.annotation.Command;
import com.sk89q.worldedit.function.factory.Apply;
import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.ArgFlag;
@ -134,6 +134,8 @@ import org.enginehub.piston.annotation.param.Switch;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Commands to set brush shape.
*/
@ -152,6 +154,15 @@ public class BrushCommands {
this.worldEdit = worldEdit;
}
@Command(
name = "none",
aliases = "unbind",
desc = "Unbind a bound brush from your current item"
)
void none(Player player, LocalSession session) throws WorldEditException {
ToolCommands.setToolNone(player, session, "Brush");
}
@Command(
name = "blendball",
aliases = {"bb", "blend"},
@ -644,18 +655,18 @@ public class BrushCommands {
)
@Deprecated
@CommandPermissions("worldedit.brush.clipboard")
public void clipboardBrush(LocalSession session, InjectedValueAccess context,
@Switch(name = 'a', desc = "Don't paste air from the clipboard")
boolean ignoreAir,
@Switch(name = 'o', desc = "Paste starting at the target location, instead of centering on it")
boolean usingOrigin,
@Switch(name = 'e', desc = "Skip paste entities if available")
boolean skipEntities,
@Switch(name = 'b', desc = "Paste biomes if available")
boolean pasteBiomes,
@ArgFlag(name = 'm', desc = "Skip blocks matching this mask in the clipboard", def = "")
@ClipboardMask
Mask sourceMask) throws WorldEditException {
public void clipboardBrush(Player player, LocalSession session,
@Switch(name = 'a', desc = "Don't paste air from the clipboard")
boolean ignoreAir,
@Switch(name = 'o', desc = "Paste starting at the target location, instead of centering on it")
boolean usingOrigin,
@Switch(name = 'e', desc = "Paste entities if available")
boolean pasteEntities,
@Switch(name = 'b', desc = "Paste biomes if available")
boolean pasteBiomes,
@ArgFlag(name = 'm', desc = "Skip blocks matching this mask in the clipboard", def = "")
@ClipboardMask
Mask sourceMask) throws WorldEditException {
ClipboardHolder holder = session.getClipboard();
Clipboard clipboard = holder.getClipboard();
@ -678,13 +689,13 @@ public class BrushCommands {
descFooter = "Example: '/brush smooth 2 4 grass_block,dirt,stone'"
)
@CommandPermissions("worldedit.brush.smooth")
public void smoothBrush(Player player, InjectedValueAccess context, EditSession editSession,
@Arg(desc = "The radius to sample for softening", def = "2")
Expression radius,
@Arg(desc = "The number of iterations to perform", def = "4")
int iterations,
@Arg(desc = "The mask of blocks to use for the heightmap", def = "")
Mask maskOpt) throws WorldEditException {
public void smoothBrush(Player player, LocalSession session,
@Arg(desc = "The radius to sample for softening", def = "2")
Expression radius,
@Arg(desc = "The number of iterations to perform", def = "4")
int iterations,
@Arg(desc = "The mask of blocks to use for the heightmap", def = "")
Mask maskOpt) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
FaweLimit limit = Settings.IMP.getLimit(player);
@ -1089,4 +1100,106 @@ public class BrushCommands {
player.print("Set brush to " + factory);
}
@Command(
name = "deform",
desc = "Deform brush, applies an expression to an area"
)
@CommandPermissions("worldedit.brush.deform")
public void deform(Player player, LocalSession localSession,
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
double radius,
@Arg(desc = "Expression to apply", def = "y-=0.2")
String expression,
@Switch(name = 'r', desc = "Use the game's coordinate origin")
boolean useRawCoords,
@Switch(name = 'o', desc = "Use the placement position as the origin")
boolean usePlacement) throws WorldEditException {
Deform deform = new Deform(expression);
if (useRawCoords) {
deform.setMode(Deform.Mode.RAW_COORD);
} else if (usePlacement) {
deform.setMode(Deform.Mode.OFFSET);
deform.setOffset(localSession.getPlacementPosition(player).toVector3());
}
setOperationBasedBrush(player, localSession, radius,
deform, shape, "worldedit.brush.deform");
}
@Command(
name = "set",
desc = "Set brush, sets all blocks in the area"
)
@CommandPermissions("worldedit.brush.set")
public void set(Player player, LocalSession localSession,
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
double radius,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern) throws WorldEditException {
setOperationBasedBrush(player, localSession, radius,
new Apply(new ReplaceFactory(pattern)), shape, "worldedit.brush.set");
}
@Command(
name = "forest",
desc = "Forest brush, creates a forest in the area"
)
@CommandPermissions("worldedit.brush.forest")
public void forest(Player player, LocalSession localSession,
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
double radius,
@Arg(desc = "The density of the brush", def = "20")
double density,
@Arg(desc = "The type of tree to use")
TreeGenerator.TreeType type) throws WorldEditException {
setOperationBasedBrush(player, localSession, radius,
new Paint(new TreeGeneratorFactory(type), density / 100), shape, "worldedit.brush.forest");
}
@Command(
name = "raise",
desc = "Raise brush, raise all blocks by one"
)
@CommandPermissions("worldedit.brush.raise")
public void raise(Player player, LocalSession localSession,
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
double radius) throws WorldEditException {
setOperationBasedBrush(player, localSession, radius,
new Deform("y-=1"), shape, "worldedit.brush.raise");
}
@Command(
name = "lower",
desc = "Lower brush, lower all blocks by one"
)
@CommandPermissions("worldedit.brush.lower")
public void lower(Player player, LocalSession localSession,
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
double radius) throws WorldEditException {
setOperationBasedBrush(player, localSession, radius,
new Deform("y+=1"), shape, "worldedit.brush.lower");
}
static void setOperationBasedBrush(Player player, LocalSession session, double radius,
Contextual<? extends Operation> factory,
RegionFactory shape,
String permission) throws WorldEditException {
WorldEdit.getInstance().checkMaxBrushRadius(radius);
BrushTool tool = session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
tool.setSize(radius);
tool.setFill(null);
tool.setBrush(new OperationFactoryBrush(factory, shape, session), permission);
player.print("Set brush to " + factory);
}
}

View File

@ -18,8 +18,6 @@
*/
package com.sk89q.worldedit.command;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
@ -39,6 +37,7 @@ import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
@ -46,9 +45,10 @@ import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.storage.LegacyChunkStore;
import com.sk89q.worldedit.world.storage.McRegionChunkStore;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.io.File;
import java.nio.file.Path;
import java.time.ZonedDateTime;
import java.util.ArrayList;
@ -59,6 +59,8 @@ import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.exception.StopExecutionException;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Commands for working with chunks.
*/

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.command;
import com.google.common.collect.Lists;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.BBC;
@ -37,12 +39,10 @@ import com.boydti.fawe.util.MaskTraverser;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.extent.PasteEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.Extent;
@ -53,6 +53,8 @@ import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.function.block.BlockReplace;
import static com.sk89q.worldedit.command.util.Logging.LogMode.PLACEMENT;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
@ -91,11 +93,10 @@ import java.util.Set;
import java.util.function.Supplier;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.command.util.Logging.LogMode.PLACEMENT;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import java.util.List;
/**
* Clipboard commands.
@ -103,18 +104,6 @@ import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class ClipboardCommands {
private WorldEdit worldEdit;
/**
* Create a new instance.
*
* @param worldEdit reference to WorldEdit
*/
public ClipboardCommands(WorldEdit worldEdit) {
checkNotNull(worldEdit);
this.worldEdit = worldEdit;
}
@Command(
name = "/copy",
@ -442,6 +431,8 @@ public class ClipboardCommands {
boolean atOrigin,
@Switch(name = 's', desc = "Select the region after pasting")
boolean selectPasted,
@Switch(name = 'n', desc = "No paste, select only. (Implies -s)")
boolean onlySelect,
@Switch(name = 'e', desc = "Paste entities if available")
boolean pasteEntities,
@Switch(name = 'b', desc = "Paste biomes if available")
@ -457,6 +448,7 @@ public class ClipboardCommands {
}
Clipboard clipboard = holder.getClipboard();
Region region = clipboard.getRegion();
List<String> messages = Lists.newArrayList();
BlockVector3 to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(actor);
checkPaste(actor, editSession, to, holder, clipboard);
@ -471,7 +463,7 @@ public class ClipboardCommands {
.build();
Operations.completeLegacy(operation);
if (selectPasted) {
if (selectPasted || onlySelect) {
BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
Vector3 realTo = to.toVector3().add(holder.getTransform().apply(clipboardOffset.toVector3()));
Vector3 max = realTo.add(holder.getTransform().apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3()));
@ -578,7 +570,7 @@ public class ClipboardCommands {
AffineTransform transform = new AffineTransform();
transform = transform.scale(direction.abs().multiply(-2).add(1, 1, 1).toVector3());
holder.setTransform(holder.getTransform().combine(transform));
actor.print(BBC.COMMAND_FLIPPED.s());
actor.print("The clipboard copy has been flipped.");
}
@Command(
@ -588,6 +580,6 @@ public class ClipboardCommands {
@CommandPermissions("worldedit.clipboard.clear")
public void clearClipboard(Actor actor, LocalSession session) throws WorldEditException {
session.setClipboard(null);
actor.print(BBC.CLIPBOARD_CLEARED.s());
actor.print("Clipboard cleared.");
}
}

View File

@ -19,9 +19,6 @@
package com.sk89q.worldedit.command;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import static com.sk89q.worldedit.internal.command.CommandUtil.requireIV;
import com.google.common.collect.ImmutableSet;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
@ -39,7 +36,6 @@ import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.World;
import java.util.List;
import org.enginehub.piston.Command;
import org.enginehub.piston.CommandManager;
import org.enginehub.piston.CommandManagerService;
@ -48,6 +44,11 @@ import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.inject.Key;
import org.enginehub.piston.part.SubCommandPart;
import java.util.List;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import static com.sk89q.worldedit.internal.command.CommandUtil.requireIV;
/**
* Extracted from {@link SelectionCommands} to allow importing of {@link Command}.
*/

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.command;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.extent.ResettableExtent;
@ -44,6 +42,8 @@ import com.sk89q.worldedit.extension.input.DisallowedUsageException;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import java.util.ArrayList;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.function.mask.Mask;
@ -52,7 +52,6 @@ import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.item.ItemType;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -64,6 +63,8 @@ import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* General WorldEdit commands.
*/
@ -132,8 +133,8 @@ public class GeneralCommands {
}
@Command(
name = "/fast",
desc = "Toggle fast mode"
name = "/fast",
desc = "Toggle fast mode"
)
@CommandPermissions("worldedit.fast")
public void fast(Actor actor, LocalSession session,
@ -144,12 +145,13 @@ public class GeneralCommands {
actor.printError("Fast mode already " + (fastMode ? "enabled" : "disabled") + ".");
return;
}
if (hasFastMode) {
session.setFastMode(false);
actor.print(BBC.FAST_DISABLED.s());
actor.print("Fast mode disabled.");
} else {
session.setFastMode(true);
actor.print(BBC.FAST_ENABLED.s());
actor.print("Fast mode enabled. Lighting in the affected chunks may be wrong and/or you may need to rejoin to see changes.");
}
}
@ -196,20 +198,20 @@ public class GeneralCommands {
}
}
// @Command(
// name = "/world",
// desc = "Sets the world override"
// )
// @CommandPermissions("worldedit.world")
// public void worldOverride(Actor actor, LocalSession session,
// @Arg(desc = "The world override", def = "") World world) {
// session.setWorldOverride(world);
// if (world == null) {
// actor.print("Removed world override.");
// } else {
// actor.print("Set the world override to " + world.getId() + ". (Use //world to go back to default)");
// }
// }
@Command(
name = "/world",
desc = "Sets the world override"
)
@CommandPermissions("worldedit.world")
public void world(Actor actor, LocalSession session,
@Arg(desc = "The world override", def = "") World world) {
session.setWorldOverride(world);
if (world == null) {
actor.print("Removed world override.");
} else {
actor.print("Set the world override to " + world.getId() + ". (Use //world to go back to default)");
}
}
@Command(
name = "/watchdog",
@ -237,16 +239,18 @@ public class GeneralCommands {
@Command(
name = "gmask",
aliases = {"/gmask"},
descFooter = "The global destination mask applies to all edits you do and masks based on the destination blocks (i.e., the blocks in the world).",
desc = "Set the global mask"
)
@CommandPermissions({"worldedit.global-mask", "worldedit.mask.global"})
public void gmask(Actor actor, LocalSession session, @Arg(desc = "The mask to set", def = "") Mask mask) {
session.setMask(mask);
@CommandPermissions("worldedit.global-mask")
public void gmask(Actor actor, LocalSession session,
@Arg(desc = "The mask to set", def = "")
Mask mask) {
if (mask == null) {
actor.print(BBC.MASK_DISABLED.s());
session.setMask(null);
actor.print("Global mask disabled.");
} else {
actor.print(BBC.MASK.s());
session.setMask(mask);
actor.print("Global mask set.");
}
}
@ -291,7 +295,7 @@ public class GeneralCommands {
actor.print(new ItemSearcher(search, blocksOnly, itemsOnly, page).call());
}
public static class ItemSearcher implements Callable<Component> {
private static class ItemSearcher implements Callable<Component> {
private final boolean blocksOnly;
private final boolean itemsOnly;
private final String search;

View File

@ -18,8 +18,6 @@
*/
package com.sk89q.worldedit.command;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.command.MethodCommands.getArguments;
import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL;
import static com.sk89q.worldedit.command.util.Logging.LogMode.PLACEMENT;
@ -42,10 +40,13 @@ import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.function.generator.CavesGen;
import java.util.List;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.internal.annotation.Radii;
import com.sk89q.worldedit.internal.annotation.Range;
import com.sk89q.worldedit.internal.annotation.Selection;
import com.sk89q.worldedit.internal.expression.ExpressionException;
@ -61,11 +62,12 @@ import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.Switch;
import static com.google.common.base.Preconditions.checkNotNull;
import org.enginehub.piston.inject.InjectedValueAccess;
/**
@ -184,20 +186,15 @@ public class GenerationCommands {
)
@CommandPermissions("worldedit.generation.cylinder")
@Logging(PLACEMENT)
public void hcyl(Actor actor, LocalSession session, EditSession editSession,
public int hcyl(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to generate")
Pattern pattern,
@Arg(desc = "The radii of the cylinder. Order is N/S, E/W") BlockVector2 radius,
Pattern pattern,
@Arg(desc = "The radii of the cylinder. 1st is N/S, 2nd is E/W")
@Radii(2)
List<Double> radii,
@Arg(desc = "The height of the cylinder", def = "1")
int height,
@Range(min = 1) @Arg(desc = "double", def = "1") double thickness, InjectedValueAccess context) throws WorldEditException {
double max = MathMan.max(radius.getBlockX(), radius.getBlockZ());
worldEdit.checkMaxRadius(max);
BlockVector3 pos = session.getPlacementPosition(actor);
actor.checkConfirmationRadius(() -> {
int affected = editSession.makeHollowCylinder(pos, pattern, radius.getX(), radius.getZ(), Math.min(256, height), thickness - 1);
BBC.VISITOR_BLOCK.send(actor, affected);
}, "/hcyl", (int) max, context);
int height) throws WorldEditException {
return cyl(actor, session, editSession, pattern, radii, height, true);
}
@Command(
@ -278,9 +275,10 @@ public class GenerationCommands {
int size,
@Arg(desc = "The type of forest", def = "tree")
TreeType type,
@Range(min = 0, max = 100) @Arg(desc = "The density of the forest, between 0 and 100", def = "5")
@Arg(desc = "The density of the forest, between 0 and 100", def = "5")
double density) throws WorldEditException {
checkCommandArgument(0 <= density && density <= 100, "Density must be between 0 and 100");
worldEdit.checkMaxRadius(size);
density /= 100;
int affected = editSession.makeForest(session.getPlacementPosition(actor), size, density, type);
actor.print(affected + " trees created.");
@ -295,14 +293,10 @@ public class GenerationCommands {
@Logging(POSITION)
public int pumpkins(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The size of the patch", def = "10")
int size,
@Arg(desc = "//TODO", def = "10")
int apothem,
@Arg(desc = "//TODO ", def = "0.02")
double density) throws WorldEditException {
checkCommandArgument(0 <= density && density <= 100, "Density must be between 0 and 100");
int affected = editSession.makePumpkinPatches(session.getPlacementPosition(actor), apothem, density);
BBC.COMMAND_PUMPKIN.send(actor, affected);
int size) throws WorldEditException {
worldEdit.checkMaxRadius(size);
int affected = editSession.makePumpkinPatches(session.getPlacementPosition(actor), size);
actor.print(affected + " pumpkin patches created.");
return affected;
}

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.command;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.config.BBC;
@ -57,6 +55,8 @@ import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.Switch;
import org.enginehub.piston.inject.InjectedValueAccess;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Commands to undo, redo, and clear history.
*/
@ -223,6 +223,16 @@ public class HistoryCommands {
aliases = { "/un", "/ud", "undo" },
desc = "Undoes the last action (from history)"
)
} else {
undoSession = session;
}
int finalTimes = times;
player.checkConfirmation(() -> {
EditSession undone = null;
int i = 0;
for (; i < finalTimes; ++i) {
undone = undoSession.undo(undoSession.getBlockBag(player), player);
if (undone == null) break;
@CommandPermissions({"worldedit.history.undo", "worldedit.history.undo.self"})
public void undo(Player player, LocalSession session,
@Range(min = 1) @Arg(desc = "Number of undoes to perform", def = "1")
@ -243,16 +253,6 @@ public class HistoryCommands {
BBC.COMMAND_HISTORY_OTHER_ERROR.send(player, playerName);
return;
}
} else {
undoSession = session;
}
int finalTimes = times;
player.checkConfirmation(() -> {
EditSession undone = null;
int i = 0;
for (; i < finalTimes; ++i) {
undone = undoSession.undo(undoSession.getBlockBag(player), player);
if (undone == null) break;
worldEdit.flushBlockBag(player, undone);
}
if (undone == null) i--;
@ -311,7 +311,7 @@ public class HistoryCommands {
@CommandPermissions("worldedit.history.clear")
public void clearHistory(Actor actor, LocalSession session) {
session.clearHistory();
actor.print(BBC.COMMAND_HISTORY_CLEAR.s());
actor.print("History cleared.");
}
}

View File

@ -18,8 +18,6 @@
*/
package com.sk89q.worldedit.command;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.command.util.Logging.LogMode.POSITION;
import com.boydti.fawe.config.BBC;
@ -36,6 +34,8 @@ import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.Switch;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Commands for moving the player around.
*/
@ -62,7 +62,7 @@ public class NavigationCommands {
@CommandPermissions("worldedit.navigation.unstuck")
public void unstuck(Player player) throws WorldEditException {
player.findFreePosition();
player.print(BBC.UNSTUCK.s());
player.print("There you go!");
}
@Command(
@ -84,11 +84,7 @@ public class NavigationCommands {
if (ascentLevels == 0) {
player.printError(BBC.ASCEND_FAIL.s());
} else {
if (ascentLevels == 1) {
player.print(BBC.ASCENDED_SINGULAR.s());
} else {
BBC.ASCENDED_PLURAL.send(player, ascentLevels);
}
player.print((ascentLevels != 1) ? "Ascended " + ascentLevels + " levels." : "Ascended a level.");
}
}
@ -113,7 +109,7 @@ public class NavigationCommands {
} else if (descentLevels == 1) {
player.print(BBC.DESCEND_SINGULAR.s());
} else {
BBC.DESCEND_PLURAL.send(player, descentLevels);
player.print((descentLevels != 1) ? "Descended " + descentLevels + " levels." : "Descended a level.");
}
}

View File

@ -19,19 +19,23 @@
package com.sk89q.worldedit.command;
import com.google.common.base.Joiner;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.implementation.processors.ChunkSendProcessor;
import com.boydti.fawe.beta.implementation.processors.NullProcessor;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.FaweLimit;
import com.google.common.collect.Lists;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
@ -39,9 +43,11 @@ import com.sk89q.worldedit.function.FlatRegionFunction;
import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.biome.BiomeReplace;
import com.sk89q.worldedit.function.generator.FloraGenerator;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.NoiseFilter2D;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -63,6 +69,8 @@ import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.regions.Regions;
import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.World;
@ -81,10 +89,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.command.MethodCommands.getArguments;
import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL;
import static com.sk89q.worldedit.command.util.Logging.LogMode.ORIENTATION_REGION;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import static com.sk89q.worldedit.internal.command.CommandUtil.checkCommandArgument;
@ -98,16 +103,35 @@ import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class RegionCommands {
private final WorldEdit worldEdit;
/**
* Create a new instance.
*
* @param worldEdit reference to WorldEdit
*/
public RegionCommands(WorldEdit worldEdit) {
checkNotNull(worldEdit);
this.worldEdit = worldEdit;
public RegionCommands() {
}
@Command(
name = "/set",
desc = "Sets all the blocks in the region"
)
@CommandPermissions("worldedit.region.set")
@Logging(REGION)
public int set(Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern) {
RegionFunction set = new BlockReplace(editSession, pattern);
RegionVisitor visitor = new RegionVisitor(region, set);
Operations.completeBlindly(visitor);
List<String> messages = Lists.newArrayList();
visitor.addStatusMessages(messages);
if (messages.isEmpty()) {
actor.print("Operation completed.");
} else {
actor.print("Operation completed (" + Joiner.on(", ").join(messages) + ").");
}
return visitor.getAffected();
}
@Command(
@ -254,7 +278,7 @@ public class RegionCommands {
@Selection Region region,
@Arg(desc = "The pattern of blocks to place")
Pattern pattern,
@Range(min = 1) @Arg(desc = "The thickness of the line", def = "0")
@Arg(desc = "The thickness of the line", def = "0")
int thickness,
@Switch(name = 'h', desc = "Generate only a shell")
boolean shell) throws WorldEditException {
@ -269,7 +293,7 @@ public class RegionCommands {
BlockVector3 pos2 = cuboidregion.getPos2();
int blocksChanged = editSession.drawLine(pattern, pos1, pos2, thickness, !shell);
BBC.VISITOR_BLOCK.send(actor, blocksChanged);
actor.print(blocksChanged + " block(s) have been changed.");
return blocksChanged;
}
@ -290,7 +314,7 @@ public class RegionCommands {
boolean shell, InjectedValueAccess context) throws WorldEditException {
if (!(region instanceof ConvexPolyhedralRegion)) {
actor.printError("//curve only works with convex polyhedral selections");
return;
return 0;
}
checkCommandArgument(thickness >= 0, "Thickness must be >= 0");
@ -300,7 +324,7 @@ public class RegionCommands {
int blocksChanged = editSession.drawSpline(pattern, vectors, 0, 0, 0, 10, thickness, !shell);
BBC.VISITOR_BLOCK.send(actor, blocksChanged);
actor.print(blocksChanged + " block(s) have been changed.");
}, getArguments(context), region, context);
}
@ -321,14 +345,8 @@ public class RegionCommands {
}
Mask finalFrom = from;
actor.checkConfirmationRegion(() -> {
int affected = editSession.replaceBlocks(region, finalFrom, to);
BBC.VISITOR_BLOCK.send(actor, affected);
if (!actor.hasPermission("fawe.tips")) {
BBC.TIP_REPLACE_ID
.or(BBC.TIP_REPLACE_LIGHT, BBC.TIP_REPLACE_MARKER, BBC.TIP_TAB_COMPLETE,
BBC.TIP_REPLACE_REGEX, BBC.TIP_REPLACE_REGEX_2, BBC.TIP_REPLACE_REGEX_3,
BBC.TIP_REPLACE_REGEX_4, BBC.TIP_REPLACE_REGEX_5).send(actor);
}
int affected = editSession.replaceBlocks(region, finalFrom, to);
actor.print(affected + " block(s) have been replaced.");
}, getArguments(context), region, context);
}
@ -342,8 +360,8 @@ public class RegionCommands {
@Arg(desc = "The pattern of blocks to overlay")
Pattern pattern, InjectedValueAccess context) throws WorldEditException {
actor.checkConfirmationRegion(() -> {
int affected = editSession.overlayCuboidBlocks(region, pattern);
BBC.VISITOR_BLOCK.send(actor, affected);
int affected = editSession.overlayCuboidBlocks(region, pattern);
actor.print(affected + " block(s) have been overlaid.");
}, getArguments(context), region, context);
}
@ -380,11 +398,12 @@ public class RegionCommands {
)
@Logging(REGION)
@CommandPermissions("worldedit.region.center")
public void center(Actor actor, EditSession editSession, @Selection Region region,
public int center(Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern) throws WorldEditException {
int affected = editSession.center(region, pattern);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print("Center set (" + affected + " block(s) changed)");
return affected;
}
@Command(
@ -396,7 +415,7 @@ public class RegionCommands {
public void naturalize(Actor actor, EditSession editSession, @Selection Region region, InjectedValueAccess context) throws WorldEditException {
actor.checkConfirmationRegion(() -> {
int affected = editSession.naturalizeCuboidBlocks(region);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been made to look more natural.");
}, getArguments(context), region, context);
}
@ -411,7 +430,7 @@ public class RegionCommands {
Pattern pattern, InjectedValueAccess context) throws WorldEditException {
actor.checkConfirmationRegion(() -> {
int affected = editSession.makeWalls(region, pattern);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been changed.");
}, getArguments(context), region, context);
}
@ -427,7 +446,7 @@ public class RegionCommands {
Pattern pattern, InjectedValueAccess context) throws WorldEditException {
actor.checkConfirmationRegion(() -> {
int affected = editSession.makeCuboidFaces(region, pattern);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been changed.");
}, getArguments(context), region, context);
}
@ -456,7 +475,7 @@ public class RegionCommands {
HeightMap heightMap = new HeightMap(editSession, region, mask, snow);
HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0));
int affected = heightMap.applyFilter(filter, iterations);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print("Terrain's height map smoothed. " + affected + " block(s) changed.");
} catch (Throwable e) {
throw new RuntimeException(e);
}
@ -522,8 +541,20 @@ public class RegionCommands {
boolean copyBiomes,
InjectedValueAccess context) throws WorldEditException {
checkCommandArgument(count >= 1, "Count must be >= 1");
Mask combinedMask;
if (ignoreAirBlocks) {
if (mask == null) {
combinedMask = new ExistingBlockMask(editSession);
} else {
combinedMask = new MaskIntersection(mask, new ExistingBlockMask(editSession));
}
} else {
combinedMask = mask;
}
actor.checkConfirmationRegion(() -> {
int affected = editSession.moveRegion(region, direction, count, !ignoreAirBlocks, !skipEntities, copyBiomes, replace);
int affected = editSession.moveRegion(region, direction, count, !ignoreAirBlocks, !skipEntities, copyBiomes, combinedMask, replace);
if (moveSelection) {
try {
@ -583,17 +614,29 @@ public class RegionCommands {
@ArgFlag(name = 'm', desc = "Source mask", def="")
Mask sourceMask,
InjectedValueAccess context) throws WorldEditException {
Mask combinedMask;
if (ignoreAirBlocks) {
if (mask == null) {
combinedMask = new ExistingBlockMask(editSession);
} else {
combinedMask = new MaskIntersection(mask, new ExistingBlockMask(editSession));
}
} else {
combinedMask = mask;
}
actor.checkConfirmationStack(() -> {
if (sourceMask != null) {
editSession.addSourceMask(sourceMask);
}
int affected = editSession.stackCuboidRegion(region, direction, count, !ignoreAirBlocks, !skipEntities, copyBiomes);
int affected = editSession.stackCuboidRegion(region, direction, count, !skipEntities, copyBiomes, combinedMask);
if (moveSelection) {
try {
final BlockVector3 size = region.getMaximumPoint().subtract(region.getMinimumPoint());
final BlockVector3 size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
final BlockVector3 shiftVector = direction.toVector3().multiply(count * (Math.abs(direction.dot(size)) + 1)).toBlockPoint();
final BlockVector3 shiftVector = direction.multiply(size).multiply(count);
region.shift(shiftVector);
session.getRegionSelector(world).learnChanges();
@ -652,7 +695,7 @@ public class RegionCommands {
if (actor instanceof Player) {
((Player) actor).findFreePosition();
}
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been deformed.");
} catch (ExpressionException e) {
actor.printError(e.getMessage());
}
@ -718,7 +761,7 @@ public class RegionCommands {
Mask finalMask = mask == null ? new SolidBlockMask(editSession) : mask;
actor.checkConfirmationRegion(() -> {
int affected = editSession.hollowOutRegion(region, thickness, pattern, finalMask);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been changed.");
}, getArguments(context), region, context);
}
@ -735,7 +778,7 @@ public class RegionCommands {
double density) throws WorldEditException {
checkCommandArgument(0 <= density && density <= 100, "Density must be in [0, 100]");
int affected = editSession.makeForest(region, density / 100, type);
BBC.COMMAND_TREE.send(actor, affected);
actor.print(affected + " trees created.");
return affected;
}
@ -756,7 +799,7 @@ public class RegionCommands {
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density / 100));
Operations.completeLegacy(visitor);
BBC.COMMAND_FLORA.send(actor, ground.getAffected());
actor.print(affected + " flora created.");
}, "/flora", region, context);
}

View File

@ -20,7 +20,6 @@
package com.sk89q.worldedit.command;
import static com.boydti.fawe.util.ReflectionUtils.as;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.config.BBC;
@ -41,6 +40,7 @@ import com.sk89q.worldedit.command.argument.Arguments;
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.extent.ActorSaveClipboardEvent;
import com.sk89q.worldedit.extension.platform.Actor;
@ -60,6 +60,7 @@ import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.util.formatting.component.CodeFormat;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.util.io.Closer;
import com.sk89q.worldedit.util.io.file.FilenameException;
@ -70,6 +71,8 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import static com.google.common.base.Preconditions.checkArgument;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
@ -843,6 +846,24 @@ public class SchematicCommands {
return fileList;
}
@Command(
name = "delete",
aliases = {"d"},
desc = "Delete a saved schematic"
)
@CommandPermissions("worldedit.schematic.delete")
public void delete(Actor actor,
@Arg(desc = "File name.")
String filename) throws WorldEditException {
LocalConfiguration config = worldEdit.getConfiguration();
File dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
File f = worldEdit.getSafeOpenFile(actor instanceof Player ? ((Player) actor) : null,
dir, filename, "schematic", ClipboardFormats.getFileExtensionArray());
if (!f.exists()) {
actor.printError("Schematic " + filename + " does not exist!");
return;
private boolean delete(File file) {
if (file.delete()) {
new File(file.getParentFile(), "." + file.getName() + ".cached").delete();

View File

@ -18,8 +18,6 @@
*/
package com.sk89q.worldedit.command;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL;
import com.boydti.fawe.config.BBC;
@ -39,6 +37,8 @@ import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.inject.InjectedValueAccess;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Commands related to scripting.
@ -68,8 +68,8 @@ public class ScriptingCommands {
}
@Command(
name = "cs",
desc = "Execute a CraftScript"
name = "cs",
desc = "Execute a CraftScript"
)
@CommandPermissions("worldedit.scripting.execute")
@Logging(ALL)
@ -77,9 +77,9 @@ public class ScriptingCommands {
@Arg(desc = "Filename of the CraftScript to load")
String filename,
@Arg(desc = "Arguments to the CraftScript", def = "", variable = true)
List<String> commandStr) throws WorldEditException {
List<String> args) throws WorldEditException {
if (!player.hasPermission("worldedit.scripting.execute." + filename)) {
player.printError(BBC.SCRIPTING_NO_PERM.s());
player.printError("You don't have permission to use that script.");
return;
}
@ -88,19 +88,19 @@ public class ScriptingCommands {
File dir = worldEdit.getWorkingDirectoryFile(worldEdit.getConfiguration().scriptsDir);
File f = worldEdit.getSafeOpenFile(player, dir, filename, "js", "js");
worldEdit.runScript(player, f, Stream.concat(Stream.of(filename), commandStr.stream())
.toArray(String[]::new));
worldEdit.runScript(player, f, Stream.concat(Stream.of(filename), args.stream())
.toArray(String[]::new));
}
@Command(
name = ".s",
desc = "Execute last CraftScript"
name = ".s",
desc = "Execute last CraftScript"
)
@CommandPermissions("worldedit.scripting.execute")
@Logging(ALL)
public void executeLast(Player player, LocalSession session,
@Arg(desc = "Arguments to the CraftScript", def = "", variable = true)
List<String> commandStr) throws WorldEditException {
List<String> args) throws WorldEditException {
String lastScript = session.getLastScript();
@ -117,7 +117,7 @@ public class ScriptingCommands {
File dir = worldEdit.getWorkingDirectoryFile(worldEdit.getConfiguration().scriptsDir);
File f = worldEdit.getSafeOpenFile(player, dir, lastScript, "js", "js");
worldEdit.runScript(player, f, Stream.concat(Stream.of(lastScript), commandStr.stream())
.toArray(String[]::new));
worldEdit.runScript(player, f, Stream.concat(Stream.of(lastScript), args.stream())
.toArray(String[]::new));
}
}

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.command;
import com.google.common.base.Strings;
import static com.sk89q.worldedit.command.util.Logging.LogMode.POSITION;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
@ -44,6 +46,7 @@ import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.annotation.Direction;
@ -77,12 +80,19 @@ import com.sk89q.worldedit.world.storage.ChunkStore;
import java.io.File;
import java.net.URI;
import java.util.List;
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
import com.sk89q.worldedit.util.formatting.component.InvalidComponentException;
import com.sk89q.worldedit.util.formatting.text.Component;
import java.util.Optional;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import java.util.stream.Stream;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
import com.sk89q.worldedit.world.block.BlockType;
import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.Switch;
import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.exception.StopExecutionException;
/**
* Selection commands.
@ -98,7 +108,6 @@ public class SelectionCommands {
@Command(
name = "/pos1",
aliases = "/1",
desc = "Set position 1"
)
@Logging(POSITION)
@ -116,18 +125,17 @@ public class SelectionCommands {
return;
}
if (!session.getRegionSelector(world).selectPrimary(pos.toBlockPoint(), ActorSelectorLimits.forActor(actor))) {
actor.printError(BBC.SELECTOR_ALREADY_SET.s());
if (!session.getRegionSelector(world).selectPrimary(pos.toVector().toBlockPoint(), ActorSelectorLimits.forActor(actor))) {
actor.printError("Position already set.");
return;
}
session.getRegionSelector(world)
.explainPrimarySelection(actor, session, pos.toBlockPoint());
.explainPrimarySelection(actor, session, pos.toVector().toBlockPoint());
}
@Command(
name = "/pos2",
aliases = "/2",
desc = "Set position 2"
)
@Logging(POSITION)
@ -145,13 +153,13 @@ public class SelectionCommands {
return;
}
if (!session.getRegionSelector(world).selectSecondary(pos.toBlockPoint(), ActorSelectorLimits.forActor(actor))) {
actor.printError(BBC.SELECTOR_ALREADY_SET.s());
if (!session.getRegionSelector(world).selectSecondary(pos.toVector().toBlockPoint(), ActorSelectorLimits.forActor(actor))) {
actor.printError("Position already set.");
return;
}
session.getRegionSelector(world)
.explainSecondarySelection(actor, session, pos.toBlockPoint());
.explainSecondarySelection(actor, session, pos.toVector().toBlockPoint());
}
@Command(
@ -204,7 +212,7 @@ public class SelectionCommands {
)
@Logging(POSITION)
@CommandPermissions("worldedit.selection.chunk")
public void chunk(Player player, LocalSession session,
public void chunk(Actor actor, World world, LocalSession session,
@Arg(desc = "The chunk to select", def = "")
BlockVector2 coordinates,
@Switch(name = 's', desc = "Expand your selection to encompass all chunks that are part of it")
@ -213,7 +221,6 @@ public class SelectionCommands {
boolean useChunkCoordinates) throws WorldEditException {
final BlockVector3 min;
final BlockVector3 max;
final World world = player.getWorld();
if (expandSelection) {
Region region = session.getSelection(world);
@ -223,7 +230,9 @@ public class SelectionCommands {
min = BlockVector3.at(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16);
max = BlockVector3.at(max2D.getBlockX() * 16 + 15, world.getMaxY(), max2D.getBlockZ() * 16 + 15);
BBC.SELECTION_CHUNKS.send(player, min2D.getBlockX() + ", " + min2D.getBlockZ(), max2D.getBlockX() + ", " + max2D.getBlockZ());
actor.print("Chunks selected: ("
+ min2D.getBlockX() + ", " + min2D.getBlockZ() + ") - ("
+ max2D.getBlockX() + ", " + max2D.getBlockZ() + ")");
} else {
final BlockVector2 min2D;
if (coordinates != null) {
@ -233,13 +242,18 @@ public class SelectionCommands {
: ChunkStore.toChunk(coordinates.toBlockVector3());
} else {
// use player loc
min2D = ChunkStore.toChunk(player.getBlockLocation().toBlockPoint());
if (actor instanceof Locatable) {
min2D = ChunkStore.toChunk(((Locatable) actor).getBlockLocation().toVector().toBlockPoint());
} else {
throw new StopExecutionException(TextComponent.of("A player or coordinates are required."));
}
}
min = BlockVector3.at(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16);
max = min.add(15, world.getMaxY(), 15);
BBC.SELECTION_CHUNK.send(player, min2D.getBlockX() + ", " + min2D.getBlockZ());
actor.print("Chunk selected: "
+ min2D.getBlockX() + ", " + min2D.getBlockZ());
}
final CuboidRegionSelector selector;
@ -248,11 +262,11 @@ public class SelectionCommands {
} else {
selector = new CuboidRegionSelector(world);
}
selector.selectPrimary(min, ActorSelectorLimits.forActor(player));
selector.selectSecondary(max, ActorSelectorLimits.forActor(player));
selector.selectPrimary(min, ActorSelectorLimits.forActor(actor));
selector.selectSecondary(max, ActorSelectorLimits.forActor(actor));
session.setRegionSelector(world, selector);
session.dispatchCUISelection(player);
session.dispatchCUISelection(actor);
}
@ -333,8 +347,7 @@ public class SelectionCommands {
session.getRegionSelector(world).explainRegionAdjust(actor, session);
BBC.SELECTION_CONTRACT.send(actor, (oldSize - newSize));
actor.print("Region contracted " + (oldSize - newSize) + " blocks.");
} catch (RegionOperationException e) {
actor.printError(e.getMessage());
}
@ -363,7 +376,7 @@ public class SelectionCommands {
session.getRegionSelector(world).explainRegionAdjust(actor, session);
actor.print(BBC.SELECTION_SHIFT.s());
actor.print("Region shifted.");
} catch (RegionOperationException e) {
actor.printError(e.getMessage());
}
@ -386,7 +399,7 @@ public class SelectionCommands {
region.expand(getChangesForEachDir(amount, onlyHorizontal, onlyVertical));
session.getRegionSelector(world).learnChanges();
session.getRegionSelector(world).explainRegionAdjust(actor, session);
actor.print(BBC.SELECTION_OUTSET.s());
actor.print("Region outset.");
}
@Command(
@ -496,11 +509,11 @@ public class SelectionCommands {
desc = "Counts the number of blocks matching a mask"
)
@CommandPermissions("worldedit.analysis.count")
public void count(Player player, LocalSession session, EditSession editSession,
public void count(Actor actor, World world, LocalSession session, EditSession editSession,
@Arg(desc = "The mask of blocks to match")
Mask mask) throws WorldEditException {
int count = editSession.countBlocks(session.getSelection(player.getWorld()), mask);
BBC.SELECTION_COUNT.send(player, count);
int count = editSession.countBlocks(session.getSelection(world), mask);
actor.print("Counted: " + count);
}
@Command(
@ -531,7 +544,7 @@ public class SelectionCommands {
if (distribution.isEmpty()) { // *Should* always be false
player.printError("No blocks counted.");
actor.printError("No blocks counted.");
return;
}
@ -549,6 +562,65 @@ public class SelectionCommands {
}
}
private static class BlockDistributionResult extends PaginationBox {
private final List<Countable<BlockState>> distribution;
private final int totalBlocks;
private final boolean separateStates;
BlockDistributionResult(List<Countable<BlockState>> distribution, boolean separateStates) {
super("Block Distribution", "//distr -p %page%" + (separateStates ? " -d" : ""));
this.distribution = distribution;
// note: doing things like region.getArea is inaccurate for non-cuboids.
this.totalBlocks = distribution.stream().mapToInt(Countable::getAmount).sum();
this.separateStates = separateStates;
setComponentsPerPage(7);
}
@Override
public Component getComponent(int number) {
Countable<BlockState> c = distribution.get(number);
TextComponent.Builder line = TextComponent.builder();
final int count = c.getAmount();
final double perc = count / (double) totalBlocks * 100;
final int maxDigits = (int) (Math.log10(totalBlocks) + 1);
final int curDigits = (int) (Math.log10(count) + 1);
line.append(String.format("%s%.3f%% ", perc < 10 ? " " : "", perc), TextColor.GOLD);
final int space = maxDigits - curDigits;
String pad = Strings.repeat(" ", space == 0 ? 2 : 2 * space + 1);
line.append(String.format("%s%s", count, pad), TextColor.YELLOW);
final BlockState state = c.getID();
final BlockType blockType = state.getBlockType();
TextComponent blockName = TextComponent.of(blockType.getName(), TextColor.LIGHT_PURPLE);
TextComponent toolTip;
if (separateStates && state != blockType.getDefaultState()) {
toolTip = TextComponent.of(state.getAsString(), TextColor.GRAY);
blockName = blockName.append(TextComponent.of("*", TextColor.LIGHT_PURPLE));
} else {
toolTip = TextComponent.of(blockType.getId(), TextColor.GRAY);
}
blockName = blockName.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, toolTip));
line.append(blockName);
return line.build();
}
@Override
public int getComponentsSize() {
return distribution.size();
}
@Override
public Component create(int page) throws InvalidComponentException {
super.getContents().append(TextComponent.of("Total Block Count: " + totalBlocks, TextColor.GRAY))
.append(TextComponent.newline());
return super.create(page);
}
}
@Command(
name = "/sel",
aliases = { ";", "/desel", "/deselect" },

View File

@ -76,7 +76,7 @@ public class SnapshotCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError(BBC.SNAPSHOT_NOT_CONFIGURED.s());
actor.printError("Snapshot/backup restore is not configured.");
return;
}
@ -86,7 +86,7 @@ public class SnapshotCommands {
if (!snapshots.isEmpty()) {
actor.print(new SnapshotListBox(world.getName(), snapshots).create(page));
} else {
actor.printError(BBC.SNAPSHOT_NOT_AVAILABLE.s());
actor.printError("No snapshots are available. See console for details.");
// Okay, let's toss some debugging information!
File dir = config.snapshotRepo.getDirectory();
@ -101,7 +101,7 @@ public class SnapshotCommands {
}
}
} catch (MissingWorldException ex) {
actor.printError(BBC.SNAPSHOT_NOT_FOUND_WORLD.s());
actor.printError("No snapshots were found for this world.");
}
}
@ -117,7 +117,7 @@ public class SnapshotCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError(BBC.SNAPSHOT_NOT_CONFIGURED.s());
actor.printError("Snapshot/backup restore is not configured.");
return;
}
@ -128,19 +128,19 @@ public class SnapshotCommands {
if (snapshot != null) {
session.setSnapshot(null);
actor.print(BBC.SNAPSHOT_NEWEST.s());
actor.print("Now using newest snapshot.");
} else {
actor.printError(BBC.SNAPSHOT_NOT_FOUND.s());
actor.printError("No snapshots were found.");
}
} catch (MissingWorldException ex) {
actor.printError(BBC.SNAPSHOT_NOT_FOUND_WORLD.s());
actor.printError("No snapshots were found for this world.");
}
} else {
try {
session.setSnapshot(config.snapshotRepo.getSnapshot(name));
BBC.SNAPSHOT_SET.send(actor, name);
actor.print("Snapshot set to: " + name);
} catch (InvalidSnapshotException e) {
actor.printError(BBC.SNAPSHOT_NOT_AVAILABLE.s());
actor.printError("That snapshot does not exist or is not available.");
}
}
}
@ -156,12 +156,12 @@ public class SnapshotCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError(BBC.SNAPSHOT_NOT_CONFIGURED.s());
actor.printError("Snapshot/backup restore is not configured.");
return;
}
if (index < 1) {
actor.printError(BBC.SNAPSHOT_INVALID_INDEX.s());
actor.printError("Invalid index, must be equal or higher then 1.");
return;
}
@ -173,13 +173,13 @@ public class SnapshotCommands {
}
Snapshot snapshot = snapshots.get(index - 1);
if (snapshot == null) {
actor.printError(BBC.SNAPSHOT_NOT_AVAILABLE.s());
actor.printError("That snapshot does not exist or is not available.");
return;
}
session.setSnapshot(snapshot);
BBC.SNAPSHOT_SET.send(actor, snapshot.getName());
actor.print("Snapshot set to: " + snapshot.getName());
} catch (MissingWorldException e) {
actor.printError(BBC.SNAPSHOT_NOT_FOUND_WORLD.s());
actor.printError("No snapshots were found for this world.");
}
}
@ -195,7 +195,7 @@ public class SnapshotCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError(BBC.SNAPSHOT_NOT_CONFIGURED.s());
actor.printError("Snapshot/backup restore is not configured.");
return;
}
@ -207,10 +207,10 @@ public class SnapshotCommands {
+ dateFormat.withZone(session.getTimeZone()).format(date) + ".");
} else {
session.setSnapshot(snapshot);
BBC.SNAPSHOT_SET.send(actor, snapshot.getName());
actor.print("Snapshot set to: " + snapshot.getName());
}
} catch (MissingWorldException ex) {
actor.printError(BBC.SNAPSHOT_NOT_FOUND_WORLD.s());
actor.printError("No snapshots were found for this world.");
}
}
@ -226,7 +226,7 @@ public class SnapshotCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError(BBC.SNAPSHOT_NOT_CONFIGURED.s());
actor.printError("Snapshot/backup restore is not configured.");
return;
}
@ -240,7 +240,7 @@ public class SnapshotCommands {
actor.print("Snapshot set to: " + snapshot.getName());
}
} catch (MissingWorldException ex) {
actor.printError(BBC.SNAPSHOT_NOT_FOUND_WORLD.s());
actor.printError("No snapshots were found for this world.");
}
}

View File

@ -68,7 +68,7 @@ public class SnapshotUtilCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError(BBC.SNAPSHOT_NOT_CONFIGURED.s());
actor.printError("Snapshot/backup restore is not configured.");
return;
}
@ -79,7 +79,7 @@ public class SnapshotUtilCommands {
try {
snapshot = config.snapshotRepo.getSnapshot(snapshotName);
} catch (InvalidSnapshotException e) {
actor.printError(BBC.SNAPSHOT_NOT_AVAILABLE.s());
actor.printError("That snapshot does not exist or is not available.");
return;
}
} else {
@ -92,7 +92,7 @@ public class SnapshotUtilCommands {
snapshot = config.snapshotRepo.getDefaultSnapshot(world.getName());
if (snapshot == null) {
actor.printError(BBC.SNAPSHOT_NOT_AVAILABLE.s());
actor.printError("No snapshots were found. See console for details.");
// Okay, let's toss some debugging information!
File dir = config.snapshotRepo.getDirectory();
@ -109,15 +109,21 @@ public class SnapshotUtilCommands {
return;
}
} catch (MissingWorldException ex) {
actor.printError(BBC.SNAPSHOT_NOT_FOUND_WORLD.s());
actor.printError("No snapshots were found for this world.");
return;
}
}
ChunkStore chunkStore;
// Load chunk store
try (ChunkStore chunkStore = snapshot.getChunkStore()) {
BBC.SNAPSHOT_LOADED.send(actor, snapshot.getName());
try {
chunkStore = snapshot.getChunkStore();
actor.print("Snapshot '" + snapshot.getName() + "' loaded; now restoring...");
} catch (DataException | IOException e) {
actor.printError("Failed to load snapshot: " + e.getMessage());
return;
}
// Restore snapshot
SnapshotRestore restore = new SnapshotRestore(chunkStore, editSession, region);
@ -128,12 +134,12 @@ public class SnapshotUtilCommands {
if (restore.hadTotalFailure()) {
String error = restore.getLastErrorMessage();
if (!restore.getMissingChunks().isEmpty()) {
actor.printError(BBC.SNAPSHOT_ERROR_RESTORE.s());
actor.printError("Chunks were not present in snapshot.");
} else if (error != null) {
actor.printError("Errors prevented any blocks from being restored.");
actor.printError("Last error: " + error);
} else {
actor.printError(BBC.SNAPSHOT_ERROR_RESTORE_CHUNKS.s());
actor.printError("No chunks could be loaded. (Bad archive?)");
}
} else {
actor.print(String.format("Restored; %d "
@ -143,6 +149,6 @@ public class SnapshotUtilCommands {
}
} catch (DataException | IOException e) {
actor.printError("Failed to load snapshot: " + e.getMessage());
}
}
}
}

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.command;
import com.google.common.collect.Collections2;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.brush.InspectBrush;
import com.sk89q.worldedit.LocalConfiguration;
@ -28,6 +30,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.command.tool.BlockDataCyler;
import com.sk89q.worldedit.command.tool.BlockReplacer;
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
import com.sk89q.worldedit.command.tool.DistanceWand;
import com.sk89q.worldedit.command.tool.FloatingTreeRemover;
import com.sk89q.worldedit.command.tool.FloodFillTool;
@ -44,27 +47,95 @@ import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.item.ItemType;
import org.enginehub.piston.annotation.Command;
import com.sk89q.worldedit.internal.command.CommandRegistrationHandler;
import com.sk89q.worldedit.internal.command.CommandUtil;
import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import org.enginehub.piston.CommandManager;
import org.enginehub.piston.CommandManagerService;
import org.enginehub.piston.CommandMetadata;
import org.enginehub.piston.CommandParameters;
import org.enginehub.piston.part.SubCommandPart;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class ToolCommands {
public static void register(CommandRegistrationHandler registration,
CommandManager commandManager,
CommandManagerService commandManagerService,
WorldEdit worldEdit) {
// Collect the tool commands
CommandManager collect = commandManagerService.newCommandManager();
registration.register(
collect,
ToolCommandsRegistration.builder(),
new ToolCommands(worldEdit)
);
// Register deprecated global commands
Set<org.enginehub.piston.Command> commands = collect.getAllCommands()
.collect(Collectors.toSet());
for (org.enginehub.piston.Command command : commands) {
if (command.getAliases().contains("unbind")) {
// Don't register new /tool unbind alias
command = command.toBuilder().aliases(
Collections2.filter(command.getAliases(), alias -> !"unbind".equals(alias))
).build();
}
commandManager.register(CommandUtil.deprecate(
command, "Global tool names cause conflicts " +
"and will be removed in WorldEdit 8", ToolCommands::asNonGlobal
));
}
// Remove aliases with / in them, since it doesn't make sense for sub-commands.
Set<org.enginehub.piston.Command> nonGlobalCommands = commands.stream()
.map(command ->
command.toBuilder().aliases(
Collections2.filter(command.getAliases(), alias -> !alias.startsWith("/"))
).build()
)
.collect(Collectors.toSet());
commandManager.register("tool", command -> {
command.addPart(SubCommandPart.builder(
TranslatableComponent.of("tool"),
TextComponent.of("The tool to bind")
)
.withCommands(nonGlobalCommands)
.required()
.build());
command.description(TextComponent.of("Binds a tool to the item in your hand"));
});
}
private static String asNonGlobal(org.enginehub.piston.Command oldCommand,
CommandParameters oldParameters) {
String name = Optional.ofNullable(oldParameters.getMetadata())
.map(CommandMetadata::getCalledName)
.filter(n -> !n.startsWith("/"))
.orElseGet(oldCommand::getName);
return "/tool " + name;
}
static void setToolNone(Player player, LocalSession session, String type)
throws InvalidToolBindException {
session.setTool(player.getItemInHand(HandSide.MAIN_HAND).getType(), null);
player.print(type + " unbound from your current item.");
}
private final WorldEdit we;
public ToolCommands(WorldEdit we) {
this.we = we;
}
// @Command(
// name = "none",
// desc = "Unbind a bound tool from your current item"
// )
// public void none(Player player, LocalSession session) throws WorldEditException {
//
// session.setTool(player.getItemInHand(HandSide.MAIN_HAND).getType(), null);
// player.print("Tool unbound from your current item.");
// }
@Command(
name = "selwand",
aliases = "/selwand",
@ -74,7 +145,7 @@ public class ToolCommands {
public void selwand(Player player, LocalSession session) throws WorldEditException {
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(player, SelectionWand.INSTANCE);
session.setTool(itemType, new SelectionWand());
player.print("Selection wand bound to " + itemType.getName() + ".");
}
@ -215,8 +286,17 @@ public class ToolCommands {
Pattern secondary) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(player, new LongRangeBuildTool(primary, secondary));
BBC.TOOL_LRBUILD_BOUND.send(player, itemStack.getType().getName());
BBC.TOOL_LRBUILD_INFO.send(player, secondary, primary);
session.setTool(itemStack.getType(), new LongRangeBuildTool(primary, secondary));
player.print("Long-range building tool bound to " + itemStack.getType().getName() + ".");
String primaryName = "pattern";
String secondaryName = "pattern";
if (primary instanceof BlockStateHolder) {
primaryName = ((BlockStateHolder<?>) primary).getBlockType().getName();
}
if (secondary instanceof BlockStateHolder) {
secondaryName = ((BlockStateHolder<?>) secondary).getBlockType().getName();
}
player.print("Left-click set to " + primaryName + "; right-click set to "
+ secondaryName + ".");
}
}

View File

@ -82,16 +82,16 @@ public class ToolUtilCommands {
return;
}
if (maskOpt == null) {
player.print(BBC.BRUSH_MASK_DISABLED.s());
player.print("Brush mask disabled.");
tool.setMask(null);
return;
}
}
BrushSettings settings = offHand ? tool.getOffHand() : tool.getContext();
String lastArg = Iterables.getLast(CommandArgParser.spaceSplit(arguments.get())).getSubstring();
settings.addSetting(BrushSettings.SettingType.MASK, lastArg);
settings.setMask(maskOpt);
tool.update();
player.print(BBC.BRUSH_MASK.s());
player.print("Brush mask set.");
}
@Command(
@ -110,7 +110,7 @@ public class ToolUtilCommands {
if (tool == null) {
player.print(BBC.BRUSH_NONE.s());
return;
}
}
if (pattern == null) {
player.print(BBC.BRUSH_MATERIAL.s());
tool.setFill(null);
@ -125,61 +125,29 @@ public class ToolUtilCommands {
}
@Command(
name = "range",
desc = "Set the brush range"
)
name = "range",
desc = "Set the brush range"
)
@CommandPermissions("worldedit.brush.options.range")
public void range(Player player, LocalSession session,
@Arg(desc = "The range of the brush")
int range) throws WorldEditException {
range = Math.max(0, Math.min(256, range));
BrushTool tool = session.getBrushTool(player, false);
if (tool == null) {
player.print(BBC.BRUSH_NONE.s());
return;
}
tool.setRange(range);
player.print(BBC.BRUSH_RANGE.s());
int range) throws WorldEditException {
session.getBrushTool(player, false).setRange(range);
player.print("Brush range set.");
}
@Command(
name = "size",
desc = "Set the brush size"
name = "size",
desc = "Set the brush size"
)
@CommandPermissions("worldedit.brush.options.size")
public void size(Player player, LocalSession session,
@Arg(desc = "The size of the brush", def = "5")
int size,
@Switch(name = 'h', desc = "TODO")
boolean offHand) throws WorldEditException {
@Arg(desc = "The size of the brush")
int size) throws WorldEditException {
we.checkMaxBrushRadius(size);
BrushTool tool = session.getBrushTool(player, false);
if (tool == null) {
player.print(BBC.BRUSH_NONE.s());
return;
}
BrushSettings settings = offHand ? tool.getOffHand() : tool.getContext();
settings.setSize(size);
tool.update();
player.print(BBC.BRUSH_SIZE.s());
}
@Command(
name = "tracemask",
aliases = {"tarmask", "tm", "targetmask"},
desc = "Set the mask used to stop tool traces"
)
@CommandPermissions("worldedit.brush.options.tracemask")
public void traceMask(Player player, LocalSession session,
@Arg(desc = "The trace mask to set", def = "")
Mask maskOpt) throws WorldEditException {
BrushTool tool = session.getBrushTool(player, false);
if (tool == null) {
player.print(BBC.BRUSH_NONE.s());
return;
}
tool.setTraceMask(maskOpt);
BBC.BRUSH_TARGET_MASK_SET.send(player, maskOpt.toString());
session.getBrushTool(player, false).setSize(size);
player.print("Brush size set.");
}
//todo none should be moved to the same class where it is in upstream
@ -194,28 +162,42 @@ public class ToolUtilCommands {
}
@Command(
name = "/superpickaxe",
aliases = {",", "/sp", "/pickaxe"},
desc = "Toggle the super pickaxe function"
name = "tracemask",
aliases = {"tarmask", "tm", "targetmask"},
desc = "Set the mask used to stop tool traces"
)
@CommandPermissions("worldedit.brush.options.tracemask")
public void traceMask(Player player, LocalSession session,
@Arg(desc = "The trace mask to set", def = "")
Mask maskOpt) throws WorldEditException {
session.getBrushTool(player, false).setTraceMask(maskOpt);
if (maskOpt == null) {
player.print("Trace mask disabled.");
} else {
player.print("Trace mask set.");
}
}
@Command(
name = "/",
aliases = { "," },
desc = "Toggle the super pickaxe function"
)
@CommandPermissions("worldedit.superpickaxe")
public void togglePickaxe(Player player, LocalSession session,
@Arg(desc = "state", def = "on") String state) throws WorldEditException {
if (session.hasSuperPickAxe()) {
if ("on".equals(state)) {
player.print(BBC.SUPERPICKAXE_ENABLED.s());
@Arg(desc = "The new super pickaxe state", def = "")
Boolean superPickaxe) {
boolean hasSuperPickAxe = session.hasSuperPickAxe();
if (superPickaxe != null && superPickaxe == hasSuperPickAxe) {
player.printError("Super pickaxe already " + (superPickaxe ? "enabled" : "disabled") + ".");
return;
}
if (hasSuperPickAxe) {
session.disableSuperPickAxe();
player.print(BBC.SUPERPICKAXE_DISABLED.s());
player.print("Super pickaxe disabled.");
} else {
if ("off".equals(state)) {
player.print(BBC.SUPERPICKAXE_DISABLED.s());
return;
}
session.enableSuperPickAxe();
player.print(BBC.SUPERPICKAXE_ENABLED.s());
player.print("Super pickaxe enabled.");
}
}

View File

@ -30,7 +30,6 @@ import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.image.ImageUtil;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalConfiguration;
@ -46,21 +45,23 @@ import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.command.util.PrintCommandHelp;
import com.sk89q.worldedit.command.util.SkipQueue;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.function.EntityFunction;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.function.visitor.EntityVisitor;
import com.sk89q.worldedit.internal.annotation.Direction;
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 java.text.DecimalFormat;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.CylinderRegion;
@ -77,7 +78,6 @@ import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.AbstractMap;
import java.util.ArrayList;
@ -99,7 +99,8 @@ import org.enginehub.piston.annotation.param.Switch;
/**
* Utility commands.
*/
@CommandContainer(superTypes = {
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class UtilityCommands {
// CommandQueuedConditionGenerator.Registration.class,
CommandPermissionsConditionGenerator.Registration.class // TODO NOT IMPLEMENTED - Piston doesn't seem to work with multiple conditions???
})
@ -193,6 +194,7 @@ public class UtilityCommands {
@Command(
name = "/fill",
desc = "Fill a hole"
)
@CommandPermissions("worldedit.fill")
@Logging(PLACEMENT)
@ -218,6 +220,8 @@ public class UtilityCommands {
/*
@Command(
name = "/fillr",
desc = "Fill a hole recursively"
name = "patterns",
desc = "View help about patterns",
descFooter = "Patterns determine what blocks are placed\n" +
@ -296,10 +300,10 @@ public class UtilityCommands {
public int fillr(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The blocks to fill with")
Pattern pattern,
@Range(min=1) @Arg(desc = "The radius to fill in")
@Arg(desc = "The radius to fill in")
Expression radiusExp,
@Arg(desc = "The depth to fill", def = "")
Integer depth) throws WorldEditException, EvaluationException {
Integer depth) throws WorldEditException {
double radius = radiusExp.evaluate();
radius = Math.max(1, radius);
we.checkMaxRadius(radius);
@ -319,10 +323,10 @@ public class UtilityCommands {
@CommandPermissions("worldedit.drain")
@Logging(PLACEMENT)
public int drain(Actor actor, LocalSession session, EditSession editSession,
@Range(min=0) @Arg(desc = "The radius to drain")
@Arg(desc = "The radius to drain")
Expression radiusExp,
@Switch(name = 'w', desc = "Also un-waterlog blocks")
boolean waterlogged) throws WorldEditException, EvaluationException {
boolean waterlogged) throws WorldEditException {
double radius = radiusExp.evaluate();
radius = Math.max(0, radius);
we.checkMaxRadius(radius);
@ -340,9 +344,8 @@ public class UtilityCommands {
@CommandPermissions("worldedit.fixlava")
@Logging(PLACEMENT)
public int fixLava(Actor actor, LocalSession session, EditSession editSession,
@Range(min=0) @Arg(desc = "The radius to fix in")
Expression radiusExp) throws WorldEditException, EvaluationException {
double radius = radiusExp.evaluate();
@Arg(desc = "The radius to fix in")
double radius) throws WorldEditException {
radius = Math.max(0, radius);
we.checkMaxRadius(radius);
int affected = editSession.fixLiquid(session.getPlacementPosition(actor), radius, BlockTypes.LAVA);
@ -358,13 +361,12 @@ public class UtilityCommands {
@CommandPermissions("worldedit.fixwater")
@Logging(PLACEMENT)
public int fixWater(Actor actor, LocalSession session, EditSession editSession,
@Range(min=0) @Arg(desc = "The radius to fix in")
Expression radiusExp) throws WorldEditException, EvaluationException {
double radius = radiusExp.evaluate();
@Arg(desc = "The radius to fix in")
double radius) throws WorldEditException {
radius = Math.max(0, radius);
we.checkMaxRadius(radius);
int affected = editSession.fixLiquid(session.getPlacementPosition(actor), radius, BlockTypes.WATER);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been changed.");
return affected;
}
@ -376,15 +378,16 @@ public class UtilityCommands {
@CommandPermissions("worldedit.removeabove")
@Logging(PLACEMENT)
public int removeAbove(Actor actor, World world, LocalSession session, EditSession editSession,
@Range(min=1) @Arg(name = "size", desc = "The apothem of the square to remove from", def = "1")
@Arg(desc = "The apothem of the square to remove from", def = "1")
int size,
@Arg(desc = "The maximum height above you to remove from", def = "")
Integer height) throws WorldEditException {
size = Math.max(1, size);
we.checkMaxRadius(size);
height = height != null ? Math.min((world.getMaxY() + 1), height + 1) : (world.getMaxY() + 1);
int affected = editSession.removeAbove(session.getPlacementPosition(actor), size, height);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been removed.");
return affected;
}
@ -396,7 +399,7 @@ public class UtilityCommands {
@CommandPermissions("worldedit.removebelow")
@Logging(PLACEMENT)
public int removeBelow(Actor actor, World world, LocalSession session, EditSession editSession,
@Arg(name = "size", desc = "The apothem of the square to remove from", def = "1")
@Arg(desc = "The apothem of the square to remove from", def = "1")
int size,
@Arg(desc = "The maximum height below you to remove from", def = "")
Integer height) throws WorldEditException {
@ -405,7 +408,7 @@ public class UtilityCommands {
height = height != null ? Math.min((world.getMaxY() + 1), height + 1) : (world.getMaxY() + 1);
int affected = editSession.removeBelow(session.getPlacementPosition(actor), size, height);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been removed.");
return affected;
}
@ -419,25 +422,25 @@ public class UtilityCommands {
public int removeNear(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The mask of blocks to remove")
Mask mask,
@Range(min=1) @Arg(desc = "The radius of the square to remove from", def = "50")
@Arg(desc = "The radius of the square to remove from", def = "50")
int radius) throws WorldEditException {
radius = Math.max(1, radius);
we.checkMaxRadius(radius);
int affected = editSession.removeNear(session.getPlacementPosition(actor), mask, radius);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been removed.");
return affected;
}
@Command(
name = "replacenear",
aliases = { "/replacenear", "/rn" },
aliases = { "/replacenear" },
desc = "Replace nearby blocks"
)
@CommandPermissions("worldedit.replacenear")
@Logging(PLACEMENT)
public int replaceNear(Actor actor, World world, LocalSession session, EditSession editSession,
@Range(min=1) @Arg(desc = "The radius of the square to remove in")
@Arg(desc = "The radius of the square to remove in")
int radius,
@Arg(desc = "The mask matching blocks to remove", def = "")
Mask from,
@ -456,7 +459,7 @@ public class UtilityCommands {
}
int affected = editSession.replaceBlocks(region, from, to);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been replaced.");
return affected;
}
@ -468,7 +471,7 @@ public class UtilityCommands {
@CommandPermissions("worldedit.snow")
@Logging(PLACEMENT)
public int snow(Actor actor, LocalSession session, EditSession editSession,
@Range(min=1) @Arg(desc = "The radius of the circle to snow in", def = "10")
@Arg(desc = "The radius of the circle to snow in", def = "10")
double size) throws WorldEditException {
size = Math.max(1, size);
we.checkMaxRadius(size);
@ -486,7 +489,7 @@ public class UtilityCommands {
@CommandPermissions("worldedit.thaw")
@Logging(PLACEMENT)
public int thaw(Actor actor, LocalSession session, EditSession editSession,
@Range(min=1) @Arg(desc = "The radius of the circle to thaw in", def = "10")
@Arg(desc = "The radius of the circle to thaw in", def = "10")
double size) throws WorldEditException {
size = Math.max(1, size);
we.checkMaxRadius(size);
@ -504,7 +507,7 @@ public class UtilityCommands {
@CommandPermissions("worldedit.green")
@Logging(PLACEMENT)
public int green(Actor actor, LocalSession session, EditSession editSession,
@Range(min=1) @Arg(desc = "The radius of the circle to convert in", def = "10")
@Arg(desc = "The radius of the circle to convert in", def = "10")
double size,
@Switch(name = 'f', desc = "Also convert coarse dirt")
boolean convertCoarse) throws WorldEditException {
@ -513,10 +516,37 @@ public class UtilityCommands {
final boolean onlyNormalDirt = !convertCoarse;
final int affected = editSession.green(session.getPlacementPosition(actor), size, onlyNormalDirt);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " surface(s) greened.");
return affected;
}
private int killMatchingEntities(Integer radius, Actor actor, Supplier<EntityFunction> func) throws IncompleteRegionException,
MaxChangedBlocksException {
List<EntityVisitor> visitors = new ArrayList<>();
LocalSession session = we.getSessionManager().get(actor);
BlockVector3 center = session.getPlacementPosition(actor);
EditSession editSession = session.createEditSession(actor);
List<? extends Entity> entities;
if (radius >= 0) {
CylinderRegion region = CylinderRegion.createRadius(editSession, center, radius);
entities = editSession.getEntities(region);
} else {
entities = editSession.getEntities();
}
visitors.add(new EntityVisitor(entities.iterator(), func.get()));
int killed = 0;
for (EntityVisitor visitor : visitors) {
Operations.completeLegacy(visitor);
killed += visitor.getAffected();
}
session.remember(editSession);
editSession.flushSession();
return killed;
}
@Command(
name = "extinguish",
aliases = { "/ex", "/ext", "/extinguish", "ex", "ext" },
@ -525,7 +555,7 @@ public class UtilityCommands {
@CommandPermissions("worldedit.extinguish")
@Logging(PLACEMENT)
public void extinguish(Actor actor, LocalSession session, EditSession editSession,
@Range(min=1) @Arg(desc = "The radius of the square to remove in", def = "")
@Arg(desc = "The radius of the square to remove in", def = "")
Integer radius) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
@ -534,9 +564,9 @@ public class UtilityCommands {
int size = radius != null ? Math.max(1, radius) : defaultRadius;
we.checkMaxRadius(size);
Mask mask = BlockTypes.FIRE.toMask();
Mask mask = new BlockTypeMask(editSession, BlockTypes.FIRE);
int affected = editSession.removeNear(session.getPlacementPosition(actor), mask, size);
BBC.VISITOR_BLOCK.send(actor, affected);
actor.print(affected + " block(s) have been removed.");
}
@Command(
@ -597,6 +627,22 @@ public class UtilityCommands {
return killed;
}
@Command(
name = "/help",
desc = "Displays help for WorldEdit commands"
)
@CommandPermissions("worldedit.help")
public void help(Actor actor,
@Switch(name = 's', desc = "List sub-commands of the given command, if applicable")
boolean listSubCommands,
@ArgFlag(name = 'p', desc = "The page to retrieve", def = "1")
int page,
@Arg(desc = "The command to retrieve help for", def = "", variable = true)
List<String> command) throws WorldEditException {
PrintCommandHelp.help(command, page, listSubCommands,
we.getPlatformManager().getPlatformCommandManager().getCommandManager(), actor, "//help");
}
@Command(
name = "remove",
aliases = { "rem", "rement" },
@ -607,9 +653,8 @@ public class UtilityCommands {
public int remove(Actor actor,
@Arg(desc = "The type of entity to remove")
EntityRemover remover,
@Range(min=-1) @Arg(desc = "The radius of the cuboid to remove from")
@Arg(desc = "The radius of the cuboid to remove from")
int radius) throws WorldEditException {
if (radius < -1) {
actor.printError("Use -1 to remove all entities in loaded chunks");
return 0;
@ -621,34 +666,6 @@ public class UtilityCommands {
return removed;
}
private int killMatchingEntities(Integer radius, Actor actor, Supplier<EntityFunction> func) throws IncompleteRegionException, MaxChangedBlocksException {
List<EntityVisitor> visitors = new ArrayList<>();
LocalSession session = we.getSessionManager().get(actor);
BlockVector3 center = session.getPlacementPosition(actor);
EditSession editSession = session.createEditSession(actor);
List<? extends Entity> entities;
if (radius >= 0) {
CylinderRegion region = CylinderRegion.createRadius(editSession, center, radius);
entities = editSession.getEntities(region);
} else {
entities = editSession.getEntities();
}
visitors.add(new EntityVisitor(entities.iterator(), func.get()));
int killed = 0;
for (EntityVisitor visitor : visitors) {
Operations.completeLegacy(visitor);
killed += visitor.getAffected();
}
BBC.KILL_SUCCESS.send(actor, killed, radius);
session.remember(editSession);
editSession.flushSession();
return killed;
}
// get the formatter with the system locale. in the future, if we can get a local from a player, we can use that
private static final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.getDefault());
static {
@ -663,7 +680,7 @@ public class UtilityCommands {
@CommandPermissions("worldedit.calc")
public void calc(Actor actor,
@Arg(desc = "Expression to evaluate", variable = true)
List<String> input) throws EvaluationException {
List<String> input) {
Expression expression;
try {
expression = Expression.compile(String.join(" ", input));
@ -672,11 +689,12 @@ public class UtilityCommands {
"'%s' could not be parsed as a valid expression", input));
return;
}
double result = expression.evaluate(
new double[]{}, WorldEdit.getInstance().getSessionManager().get(actor).getTimeout());
String formatted = Double.isNaN(result) ? "NaN" : formatter.format(result);
TextComponent msg = SubtleFormat.wrap(input + " = ").append(TextComponent.of(formatted, TextColor.LIGHT_PURPLE));
actor.print(msg);
WorldEditAsyncCommandBuilder.createAndSendMessage(actor, () -> {
double result = expression.evaluate(
new double[]{}, WorldEdit.getInstance().getSessionManager().get(actor).getTimeout());
String formatted = Double.isNaN(result) ? "NaN" : formatter.format(result);
return SubtleFormat.wrap(input + " = ").append(TextComponent.of(formatted, TextColor.LIGHT_PURPLE));
}, null);
}
@Command(
@ -690,22 +708,6 @@ public class UtilityCommands {
}
}
@Command(
name = "/help",
desc = "Displays help for WorldEdit commands"
)
@CommandPermissions("worldedit.help")
public void help(Actor actor,
@Switch(name = 's', desc = "List sub-commands of the given command, if applicable")
boolean listSubCommands,
@ArgFlag(name = 'p', desc = "The page to retrieve", def = "1")
int page,
@Arg(desc = "The command to retrieve help for", def = "", variable = true)
List<String> commandStr) throws WorldEditException {
PrintCommandHelp.help(commandStr, page, listSubCommands,
we.getPlatformManager().getPlatformCommandManager().getCommandManager(), actor, "//help");
}
public static List<Map.Entry<URI, String>> filesToEntry(final File root, final List<File> files, final UUID uuid) {
return Lists.transform(files, input -> { // Keep this functional, as transform is evaluated lazily
URI uri = input.toURI();

View File

@ -56,11 +56,9 @@ import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch;
@CommandContainer(superTypes = {CommandPermissionsConditionGenerator.Registration.class, CommandQueuedConditionGenerator.Registration.class})
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class WorldEditCommands {
private static final DateTimeFormatter dateFormat = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss z");
private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
private final WorldEdit we;
@ -174,11 +172,10 @@ public class WorldEditCommands {
try {
ZoneId tz = ZoneId.of(timezone);
session.setTimezone(tz);
BBC.TIMEZONE_SET.send(actor, tz.getDisplayName(
TextStyle.FULL, Locale.ENGLISH
actor.print("Timezone set for this session to: " + tz.getDisplayName(
TextStyle.FULL, Locale.ENGLISH
));
BBC.TIMEZONE_DISPLAY
.send(actor, dateFormat.format(ZonedDateTime.now(tz)));
actor.print("The current time in that timezone is: " + dateFormat.format(ZonedDateTime.now(tz)));
} catch (ZoneRulesException e) {
actor.printError("Invalid timezone");
}
@ -186,7 +183,7 @@ public class WorldEditCommands {
@Command(
name = "help",
desc = "Displays help for FAWE commands"
desc = "Displays help for WorldEdit commands"
)
@SkipQueue
@CommandPermissions("worldedit.help")
@ -196,8 +193,8 @@ public class WorldEditCommands {
@ArgFlag(name = 'p', desc = "The page to retrieve", def = "1")
int page,
@Arg(desc = "The command to retrieve help for", def = "", variable = true)
List<String> commandStr) throws WorldEditException {
PrintCommandHelp.help(commandStr, page, listSubCommands,
we.getPlatformManager().getPlatformCommandManager().getCommandManager(), actor, "/worldedit help");
List<String> command) throws WorldEditException {
PrintCommandHelp.help(command, page, listSubCommands,
we.getPlatformManager().getPlatformCommandManager().getCommandManager(), actor, "/worldedit help");
}
}

View File

@ -19,20 +19,21 @@
package com.sk89q.worldedit.command.argument;
import static com.google.common.base.Preconditions.checkArgument;
import static com.sk89q.worldedit.util.formatting.text.TextComponent.space;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.List;
import org.enginehub.piston.converter.ArgumentConverter;
import org.enginehub.piston.converter.ConversionResult;
import org.enginehub.piston.converter.SuccessfulConversion;
import org.enginehub.piston.inject.InjectedValueAccess;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
import static com.sk89q.worldedit.util.formatting.text.TextComponent.space;
public class CommaSeparatedValuesConverter<T> implements ArgumentConverter<T> {
public static <T> CommaSeparatedValuesConverter<T> wrap(ArgumentConverter<T> delegate) {

View File

@ -28,12 +28,13 @@ import org.enginehub.piston.converter.ArgumentConverter;
import org.enginehub.piston.converter.ConversionResult;
import org.enginehub.piston.converter.FailedConversion;
import org.enginehub.piston.converter.SuccessfulConversion;
import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import java.util.List;
import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
public class EntityRemoverConverter implements ArgumentConverter<EntityRemover> {
public static void register(CommandManager commandManager) {

View File

@ -1,44 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.factory;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.util.TreeGenerator;
public final class TreeGeneratorFactory implements Contextual<ForestGenerator> {
private final TreeGenerator.TreeType type;
public TreeGeneratorFactory(TreeGenerator.TreeType type) {
this.type = type;
}
@Override
public ForestGenerator createFromContext(EditContext input) {
return new ForestGenerator((EditSession) input.getDestination(), type);
}
@Override
public String toString() {
return "tree of type " + type;
}
}

View File

@ -66,8 +66,8 @@ public class AreaPickaxe implements BlockTool {
try {
for (int x = ox - range; x <= ox + range; ++x) {
for (int z = oz - range; z <= oz + range; ++z) {
for (int y = oy + range; y >= oy - range; --y) {
for (int y = oy - range; y <= oy + range; ++y) {
for (int z = oz - range; z <= oz + range; ++z) {
if (initialType.equals(editSession.getBlock(x, y, z))) {
continue;
}

View File

@ -70,7 +70,6 @@ import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockType;
@ -437,7 +436,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
return act(BrushAction.PRIMARY, player, session);
}
}
public BlockVector3 getPosition(EditSession editSession, Player player) {
Location loc = player.getLocation();

View File

@ -23,7 +23,6 @@ import com.boydti.fawe.config.BBC;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
import com.sk89q.worldedit.function.mask.Mask;
@ -40,11 +39,6 @@ public class DistanceWand extends BrushTool implements DoubleActionTraceTool {
super("worldedit.selection.pos");
}
@Override
public boolean canUse(Actor player) {
return player.hasPermission("worldedit.wand");
}
@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
Location target = getTarget(player);
@ -74,8 +68,7 @@ public class DistanceWand extends BrushTool implements DoubleActionTraceTool {
private Location getTarget(Player player) {
Location target;
Mask mask = getTraceMask();
int range = getRange();
if (range < MAX_RANGE) {
if (this.range > -1) {
target = player.getBlockTrace(getRange(), true, mask);
} else {
target = player.getBlockTrace(MAX_RANGE, false, mask);

View File

@ -118,7 +118,7 @@ public class FloatingTreeRemover implements BlockTool {
* @param origin any point contained in the floating tree
* @return a set containing all blocks in the tree/shroom or null if this is not a floating tree/shroom.
*/
private Set<BlockVector3> bfs(World world, BlockVector3 origin) throws MaxChangedBlocksException {
private Set<BlockVector3> bfs(World world, BlockVector3 origin) {
final LocalBlockVectorSet visited = new LocalBlockVectorSet();
final LocalBlockVectorSet queue = new LocalBlockVectorSet();

View File

@ -27,6 +27,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
@ -56,39 +57,56 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
Location pos = getTargetFace(player);
if (pos == null) return false;
try (EditSession eS = session.createEditSession(player)) {
BlockBag bag = session.getBlockBag(player);
try (EditSession editSession = session.createEditSession(player)) {
try {
editSession.disableBuffering();
BlockVector3 blockPoint = pos.toVector().toBlockPoint();
BaseBlock applied = secondary.apply(blockPoint);
if (applied.getBlockType().getMaterial().isAir()) {
eS.setBlock(blockPoint, secondary);
editSession.setBlock(blockPoint, secondary);
} else {
eS.setBlock(pos.toVector().subtract(pos.getDirection()).toBlockPoint(), secondary);
editSession.setBlock(pos.toVector().subtract(pos.getDirection()).toBlockPoint(), secondary);
}
} catch (MaxChangedBlocksException ignored) {
} finally {
session.remember(editSession);
}
return true;
} catch (MaxChangedBlocksException ignored) {
// one block? eat it
} finally {
if (bag != null) {
bag.flushChanges();
}
return false;
}
return true;
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
Location pos = getTargetFace(player);
if (pos == null) return false;
try (EditSession eS = session.createEditSession(player)) {
BlockBag bag = session.getBlockBag(player);
try (EditSession editSession = session.createEditSession(player)) {
try {
editSession.disableBuffering();
BlockVector3 blockPoint = pos.toVector().toBlockPoint();
BaseBlock applied = primary.apply(blockPoint);
if (applied.getBlockType().getMaterial().isAir()) {
eS.setBlock(blockPoint, primary);
editSession.setBlock(blockPoint, primary);
} else {
eS.setBlock(pos.toVector().subtract(pos.getDirection()).toBlockPoint(), primary);
editSession.setBlock(pos.toVector().subtract(pos.getDirection()).toBlockPoint(), primary);
}
} catch (MaxChangedBlocksException ignored) {
} finally {
session.remember(editSession);
}
return true;
} catch (MaxChangedBlocksException ignored) {
// one block? eat it
} finally {
if (bag != null) {
bag.flushChanges();
}
return false;
}
return true;
}
private Location getTargetFace(Player player) {
@ -99,6 +117,7 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo
} else {
target = player.getBlockTrace(MAX_RANGE, false, mask);
}
if (target == null) {
player.printError(BBC.NO_BLOCK.s());
return null;

View File

@ -24,6 +24,7 @@ import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
@ -33,6 +34,8 @@ import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import java.util.OptionalInt;
/**
* Looks up information about a block.
*/

View File

@ -84,4 +84,36 @@ public class RecursivePickaxe implements BlockTool {
return true;
}
private static void recurse(Platform server, EditSession editSession, World world, BlockVector3 pos,
BlockVector3 origin, double size, BlockType initialType, Set<BlockVector3> visited) throws MaxChangedBlocksException {
final double distanceSq = origin.distanceSq(pos);
if (distanceSq > size*size || visited.contains(pos)) {
return;
}
visited.add(pos);
if (editSession.getBlock(pos).getBlockType() != initialType) {
return;
}
editSession.setBlock(pos, BlockTypes.AIR.getDefaultState());
world.queueBlockBreakEffect(server, pos, initialType, distanceSq);
recurse(server, editSession, world, pos.add(1, 0, 0),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(-1, 0, 0),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 0, 1),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 0, -1),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 1, 0),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, -1, 0),
origin, size, initialType, visited);
}
}

View File

@ -44,7 +44,7 @@ public class ClipboardBrush implements Brush {
this.ignoreAirBlocks = ignoreAirBlocks;
this.usingOrigin = usingOrigin;
this.pasteBiomes = false;
this.pasteEntities = true;
this.pasteEntities = false;
this.sourceMask = null;
}

View File

@ -23,7 +23,12 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.util.LocatedBlock;
import java.util.LinkedHashSet;
import java.util.Set;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.util.collection.LocatedBlockList;
import com.sk89q.worldedit.world.block.BlockTypes;
public class GravityBrush implements Brush {
@ -48,12 +53,15 @@ public class GravityBrush implements Brush {
if (y != freeSpot) {
editSession.setBlock((int)x, (int)y, (int)z, BlockTypes.AIR.getDefaultState());
editSession.setBlock((int)x, (int)freeSpot, (int)z, block);
}
}
freeSpot = y + 1;
}
}
}
column.clear();
removedBlocks.clear();
}
}
}
}

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.command.util;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListenableFuture;
@ -42,6 +40,9 @@ import javax.annotation.Nullable;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
public final class AsyncCommandBuilder<T> {
private static final Logger logger = LoggerFactory.getLogger(AsyncCommandBuilder.class);

View File

@ -19,7 +19,6 @@
package com.sk89q.worldedit.command.util;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.ImmutableSet;
import org.enginehub.piston.Command;
import org.enginehub.piston.gen.CommandConditionGenerator;
@ -28,6 +27,8 @@ import org.enginehub.piston.util.NonnullByDefault;
import java.lang.reflect.Method;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
@NonnullByDefault
public final class CommandPermissionsConditionGenerator implements CommandConditionGenerator {

View File

@ -20,12 +20,12 @@
package com.sk89q.worldedit.command.util;
import com.boydti.fawe.util.TaskManager;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.entity.metadata.EntityProperties;
import com.sk89q.worldedit.function.EntityFunction;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.regex.Pattern;
/**

View File

@ -24,8 +24,6 @@ import org.enginehub.piston.Command;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import java.lang.annotation.Annotation;
import java.util.Optional;
import java.util.Set;
public class PermissionCondition implements Command.Condition {