Add and apply .editorconfig from P2 (#1195)

* Consistenty use javax annotations.
 - Unfortunately jetbrains annotations seem to be exposed transitively via core somewhere, but with the correct IDE settings, annotations can be defaulted to javax
 - Cleaning up of import order in #1195
 - Must be merged before #1195

* Add and apply .editorconfig from P2
 - Does not rearrange entries

* Address some comments

* add back some javadoc comments

* Address final comments

Co-authored-by: NotMyFault <mc.cache@web.de>
This commit is contained in:
dordsor21
2021-07-24 16:34:05 +01:00
committed by GitHub
parent 3b4beba7d6
commit 8c0195970b
1143 changed files with 143599 additions and 9952 deletions

View File

@ -61,25 +61,29 @@ import static org.enginehub.piston.part.CommandParts.arg;
public class ApplyBrushCommands {
private static final CommandArgument REGION_FACTORY = arg(Caption.of("shape"), Caption.of("worldedit.brush.apply.shape"))
.defaultsTo(ImmutableList.of())
.ofTypes(ImmutableList.of(Key.of(RegionFactory.class)))
.build();
.defaultsTo(ImmutableList.of())
.ofTypes(ImmutableList.of(Key.of(RegionFactory.class)))
.build();
private static final CommandArgument RADIUS = arg(Caption.of("radius"), Caption.of("worldedit.brush.apply.radius"))
.defaultsTo(ImmutableList.of("5"))
.ofTypes(ImmutableList.of(Key.of(double.class)))
.build();
.defaultsTo(ImmutableList.of("5"))
.ofTypes(ImmutableList.of(Key.of(double.class)))
.build();
public static void register(CommandManagerService service, CommandManager commandManager, CommandRegistrationHandler registration) {
public static void register(
CommandManagerService service,
CommandManager commandManager,
CommandRegistrationHandler registration
) {
commandManager.register("apply", builder -> {
builder.description(Caption.of("worldedit.brush.apply.description"));
builder.action(org.enginehub.piston.Command.Action.NULL_ACTION);
CommandManager manager = service.newCommandManager();
registration.register(
manager,
ApplyBrushCommandsRegistration.builder(),
new ApplyBrushCommands()
manager,
ApplyBrushCommandsRegistration.builder(),
new ApplyBrushCommands()
);
builder.condition(new PermissionCondition(ImmutableSet.of("worldedit.brush.apply")));
@ -92,50 +96,59 @@ public class ApplyBrushCommands {
});
}
private void setApplyBrush(CommandParameters parameters, Player player, LocalSession localSession,
Contextual<? extends RegionFunction> generatorFactory) throws WorldEditException {
private void setApplyBrush(
CommandParameters parameters, Player player, LocalSession localSession,
Contextual<? extends RegionFunction> generatorFactory
) throws WorldEditException {
double radius = requireNonNull(RADIUS.value(parameters).asSingle(double.class));
RegionFactory regionFactory = REGION_FACTORY.value(parameters).asSingle(RegionFactory.class);
BrushCommands.setOperationBasedBrush(player, localSession, Expression.compile(Double.toString(radius)),
new ApplyRegion(generatorFactory), regionFactory, "worldedit.brush.apply");
new ApplyRegion(generatorFactory), regionFactory, "worldedit.brush.apply"
);
}
@Command(
name = "forest",
desc = "Plant trees"
name = "forest",
desc = "Plant trees"
)
public void forest(CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The type of tree to plant")
TreeGenerator.TreeType type) throws WorldEditException {
public void forest(
CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The type of tree to plant")
TreeGenerator.TreeType type
) throws WorldEditException {
setApplyBrush(parameters, player, localSession, new TreeGeneratorFactory(type));
}
@Command(
name = "item",
desc = "Use an item"
name = "item",
desc = "Use an item"
)
@CommandPermissions("worldedit.brush.item")
public void item(CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The type of item to use")
BaseItem item,
@Arg(desc = "The direction in which the item will be applied", def = "up")
@Direction(includeDiagonals = true)
com.sk89q.worldedit.util.Direction direction) throws WorldEditException {
public void item(
CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The type of item to use")
BaseItem item,
@Arg(desc = "The direction in which the item will be applied", def = "up")
@Direction(includeDiagonals = true)
com.sk89q.worldedit.util.Direction direction
) throws WorldEditException {
player.print(TextComponent.builder().append("WARNING: ")
.append(Caption.of("worldedit.brush.apply.item.warning")).build());
setApplyBrush(parameters, player, localSession, new ItemUseFactory(item, direction));
}
@Command(
name = "set",
desc = "Place a block"
name = "set",
desc = "Place a block"
)
public void set(CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The pattern of blocks to use")
Pattern pattern) throws WorldEditException {
public void set(
CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The pattern of blocks to use")
Pattern pattern
) throws WorldEditException {
setApplyBrush(parameters, player, localSession, new ReplaceFactory(pattern));
}

View File

@ -75,14 +75,16 @@ public class BiomeCommands {
}
@Command(
name = "biomelist",
aliases = { "biomels", "/biomelist", "/listbiomes" },
desc = "Gets all biomes available."
name = "biomelist",
aliases = {"biomels", "/biomelist", "/listbiomes"},
desc = "Gets all biomes available."
)
@CommandPermissions("worldedit.biome.list")
public void biomeList(Actor actor,
@ArgFlag(name = 'p', desc = "Page number.", def = "1")
int page) {
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();
@ -90,27 +92,30 @@ public class BiomeCommands {
PaginationBox paginationBox = PaginationBox.fromComponents("Available Biomes", "/biomelist -p %page%",
BiomeType.REGISTRY.values().stream()
.map(biomeType -> TextComponent.builder()
.append(biomeType.getId())
.append(" (")
.append(biomeRegistry.getRichName(biomeType))
.append(")")
.build())
.collect(Collectors.toList()));
return paginationBox.create(page);
.append(biomeType.getId())
.append(" (")
.append(biomeRegistry.getRichName(biomeType))
.append(")")
.build())
.collect(Collectors.toList())
);
return paginationBox.create(page);
}, (Component) null);
}
@Command(
name = "biomeinfo",
desc = "Get the biome of the targeted block.",
descFooter = "By default, uses all blocks in your selection."
name = "biomeinfo",
desc = "Get the biome of the targeted block.",
descFooter = "By default, uses all blocks in your selection."
)
@CommandPermissions("worldedit.biome.info")
public void biomeInfo(Player player, LocalSession session,
@Switch(name = 't', desc = "Use the block you are looking at.")
boolean useLineOfSight,
@Switch(name = 'p', desc = "Use the block you are currently in.")
boolean usePosition) throws WorldEditException {
public void biomeInfo(
Player player, LocalSession session,
@Switch(name = 't', desc = "Use the block you are looking at.")
boolean useLineOfSight,
@Switch(name = 'p', desc = "Use the block you are currently in.")
boolean usePosition
) throws WorldEditException {
BiomeRegistry biomeRegistry = WorldEdit.getInstance().getPlatformManager()
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
Set<BiomeType> biomes = new HashSet<>();
@ -144,24 +149,26 @@ public class BiomeCommands {
}
List<Component> components = biomes.stream().map(biome ->
biomeRegistry.getRichName(biome).hoverEvent(
HoverEvent.showText(TextComponent.of(biome.getId()))
)
biomeRegistry.getRichName(biome).hoverEvent(
HoverEvent.showText(TextComponent.of(biome.getId()))
)
).collect(Collectors.toList());
player.print(Caption.of(messageKey, TextUtils.join(components, TextComponent.of(", "))));
}
@Command(
name = "/setbiome",
desc = "Sets the biome of your current block or region.",
descFooter = "By default, uses all the blocks in your selection"
name = "/setbiome",
desc = "Sets the biome of your current block or region.",
descFooter = "By default, uses all the blocks in your selection"
)
@Logging(REGION)
@CommandPermissions("worldedit.biome.set")
public void setBiome(Player player, LocalSession session, EditSession editSession,
@Arg(desc = "Biome type.") BiomeType target,
@Switch(name = 'p', desc = "Use your current position")
boolean atPosition) throws WorldEditException {
public void setBiome(
Player player, LocalSession session, EditSession editSession,
@Arg(desc = "Biome type.") BiomeType target,
@Switch(name = 'p', desc = "Use your current position")
boolean atPosition
) throws WorldEditException {
World world = player.getWorld();
Region region;
Mask mask = editSession.getMask();

View File

@ -76,9 +76,9 @@ public class ChunkCommands {
}
@Command(
name = "chunkinfo",
aliases = { "/chunkinfo" },
desc = "Get information about the chunk you're inside"
name = "chunkinfo",
aliases = {"/chunkinfo"},
desc = "Get information about the chunk you're inside"
)
@CommandPermissions("worldedit.chunkinfo")
public void chunkInfo(Player player) {
@ -89,39 +89,48 @@ public class ChunkCommands {
final BlockVector2 chunkPos = BlockVector2.at(chunkX, chunkZ);
player.print(Caption.of("worldedit.chunkinfo.chunk", TextComponent.of(chunkX), TextComponent.of(chunkZ)));
player.print(Caption.of("worldedit.chunkinfo.old-filename", TextComponent.of(LegacyChunkStore.getFilename(chunkPos))));
player.print(Caption.of("worldedit.chunkinfo.mcregion-filename", TextComponent.of(McRegionChunkStore.getFilename(chunkPos))));
player.print(Caption.of(
"worldedit.chunkinfo.mcregion-filename",
TextComponent.of(McRegionChunkStore.getFilename(chunkPos))
));
}
@Command(
name = "listchunks",
aliases = { "/listchunks" },
desc = "List chunks that your selection includes"
name = "listchunks",
aliases = {"/listchunks"},
desc = "List chunks that your selection includes"
)
@CommandPermissions("worldedit.listchunks")
public void listChunks(Actor actor, World world, LocalSession session,
@ArgFlag(name = 'p', desc = "Page number.", def = "1") int page) throws WorldEditException {
public void listChunks(
Actor actor, World world, LocalSession session,
@ArgFlag(name = 'p', desc = "Page number.", def = "1") int page
) throws WorldEditException {
final Region region = session.getSelection(world);
WorldEditAsyncCommandBuilder.createAndSendMessage(actor,
WorldEditAsyncCommandBuilder.createAndSendMessage(
actor,
() -> new ChunkListPaginationBox(region).create(page),
TranslatableComponent.of(
"worldedit.listchunks.listfor",
TextComponent.of(actor.getName())
));
)
);
actor.print(new ChunkListPaginationBox(region).create(page));
actor.print(Caption.of("worldedit.listchunks.listfor", TextComponent.of(actor.getName())));
}
@Command(
name = "delchunks",
aliases = { "/delchunks" },
desc = "Delete chunks that your selection includes"
name = "delchunks",
aliases = {"/delchunks"},
desc = "Delete chunks that your selection includes"
)
@CommandPermissions("worldedit.delchunks")
@Logging(REGION)
public void deleteChunks(Actor actor, World world, LocalSession session,
@ArgFlag(name = 'o', desc = "Only delete chunks older than the specified time.")
ZonedDateTime beforeTime) throws WorldEditException {
public void deleteChunks(
Actor actor, World world, LocalSession session,
@ArgFlag(name = 'o', desc = "Only delete chunks older than the specified time.")
ZonedDateTime beforeTime
) throws WorldEditException {
Path worldDir = world.getStoragePath();
if (worldDir == null) {
throw new StopExecutionException(TextComponent.of("Couldn't find world folder for this world."));
@ -169,11 +178,15 @@ public class ChunkCommands {
throw new StopExecutionException(TextComponent.of("Failed to write chunk list: " + e.getMessage()));
}
actor.print(TextComponent.of(String.format("%d chunk(s) have been marked for deletion the next time the server starts.",
newBatch.getChunkCount())));
actor.print(TextComponent.of(String.format(
"%d chunk(s) have been marked for deletion the next time the server starts.",
newBatch.getChunkCount()
)));
if (currentInfo.batches.size() > 1) {
actor.printDebug(TextComponent.of(String.format("%d chunks total marked for deletion. (May have overlaps).",
currentInfo.batches.stream().mapToInt(ChunkDeletionInfo.ChunkBatch::getChunkCount).sum())));
actor.printDebug(TextComponent.of(String.format(
"%d chunks total marked for deletion. (May have overlaps).",
currentInfo.batches.stream().mapToInt(ChunkDeletionInfo.ChunkBatch::getChunkCount).sum()
)));
}
actor.print(TextComponent.of("You can mark more chunks for deletion, or to stop now, run: ", TextColor.LIGHT_PURPLE)
.append(TextComponent.of("/stop", TextColor.AQUA)
@ -181,6 +194,7 @@ public class ChunkCommands {
}
private static class ChunkListPaginationBox extends PaginationBox {
//private final Region region;
private final List<BlockVector2> chunks;
@ -202,5 +216,7 @@ public class ChunkCommands {
public int getComponentsSize() {
return chunks.size();
}
}
}

View File

@ -23,17 +23,18 @@ import com.fastasyncworldedit.core.FaweAPI;
import com.fastasyncworldedit.core.FaweCache;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.object.FaweLimit;
import com.fastasyncworldedit.core.util.task.RunnableVal;
import com.fastasyncworldedit.core.event.extent.PasteEvent;
import com.fastasyncworldedit.core.extent.clipboard.DiskOptimizedClipboard;
import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder;
import com.fastasyncworldedit.core.extent.clipboard.ReadOnlyClipboard;
import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder;
import com.fastasyncworldedit.core.internal.exception.FaweException;
import com.fastasyncworldedit.core.internal.io.FastByteArrayOutputStream;
import com.fastasyncworldedit.core.object.FaweLimit;
import com.fastasyncworldedit.core.util.ImgurUtility;
import com.fastasyncworldedit.core.util.MainUtil;
import com.fastasyncworldedit.core.util.MaskTraverser;
import com.fastasyncworldedit.core.util.task.RunnableVal;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
@ -45,7 +46,6 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.command.util.annotation.Confirm;
import com.sk89q.worldedit.entity.Player;
import com.fastasyncworldedit.core.event.extent.PasteEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
@ -107,28 +107,31 @@ import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
public class ClipboardCommands {
@Command(
name = "/copy",
aliases = "/cp",
desc = "Copy the selection to the clipboard"
name = "/copy",
aliases = "/cp",
desc = "Copy the selection to the clipboard"
)
@CommandPermissions("worldedit.clipboard.copy")
@Confirm(Confirm.Processor.REGION)
public void copy(Actor actor, LocalSession session, EditSession editSession,
@Selection Region region,
@Switch(name = 'e', desc = "Also copy entities")
boolean copyEntities,
@Switch(name = 'b', desc = "Also copy biomes")
boolean copyBiomes,
//FAWE start
@Switch(name = 'c', desc = "Set the origin of the clipboard to the center of the copied region")
boolean centerClipboard,
@ArgFlag(name = 'm', desc = "Set the include mask, non-matching blocks become air", def = "")
Mask mask) throws WorldEditException {
public void copy(
Actor actor, LocalSession session, EditSession editSession,
@Selection Region region,
@Switch(name = 'e', desc = "Also copy entities")
boolean copyEntities,
@Switch(name = 'b', desc = "Also copy biomes")
boolean copyBiomes,
//FAWE start
@Switch(name = 'c', desc = "Set the origin of the clipboard to the center of the copied region")
boolean centerClipboard,
@ArgFlag(name = 'm', desc = "Set the include mask, non-matching blocks become air", def = "")
Mask mask
) throws WorldEditException {
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
long volume =
((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1);
((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min
.getZ() + 1);
FaweLimit limit = actor.getLimit();
if (volume >= limit.MAX_CHECKS) {
throw FaweCache.MAX_CHECKS;
@ -171,18 +174,21 @@ public class ClipboardCommands {
//FAWE start
@Command(
name = "/lazycopy",
desc = "Lazily copy the selection to the clipboard"
name = "/lazycopy",
desc = "Lazily copy the selection to the clipboard"
)
@CommandPermissions("worldedit.clipboard.lazycopy")
public void lazyCopy(Actor actor, LocalSession session, EditSession editSession, @Selection Region region,
@Switch(name = 'e', desc = "Skip copy entities")
boolean skipEntities,
@Switch(name = 'b', desc = "Also copy biomes")
boolean copyBiomes) throws WorldEditException {
public void lazyCopy(
Actor actor, LocalSession session, EditSession editSession, @Selection Region region,
@Switch(name = 'e', desc = "Skip copy entities")
boolean skipEntities,
@Switch(name = 'b', desc = "Also copy biomes")
boolean copyBiomes
) throws WorldEditException {
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min
.getZ() + 1));
FaweLimit limit = actor.getLimit();
if (volume >= limit.MAX_CHECKS) {
throw new FaweException(Caption.of("fawe.cancel.worldedit.cancel.reason.max.checks"));
@ -229,29 +235,32 @@ public class ClipboardCommands {
//FAWE end
@Command(
name = "/cut",
desc = "Cut the selection to the clipboard",
descFooter = "WARNING: Cutting and pasting entities cannot be undone!"
name = "/cut",
desc = "Cut the selection to the clipboard",
descFooter = "WARNING: Cutting and pasting entities cannot be undone!"
)
@CommandPermissions("worldedit.clipboard.cut")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public void cut(Actor actor, LocalSession session, EditSession editSession,
@Selection Region region,
@Arg(desc = "Pattern to leave in place of the selection", def = "air")
Pattern leavePattern,
@Switch(name = 'e', desc = "Also cut entities")
boolean copyEntities,
@Switch(name = 'b', desc = "Also copy biomes, source biomes are unaffected")
boolean copyBiomes,
@ArgFlag(name = 'm', desc = "Set the exclude mask, non-matching blocks become air")
Mask mask) throws WorldEditException {
public void cut(
Actor actor, LocalSession session, EditSession editSession,
@Selection Region region,
@Arg(desc = "Pattern to leave in place of the selection", def = "air")
Pattern leavePattern,
@Switch(name = 'e', desc = "Also cut entities")
boolean copyEntities,
@Switch(name = 'b', desc = "Also copy biomes, source biomes are unaffected")
boolean copyBiomes,
@ArgFlag(name = 'm', desc = "Set the exclude mask, non-matching blocks become air")
Mask mask
) throws WorldEditException {
//FAWE start - Inject limits & respect source mask
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min
.getZ() + 1));
FaweLimit limit = actor.getLimit();
if (volume >= limit.MAX_CHECKS) {
throw FaweCache.MAX_CHECKS;
@ -299,13 +308,17 @@ public class ClipboardCommands {
//FAWE start
@Command(
name = "download",
aliases = { "/download" },
desc = "Downloads your clipboard through the configured web interface"
name = "download",
aliases = {"/download"},
desc = "Downloads your clipboard through the configured web interface"
)
@Deprecated
@CommandPermissions({"worldedit.clipboard.download"})
public void download(final Player player, final LocalSession session, @Arg(name = "format", desc = "String", def = "fast") final String formatName) throws WorldEditException {
public void download(
final Player player,
final LocalSession session,
@Arg(name = "format", desc = "String", def = "fast") final String formatName
) throws WorldEditException {
final ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
if (format == null) {
player.print(Caption.of("fawe.worldedit.clipboard.clipboard.invalid.format", formatName));
@ -401,17 +414,19 @@ public class ClipboardCommands {
)
@CommandPermissions("worldedit.clipboard.place")
@Logging(PLACEMENT)
public void place(Actor actor, World world, LocalSession session, final EditSession editSession,
@Switch(name = 'a', desc = "Skip air blocks")
boolean ignoreAirBlocks,
@Switch(name = 'o', desc = "Paste at the original position")
boolean atOrigin,
@Switch(name = 's', desc = "Select the region after pasting")
boolean selectPasted,
@Switch(name = 'e', desc = "Paste entities if available")
boolean pasteEntities,
@Switch(name = 'b', desc = "Paste biomes if available")
boolean pasteBiomes) throws WorldEditException {
public void place(
Actor actor, World world, LocalSession session, final EditSession editSession,
@Switch(name = 'a', desc = "Skip air blocks")
boolean ignoreAirBlocks,
@Switch(name = 'o', desc = "Paste at the original position")
boolean atOrigin,
@Switch(name = 's', desc = "Select the region after pasting")
boolean selectPasted,
@Switch(name = 'e', desc = "Paste entities if available")
boolean pasteEntities,
@Switch(name = 'b', desc = "Paste biomes if available")
boolean pasteBiomes
) throws WorldEditException {
ClipboardHolder holder = session.getClipboard();
final Clipboard clipboard = holder.getClipboard();
final BlockVector3 origin = clipboard.getOrigin();
@ -424,7 +439,10 @@ public class ClipboardCommands {
if (selectPasted) {
BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
BlockVector3 realTo = to.add(holder.getTransform().apply(clipboardOffset.toVector3()).toBlockPoint());
BlockVector3 max = realTo.add(holder.getTransform().apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3()).toBlockPoint());
BlockVector3 max = realTo.add(holder
.getTransform()
.apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3())
.toBlockPoint());
RegionSelector selector = new CuboidRegionSelector(world, realTo, max);
session.setRegionSelector(world, selector);
selector.learnChanges();
@ -439,46 +457,50 @@ public class ClipboardCommands {
private void saveDiskClipboard(Clipboard clipboard) {
DiskOptimizedClipboard c;
if (clipboard instanceof DiskOptimizedClipboard)
if (clipboard instanceof DiskOptimizedClipboard) {
c = (DiskOptimizedClipboard) clipboard;
else if (clipboard instanceof BlockArrayClipboard
&& ((BlockArrayClipboard) clipboard).getParent() instanceof DiskOptimizedClipboard)
} else if (clipboard instanceof BlockArrayClipboard
&& ((BlockArrayClipboard) clipboard).getParent() instanceof DiskOptimizedClipboard) {
c = (DiskOptimizedClipboard) ((BlockArrayClipboard) clipboard).getParent();
else
} else {
return;
}
c.flush();
}
//FAWE end
@Command(
name = "/paste",
aliases = {"/p", "/pa"},
desc = "Paste the clipboard's contents"
name = "/paste",
aliases = {"/p", "/pa"},
desc = "Paste the clipboard's contents"
)
@CommandPermissions("worldedit.clipboard.paste")
@Logging(PLACEMENT)
public void paste(Actor actor, World world, LocalSession session, EditSession editSession,
@Switch(name = 'a', desc = "Skip air blocks")
boolean ignoreAirBlocks,
@Switch(name = 'o', desc = "Paste at the original position")
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")
boolean pasteBiomes,
@ArgFlag(name = 'm', desc = "Only paste blocks matching this mask")
@ClipboardMask
Mask sourceMask) throws WorldEditException {
public void paste(
Actor actor, World world, LocalSession session, EditSession editSession,
@Switch(name = 'a', desc = "Skip air blocks")
boolean ignoreAirBlocks,
@Switch(name = 'o', desc = "Paste at the original position")
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")
boolean pasteBiomes,
@ArgFlag(name = 'm', desc = "Only paste blocks matching this mask")
@ClipboardMask
Mask sourceMask
) throws WorldEditException {
ClipboardHolder holder = session.getClipboard();
if (holder.getTransform().isIdentity() && editSession.getSourceMask() == null) {
//FAWE start - use place
place(actor, world, session, editSession, ignoreAirBlocks, atOrigin, selectPasted,
pasteEntities, pasteBiomes);
pasteEntities, pasteBiomes
);
//FAWE end
return;
}
@ -507,7 +529,9 @@ public class ClipboardCommands {
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()));
Vector3 max = realTo.add(holder
.getTransform()
.apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3()));
RegionSelector selector = new CuboidRegionSelector(world, realTo.toBlockPoint(), max.toBlockPoint());
session.setRegionSelector(world, selector);
selector.learnChanges();
@ -537,20 +561,22 @@ public class ClipboardCommands {
//FAWE end
@Command(
name = "/rotate",
desc = "Rotate the contents of the clipboard",
descFooter = "Non-destructively rotate the contents of the clipboard.\n"
+ "Angles are provided in degrees and a positive angle will result in a clockwise rotation. "
+ "Multiple rotations can be stacked. Interpolation is not performed so angles should be a multiple of 90 degrees.\n"
name = "/rotate",
desc = "Rotate the contents of the clipboard",
descFooter = "Non-destructively rotate the contents of the clipboard.\n"
+ "Angles are provided in degrees and a positive angle will result in a clockwise rotation. "
+ "Multiple rotations can be stacked. Interpolation is not performed so angles should be a multiple of 90 degrees.\n"
)
@CommandPermissions("worldedit.clipboard.rotate")
public void rotate(Actor actor, LocalSession session,
@Arg(desc = "Amount to rotate on the y-axis")
double rotateY,
@Arg(desc = "Amount to rotate on the x-axis", def = "0")
double rotateX,
@Arg(desc = "Amount to rotate on the z-axis", def = "0")
double rotateZ) throws WorldEditException {
public void rotate(
Actor actor, LocalSession session,
@Arg(desc = "Amount to rotate on the y-axis")
double rotateY,
@Arg(desc = "Amount to rotate on the x-axis", def = "0")
double rotateX,
@Arg(desc = "Amount to rotate on the z-axis", def = "0")
double rotateZ
) throws WorldEditException {
ClipboardHolder holder = session.getClipboard();
AffineTransform transform = new AffineTransform();
transform = transform.rotateY(-rotateY);
@ -561,13 +587,15 @@ public class ClipboardCommands {
}
@Command(
name = "/flip",
desc = "Flip the contents of the clipboard across the origin"
name = "/flip",
desc = "Flip the contents of the clipboard across the origin"
)
@CommandPermissions("worldedit.clipboard.flip")
public void flip(Actor actor, LocalSession session,
@Arg(desc = "The direction to flip, defaults to look direction.", def = Direction.AIM)
@Direction BlockVector3 direction) throws WorldEditException {
public void flip(
Actor actor, LocalSession session,
@Arg(desc = "The direction to flip, defaults to look direction.", def = Direction.AIM)
@Direction BlockVector3 direction
) throws WorldEditException {
ClipboardHolder holder = session.getClipboard();
AffineTransform transform = new AffineTransform();
transform = transform.scale(direction.abs().multiply(-2).add(1, 1, 1).toVector3());
@ -576,13 +604,14 @@ public class ClipboardCommands {
}
@Command(
name = "clearclipboard",
aliases = { "/clearclipboard", "/cc", "/clearclip" },
desc = "Clear your clipboard"
name = "clearclipboard",
aliases = {"/clearclipboard", "/cc", "/clearclip"},
desc = "Clear your clipboard"
)
@CommandPermissions("worldedit.clipboard.clear")
public void clearClipboard(Actor actor, LocalSession session) throws WorldEditException {
session.setClipboard(null);
actor.print(Caption.of("worldedit.clearclipboard.cleared"));
}
}

View File

@ -54,31 +54,33 @@ import static com.sk89q.worldedit.internal.command.CommandUtil.requireIV;
@CommandContainer
public class ExpandCommands {
public static void register(CommandRegistrationHandler registration,
CommandManager commandManager,
CommandManagerService commandManagerService) {
public static void register(
CommandRegistrationHandler registration,
CommandManager commandManager,
CommandManagerService commandManagerService
) {
// Collect the general expand command
CommandManager collect = commandManagerService.newCommandManager();
registration.register(
collect,
ExpandCommandsRegistration.builder(),
new ExpandCommands()
collect,
ExpandCommandsRegistration.builder(),
new ExpandCommands()
);
Command expandBaseCommand = collect.getCommand("/expand")
.orElseThrow(() -> new IllegalStateException("No /expand command"));
.orElseThrow(() -> new IllegalStateException("No /expand command"));
commandManager.register("/expand", command -> {
command.condition(new PermissionCondition(ImmutableSet.of("worldedit.selection.expand")));
command.addPart(SubCommandPart.builder(
Caption.of("vert"),
TextComponent.of("Vertical expansion sub-command")
TextComponent.of("Vertical expansion sub-command")
)
.withCommands(ImmutableSet.of(createVertCommand(commandManager)))
.optional()
.build());
.withCommands(ImmutableSet.of(createVertCommand(commandManager)))
.optional()
.build());
command.addParts(expandBaseCommand.getParts());
command.action(expandBaseCommand.getAction());
@ -88,16 +90,16 @@ public class ExpandCommands {
private static Command createVertCommand(CommandManager commandManager) {
return commandManager.newCommand("vert")
.description(Caption.of("worldedit.expand.description.vert"))
.action(parameters -> {
expandVert(
requireIV(Key.of(LocalSession.class), "localSession", parameters),
requireIV(Key.of(Actor.class), "actor", parameters),
requireIV(Key.of(World.class), "world", parameters)
);
return 1;
})
.build();
.description(Caption.of("worldedit.expand.description.vert"))
.action(parameters -> {
expandVert(
requireIV(Key.of(LocalSession.class), "localSession", parameters),
requireIV(Key.of(Actor.class), "actor", parameters),
requireIV(Key.of(World.class), "world", parameters)
);
return 1;
})
.build();
}
private static void expandVert(LocalSession session, Actor actor, World world) throws IncompleteRegionException {
@ -105,8 +107,9 @@ public class ExpandCommands {
try {
long oldSize = region.getVolume();
region.expand(
BlockVector3.at(0, (world.getMaxY() + 1), 0),
BlockVector3.at(0, -(world.getMaxY() + 1), 0));
BlockVector3.at(0, (world.getMaxY() + 1), 0),
BlockVector3.at(0, -(world.getMaxY() + 1), 0)
);
session.getRegionSelector(world).learnChanges();
long newSize = region.getVolume();
session.getRegionSelector(world).explainRegionAdjust(actor, session);
@ -120,18 +123,20 @@ public class ExpandCommands {
}
@org.enginehub.piston.annotation.Command(
name = "/expand",
desc = "Expand the selection area"
name = "/expand",
desc = "Expand the selection area"
)
@Logging(REGION)
public void expand(Actor actor, World world, LocalSession session,
@Arg(desc = "Amount to expand the selection by, can be `vert` to expand to the whole vertical column")
int amount,
@Arg(desc = "Amount to expand the selection by in the other direction", def = "0")
int reverseAmount,
@Arg(desc = "Direction to expand", def = Direction.AIM)
@MultiDirection
List<BlockVector3> direction) throws WorldEditException {
public void expand(
Actor actor, World world, LocalSession session,
@Arg(desc = "Amount to expand the selection by, can be `vert` to expand to the whole vertical column")
int amount,
@Arg(desc = "Amount to expand the selection by in the other direction", def = "0")
int reverseAmount,
@Arg(desc = "Direction to expand", def = Direction.AIM)
@MultiDirection
List<BlockVector3> direction
) throws WorldEditException {
Region region = session.getSelection(world);
long oldSize = region.getVolume();

View File

@ -49,7 +49,7 @@ public class FlattenedClipboardTransform {
/**
* Create a new instance.
*
* @param original the original clipboard
* @param original the original clipboard
* @param transform the transform
*/
private FlattenedClipboardTransform(Clipboard original, Transform transform) {
@ -73,9 +73,10 @@ public class FlattenedClipboardTransform {
new CombinedTransform(
new AffineTransform().translate(original.getOrigin().multiply(-1)),
transform,
new AffineTransform().translate(original.getOrigin()));
new AffineTransform().translate(original.getOrigin())
);
Vector3[] corners = new Vector3[] {
Vector3[] corners = new Vector3[]{
minimum,
maximum,
minimum.withX(maximum.getX()),
@ -119,7 +120,13 @@ public class FlattenedClipboardTransform {
extent = new BlockTransformExtent(original, transform);
}
//FAWE end
ForwardExtentCopy copy = new ForwardExtentCopy(extent, original.getRegion(), original.getOrigin(), target, original.getOrigin());
ForwardExtentCopy copy = new ForwardExtentCopy(
extent,
original.getRegion(),
original.getOrigin(),
target,
original.getOrigin()
);
copy.setTransform(transform);
if (original.hasBiomes()) {
copy.setCopyingBiomes(true);
@ -130,7 +137,7 @@ public class FlattenedClipboardTransform {
/**
* Create a new instance to bake the transform with.
*
* @param original the original clipboard
* @param original the original clipboard
* @param transform the transform
* @return a builder
*/

View File

@ -86,22 +86,24 @@ import static com.google.common.base.Preconditions.checkNotNull;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class GeneralCommands {
public static void register(CommandRegistrationHandler registration,
CommandManager commandManager,
CommandManagerService commandManagerService,
WorldEdit worldEdit) {
public static void register(
CommandRegistrationHandler registration,
CommandManager commandManager,
CommandManagerService commandManagerService,
WorldEdit worldEdit
) {
// Collect the tool commands
CommandManager collect = commandManagerService.newCommandManager();
registration.register(
collect,
GeneralCommandsRegistration.builder(),
new GeneralCommands(worldEdit)
collect,
GeneralCommandsRegistration.builder(),
new GeneralCommands(worldEdit)
);
Set<org.enginehub.piston.Command> commands = collect.getAllCommands()
.collect(Collectors.toSet());
.collect(Collectors.toSet());
for (org.enginehub.piston.Command command : commands) {
/*FAWE start - if in FAWE, //fast will remain for now
(command.getName().equals("/fast")) {
@ -120,15 +122,17 @@ public class GeneralCommands {
}
}
private static Component replaceFastForPerf(org.enginehub.piston.Command oldCmd,
CommandParameters oldParams) {
private static Component replaceFastForPerf(
org.enginehub.piston.Command oldCmd,
CommandParameters oldParams
) {
if (oldParams.getMetadata() == null) {
return CommandUtil.createNewCommandReplacementText("//perf");
}
ImmutableList<String> args = oldParams.getMetadata().getArguments();
if (args.isEmpty()) {
return TextComponent.of("There is not yet a replacement for //fast" +
" with no arguments");
" with no arguments");
}
String arg0 = args.get(0).toLowerCase(Locale.ENGLISH);
String flipped;
@ -158,13 +162,15 @@ public class GeneralCommands {
}
@Command(
name = "/limit",
desc = "Modify block change limit"
name = "/limit",
desc = "Modify block change limit"
)
@CommandPermissions("worldedit.limit")
public void limit(Actor actor, LocalSession session,
@Arg(desc = "The limit to set", def = "")
Integer limit) {
public void limit(
Actor actor, LocalSession session,
@Arg(desc = "The limit to set", def = "")
Integer limit
) {
LocalConfiguration config = worldEdit.getConfiguration();
boolean mayDisable = actor.hasPermission("worldedit.limit.unrestricted");
@ -186,13 +192,15 @@ public class GeneralCommands {
}
@Command(
name = "/timeout",
desc = "Modify evaluation timeout time."
name = "/timeout",
desc = "Modify evaluation timeout time."
)
@CommandPermissions("worldedit.timeout")
public void timeout(Actor actor, LocalSession session,
@Arg(desc = "The timeout time to set", def = "")
Integer limit) {
public void timeout(
Actor actor, LocalSession session,
@Arg(desc = "The timeout time to set", def = "")
Integer limit
) {
LocalConfiguration config = worldEdit.getConfiguration();
boolean mayDisable = actor.hasPermission("worldedit.timeout.unrestricted");
@ -213,19 +221,21 @@ public class GeneralCommands {
}
@Command(
name = "/perf",
desc = "Toggle side effects for performance",
descFooter = "Note that this command is GOING to change in the future." +
" Do not depend on the exact format of this command yet."
name = "/perf",
desc = "Toggle side effects for performance",
descFooter = "Note that this command is GOING to change in the future." +
" Do not depend on the exact format of this command yet."
)
@CommandPermissions("worldedit.perf")
void perf(Actor actor, LocalSession session,
@Arg(desc = "The side effect", def = "")
SideEffect sideEffect,
@Arg(desc = "The new side effect state", def = "")
SideEffect.State newState,
@Switch(name = 'h', desc = "Show the info box")
boolean showInfoBox) throws WorldEditException {
void perf(
Actor actor, LocalSession session,
@Arg(desc = "The side effect", def = "")
SideEffect sideEffect,
@Arg(desc = "The new side effect state", def = "")
SideEffect.State newState,
@Switch(name = 'h', desc = "Show the info box")
boolean showInfoBox
) throws WorldEditException {
if (sideEffect != null) {
SideEffect.State currentState = session.getSideEffectSet().getState(sideEffect);
if (newState != null && newState == currentState) {
@ -276,13 +286,15 @@ public class GeneralCommands {
}
@Command(
name = "/reorder",
desc = "Sets the reorder mode of WorldEdit"
name = "/reorder",
desc = "Sets the reorder mode of WorldEdit"
)
@CommandPermissions("worldedit.reorder")
public void reorderMode(Actor actor, LocalSession session,
@Arg(desc = "The reorder mode", def = "")
EditSession.ReorderMode reorderMode) {
public void reorderMode(
Actor actor, LocalSession session,
@Arg(desc = "The reorder mode", def = "")
EditSession.ReorderMode reorderMode
) {
if (reorderMode == null) {
actor.print(Caption.of("worldedit.reorder.current", TextComponent.of(session.getReorderMode().getDisplayName())));
} else {
@ -292,13 +304,15 @@ public class GeneralCommands {
}
@Command(
name = "/drawsel",
desc = "Toggle drawing the current selection"
name = "/drawsel",
desc = "Toggle drawing the current selection"
)
@CommandPermissions("worldedit.drawsel")
public void drawSelection(Player player, LocalSession session,
@Arg(desc = "The new draw selection state", def = "")
Boolean drawSelection) throws WorldEditException {
public void drawSelection(
Player player, LocalSession session,
@Arg(desc = "The new draw selection state", def = "")
Boolean drawSelection
) throws WorldEditException {
if (!WorldEdit.getInstance().getConfiguration().serverSideCUI) {
throw new AuthorizationException(Caption.of("worldedit.error.disabled"));
}
@ -316,17 +330,24 @@ public class GeneralCommands {
session.setUseServerCUI(true);
session.updateServerCUI(player);
int maxSize = ServerCUIHandler.getMaxServerCuiSize();
player.print(Caption.of("worldedit.drawsel.enabled", TextComponent.of(maxSize), TextComponent.of(maxSize), TextComponent.of(maxSize)));
player.print(Caption.of(
"worldedit.drawsel.enabled",
TextComponent.of(maxSize),
TextComponent.of(maxSize),
TextComponent.of(maxSize)
));
}
}
@Command(
name = "/world",
desc = "Sets the world override"
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) {
public void world(
Actor actor, LocalSession session,
@Arg(desc = "The world override", def = "") World world
) {
session.setWorldOverride(world);
if (world == null) {
actor.print(Caption.of("worldedit.world.remove"));
@ -336,15 +357,17 @@ public class GeneralCommands {
}
@Command(
name = "/watchdog",
desc = "Changes watchdog hook state.",
descFooter = "This is dependent on platform implementation. " +
"Not all platforms support watchdog hooks, or contain a watchdog."
name = "/watchdog",
desc = "Changes watchdog hook state.",
descFooter = "This is dependent on platform implementation. " +
"Not all platforms support watchdog hooks, or contain a watchdog."
)
@CommandPermissions("worldedit.watchdog")
public void watchdog(Actor actor, LocalSession session,
@Arg(desc = "The mode to set the watchdog hook to", def = "")
HookMode hookMode) {
public void watchdog(
Actor actor, LocalSession session,
@Arg(desc = "The mode to set the watchdog hook to", def = "")
HookMode hookMode
) {
if (WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWatchdog() == null) {
actor.print(Caption.of("worldedit.watchdog.no-hook"));
return;
@ -359,14 +382,16 @@ public class GeneralCommands {
}
@Command(
name = "gmask",
aliases = {"/gmask"},
desc = "Set the global mask"
name = "gmask",
aliases = {"/gmask"},
desc = "Set the global mask"
)
@CommandPermissions("worldedit.global-mask")
public void gmask(Actor actor, LocalSession session,
@Arg(desc = "The mask to set", def = "")
Mask mask) {
public void gmask(
Actor actor, LocalSession session,
@Arg(desc = "The mask to set", def = "")
Mask mask
) {
if (mask == null) {
session.setMask(null);
actor.print(Caption.of("worldedit.gmask.disabled"));
@ -377,9 +402,9 @@ public class GeneralCommands {
}
@Command(
name = "toggleplace",
aliases = {"/toggleplace"},
desc = "Switch between your position and pos1 for placement"
name = "toggleplace",
aliases = {"/toggleplace"},
desc = "Switch between your position and pos1 for placement"
)
@CommandPermissions("worldedit.toggleplace")
public void togglePlace(Actor actor, LocalSession session) {
@ -395,20 +420,22 @@ public class GeneralCommands {
}
@Command(
name = "searchitem",
aliases = {"/searchitem", "/l", "/search"},
desc = "Search for an item"
name = "searchitem",
aliases = {"/searchitem", "/l", "/search"},
desc = "Search for an item"
)
@CommandPermissions("worldedit.searchitem")
public void searchItem(Actor actor,
@Switch(name = 'b', desc = "Only search for blocks")
boolean blocksOnly,
@Switch(name = 'i', desc = "Only search for items")
boolean itemsOnly,
@ArgFlag(name = 'p', desc = "Page of results to return", def = "1")
int page,
@Arg(desc = "Search query", variable = true)
List<String> query) {
public void searchItem(
Actor actor,
@Switch(name = 'b', desc = "Only search for blocks")
boolean blocksOnly,
@Switch(name = 'i', desc = "Only search for items")
boolean itemsOnly,
@ArgFlag(name = 'p', desc = "Page of results to return", def = "1")
int page,
@Arg(desc = "Search query", variable = true)
List<String> query
) {
String search = String.join(" ", query);
if (search.length() <= 2) {
actor.print(Caption.of("worldedit.searchitem.too-short"));
@ -420,10 +447,12 @@ public class GeneralCommands {
}
WorldEditAsyncCommandBuilder.createAndSendMessage(actor, new ItemSearcher(search, blocksOnly, itemsOnly, page),
Caption.of("worldedit.searchitem.searching"));
Caption.of("worldedit.searchitem.searching")
);
}
private static class ItemSearcher implements Callable<Component> {
private final boolean blocksOnly;
private final boolean itemsOnly;
private final String search;
@ -454,15 +483,16 @@ public class GeneralCommands {
if (id.contains(idMatch)) {
Component name = searchType.getRichName();
results.put(id, TextComponent.builder()
.append(name)
.append(" (" + id + ")")
.build());
.append(name)
.append(" (" + id + ")")
.build());
}
}
List<Component> list = new ArrayList<>(results.values());
return PaginationBox.fromComponents("Search results for '" + search + "'", command, list)
.create(page);
.create(page);
}
}
//FAWE start
@ -473,7 +503,13 @@ public class GeneralCommands {
desc = "Set the global mask"
)
@CommandPermissions("worldedit.global-texture")
public void gtexture(Player player, World worldArg, LocalSession session, EditSession editSession, @Arg(name = "context", desc = "InjectedValueAccess", def = "") List<String> arguments) throws WorldEditException, FileNotFoundException {
public void gtexture(
Player player,
World worldArg,
LocalSession session,
EditSession editSession,
@Arg(name = "context", desc = "InjectedValueAccess", def = "") List<String> arguments
) throws WorldEditException, FileNotFoundException {
// gtexture <randomize> <min=0> <max=100>
// TODO NOT IMPLEMENTED convert this to an ArgumentConverter
if (arguments.isEmpty()) {
@ -536,13 +572,18 @@ public class GeneralCommands {
}
@Command(
name = "/gsmask",
aliases = {"gsmask", "globalsourcemask", "/globalsourcemask"},
desc = "Set the global source mask",
descFooter = "The global source mask applies to all edits you do and masks based on the source blocks (e.g., the blocks in your clipboard)"
name = "/gsmask",
aliases = {"gsmask", "globalsourcemask", "/globalsourcemask"},
desc = "Set the global source mask",
descFooter = "The global source mask applies to all edits you do and masks based on the source blocks (e.g., the blocks in your clipboard)"
)
@CommandPermissions({"worldedit.global-mask", "worldedit.mask.global"})
public void gsmask(Player player, LocalSession session, EditSession editSession, @Arg(desc = "The mask to set", def = "") Mask maskOpt) throws WorldEditException {
public void gsmask(
Player player,
LocalSession session,
EditSession editSession,
@Arg(desc = "The mask to set", def = "") Mask maskOpt
) throws WorldEditException {
session.setSourceMask(maskOpt);
if (maskOpt == null) {
player.print(Caption.of("fawe.worldedit.general.source.mask.disabled"));
@ -553,12 +594,13 @@ public class GeneralCommands {
@Command(
name = "/gtransform",
aliases = {"gtransform"},
desc = "Set the global transform"
name = "/gtransform",
aliases = {"gtransform"},
desc = "Set the global transform"
)
@CommandPermissions({"worldedit.global-transform", "worldedit.transform.global"})
public void gtransform(Player player, EditSession editSession, LocalSession session, ResettableExtent transform) throws WorldEditException {
public void gtransform(Player player, EditSession editSession, LocalSession session, ResettableExtent transform) throws
WorldEditException {
session.setTransform(transform);
if (transform == null) {
player.print(Caption.of("fawe.worldedit.general.transform.disabled"));
@ -568,9 +610,9 @@ public class GeneralCommands {
}
@Command(
name = "/tips",
aliases = {"tips"},
desc = "Toggle FAWE tips"
name = "/tips",
aliases = {"tips"},
desc = "Toggle FAWE tips"
)
@CommandPermissions("fawe.tips")
public void tips(Player player, LocalSession session) throws WorldEditException {
@ -587,9 +629,11 @@ public class GeneralCommands {
)
@CommandPermissions("worldedit.fast")
@Deprecated
void fast(Actor actor, LocalSession session,
@Arg(desc = "The new fast mode state", def = "")
Boolean fastMode) {
void fast(
Actor actor, LocalSession session,
@Arg(desc = "The new fast mode state", def = "")
Boolean fastMode
) {
boolean hasFastMode = session.hasFastMode();
if (fastMode != null && fastMode == hasFastMode) {
actor.print(Caption.of(fastMode ? "worldedit.fast.enabled.already" : "worldedit.fast.disabled.already"));

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.command;
import com.fastasyncworldedit.core.Fawe;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.function.generator.CavesGen;
import com.fastasyncworldedit.core.util.MainUtil;
import com.fastasyncworldedit.core.util.TextureUtil;
import com.fastasyncworldedit.core.util.image.ImageUtil;
@ -34,7 +35,6 @@ import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.command.util.annotation.Confirm;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.fastasyncworldedit.core.function.generator.CavesGen;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operations;
@ -58,7 +58,7 @@ import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.Switch;
import org.jetbrains.annotations.Range;
import java.awt.*;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
@ -89,38 +89,42 @@ public class GenerationCommands {
}
@Command(
name = "/hcyl",
desc = "Generates a hollow cylinder."
name = "/hcyl",
desc = "Generates a hollow cylinder."
)
@CommandPermissions("worldedit.generation.cylinder")
@Logging(PLACEMENT)
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. 1st is N/S, 2nd is E/W")
@Radii(2)
List<Double> radii,
@Arg(desc = "The height of the cylinder", def = "1")
int height) throws WorldEditException {
return cyl(actor, session, editSession, pattern, radii, height, true);
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. 1st is N/S, 2nd is E/W")
@Radii(2)
List<Double> radii,
@Arg(desc = "The height of the cylinder", def = "1")
int height
) throws WorldEditException {
return cyl(actor, session, editSession, pattern, radii, height, true);
}
@Command(
name = "/cyl",
desc = "Generates a cylinder."
name = "/cyl",
desc = "Generates a cylinder."
)
@CommandPermissions("worldedit.generation.cylinder")
@Logging(PLACEMENT)
public int cyl(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to generate")
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,
@Switch(name = 'h', desc = "Make a hollow cylinder")
boolean hollow) throws WorldEditException {
public int cyl(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to generate")
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,
@Switch(name = 'h', desc = "Make a hollow cylinder")
boolean hollow
) throws WorldEditException {
final double radiusX;
final double radiusZ;
switch (radii.size()) {
@ -149,38 +153,42 @@ public class GenerationCommands {
}
@Command(
name = "/hsphere",
desc = "Generates a hollow sphere."
name = "/hsphere",
desc = "Generates a hollow sphere."
)
@CommandPermissions("worldedit.generation.sphere")
@Logging(PLACEMENT)
public int hsphere(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to generate")
Pattern pattern,
@Arg(desc = "The radii of the sphere. Order is N/S, U/D, E/W")
@Radii(3)
List<Double> radii,
@Switch(name = 'r', desc = "Raise the bottom of the sphere to the placement position")
boolean raised) throws WorldEditException {
return sphere(actor, session, editSession, pattern, radii, raised, true);
public int hsphere(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to generate")
Pattern pattern,
@Arg(desc = "The radii of the sphere. Order is N/S, U/D, E/W")
@Radii(3)
List<Double> radii,
@Switch(name = 'r', desc = "Raise the bottom of the sphere to the placement position")
boolean raised
) throws WorldEditException {
return sphere(actor, session, editSession, pattern, radii, raised, true);
}
@Command(
name = "/sphere",
desc = "Generates a filled sphere."
name = "/sphere",
desc = "Generates a filled sphere."
)
@CommandPermissions("worldedit.generation.sphere")
@Logging(PLACEMENT)
public int sphere(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to generate")
Pattern pattern,
@Arg(desc = "The radii of the sphere. Order is N/S, U/D, E/W")
@Radii(3)
List<Double> radii,
@Switch(name = 'r', desc = "Raise the bottom of the sphere to the placement position")
boolean raised,
@Switch(name = 'h', desc = "Make a hollow sphere")
boolean hollow) throws WorldEditException {
public int sphere(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to generate")
Pattern pattern,
@Arg(desc = "The radii of the sphere. Order is N/S, U/D, E/W")
@Radii(3)
List<Double> radii,
@Switch(name = 'r', desc = "Raise the bottom of the sphere to the placement position")
boolean raised,
@Switch(name = 'h', desc = "Make a hollow sphere")
boolean hollow
) throws WorldEditException {
final double radiusX;
final double radiusY;
final double radiusZ;
@ -217,19 +225,21 @@ public class GenerationCommands {
}
@Command(
name = "forestgen",
aliases = { "/forestgen" },
desc = "Generate a forest"
name = "forestgen",
aliases = {"/forestgen"},
desc = "Generate a forest"
)
@CommandPermissions("worldedit.generation.forest")
@Logging(POSITION)
public int forestGen(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The size of the forest, in blocks", def = "10")
int size,
@Arg(desc = "The type of forest", def = "tree")
TreeType type,
@Arg(desc = "The density of the forest, between 0 and 100", def = "5")
double density) throws WorldEditException {
public int forestGen(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The size of the forest, in blocks", def = "10")
int size,
@Arg(desc = "The type of forest", def = "tree")
TreeType type,
@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;
@ -239,17 +249,19 @@ public class GenerationCommands {
}
@Command(
name = "pumpkins",
aliases = { "/pumpkins" },
desc = "Generate pumpkin patches"
name = "pumpkins",
aliases = {"/pumpkins"},
desc = "Generate pumpkin patches"
)
@CommandPermissions("worldedit.generation.pumpkins")
@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 = "0.02")
double density) throws WorldEditException {
public int pumpkins(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The size of the patch", def = "10")
int size,
@Arg(desc = "//TODO ", def = "0.02")
double density
) throws WorldEditException {
checkCommandArgument(0 <= density && density <= 100, "Density must be between 0 and 100");
worldEdit.checkMaxRadius(size);
int affected = editSession.makePumpkinPatches(session.getPlacementPosition(actor), size, density);
@ -258,32 +270,36 @@ public class GenerationCommands {
}
@Command(
name = "/hpyramid",
desc = "Generate a hollow pyramid"
name = "/hpyramid",
desc = "Generate a hollow pyramid"
)
@CommandPermissions("worldedit.generation.pyramid")
@Logging(PLACEMENT)
public int hollowPyramid(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern,
@Confirm(Confirm.Processor.RADIUS) @Arg(desc = "The size of the pyramid")
int size) throws WorldEditException {
public int hollowPyramid(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern,
@Confirm(Confirm.Processor.RADIUS) @Arg(desc = "The size of the pyramid")
int size
) throws WorldEditException {
return pyramid(actor, session, editSession, pattern, size, true);
}
@Command(
name = "/pyramid",
desc = "Generate a filled pyramid"
name = "/pyramid",
desc = "Generate a filled pyramid"
)
@CommandPermissions("worldedit.generation.pyramid")
@Logging(PLACEMENT)
public int pyramid(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern,
@Confirm(Confirm.Processor.RADIUS) @Arg(desc = "The size of the pyramid")
int size,
@Switch(name = 'h', desc = "Make a hollow pyramid")
boolean hollow) throws WorldEditException {
public int pyramid(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern,
@Confirm(Confirm.Processor.RADIUS) @Arg(desc = "The size of the pyramid")
int size,
@Switch(name = 'h', desc = "Make a hollow pyramid")
boolean hollow
) throws WorldEditException {
worldEdit.checkMaxRadius(size);
BlockVector3 pos = session.getPlacementPosition(actor);
int affected = editSession.makePyramid(pos, pattern, size, !hollow);
@ -295,28 +311,30 @@ public class GenerationCommands {
}
@Command(
name = "/generate",
aliases = { "/gen", "/g" },
desc = "Generates a shape according to a formula.",
descFooter = "See also https://tinyurl.com/weexpr."
name = "/generate",
aliases = {"/gen", "/g"},
desc = "Generates a shape according to a formula.",
descFooter = "See also https://tinyurl.com/weexpr."
)
@CommandPermissions("worldedit.generation.shape")
@Logging(ALL)
@Confirm(Confirm.Processor.REGION)
public int generate(Actor actor, LocalSession session, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern,
@Arg(desc = "Expression to test block placement locations and set block type", variable = true)
List<String> expression,
@Switch(name = 'h', desc = "Generate a hollow shape")
boolean hollow,
@Switch(name = 'r', desc = "Use the game's coordinate origin")
boolean useRawCoords,
@Switch(name = 'o', desc = "Use the placement's coordinate origin")
boolean offset,
@Switch(name = 'c', desc = "Use the selection's center as origin")
boolean offsetCenter) throws WorldEditException {
public int generate(
Actor actor, LocalSession session, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern,
@Arg(desc = "Expression to test block placement locations and set block type", variable = true)
List<String> expression,
@Switch(name = 'h', desc = "Generate a hollow shape")
boolean hollow,
@Switch(name = 'r', desc = "Use the game's coordinate origin")
boolean useRawCoords,
@Switch(name = 'o', desc = "Use the placement's coordinate origin")
boolean offset,
@Switch(name = 'c', desc = "Use the selection's center as origin")
boolean offsetCenter
) throws WorldEditException {
final Vector3 zero;
Vector3 unit;
@ -354,7 +372,15 @@ public class GenerationCommands {
final Vector3 unit1 = unit;
try {
final int affected = editSession.makeShape(region, zero, unit1, pattern, String.join(" ", expression), hollow, session.getTimeout());
final int affected = editSession.makeShape(
region,
zero,
unit1,
pattern,
String.join(" ", expression),
hollow,
session.getTimeout()
);
if (actor instanceof Player) {
((Player) actor).findFreePosition();
}
@ -367,30 +393,32 @@ public class GenerationCommands {
}
@Command(
name = "/generatebiome",
aliases = { "/genbiome", "/gb" },
desc = "Sets biome according to a formula.",
descFooter = "Formula must return positive numbers (true) if the point is inside the shape\n"
+ "Sets the biome of blocks in that shape.\n"
+ "See also https://tinyurl.com/weexpr."
name = "/generatebiome",
aliases = {"/genbiome", "/gb"},
desc = "Sets biome according to a formula.",
descFooter = "Formula must return positive numbers (true) if the point is inside the shape\n"
+ "Sets the biome of blocks in that shape.\n"
+ "See also https://tinyurl.com/weexpr."
)
@CommandPermissions("worldedit.generation.shape.biome")
@Logging(ALL)
@Confirm(Confirm.Processor.REGION)
public int generateBiome(Actor actor, LocalSession session, EditSession editSession,
@Selection Region region,
@Arg(desc = "The biome type to set")
BiomeType target,
@Arg(desc = "Expression to test block placement locations and set biome type", variable = true)
List<String> expression,
@Switch(name = 'h', desc = "Generate a hollow shape")
boolean hollow,
@Switch(name = 'r', desc = "Use the game's coordinate origin")
boolean useRawCoords,
@Switch(name = 'o', desc = "Use the placement's coordinate origin")
boolean offset,
@Switch(name = 'c', desc = "Use the selection's center as origin")
boolean offsetCenter) throws WorldEditException {
public int generateBiome(
Actor actor, LocalSession session, EditSession editSession,
@Selection Region region,
@Arg(desc = "The biome type to set")
BiomeType target,
@Arg(desc = "Expression to test block placement locations and set biome type", variable = true)
List<String> expression,
@Switch(name = 'h', desc = "Generate a hollow shape")
boolean hollow,
@Switch(name = 'r', desc = "Use the game's coordinate origin")
boolean useRawCoords,
@Switch(name = 'o', desc = "Use the placement's coordinate origin")
boolean offset,
@Switch(name = 'c', desc = "Use the selection's center as origin")
boolean offsetCenter
) throws WorldEditException {
final Vector3 zero;
Vector3 unit;
@ -426,7 +454,15 @@ public class GenerationCommands {
final Vector3 unit1 = unit;
try {
final int affected = editSession.makeBiomeShape(region, zero, unit1, target, String.join(" ", expression), hollow, session.getTimeout());
final int affected = editSession.makeBiomeShape(
region,
zero,
unit1,
target,
String.join(" ", expression),
hollow,
session.getTimeout()
);
actor.print(Caption.of("worldedit.generatebiome.changed", TextComponent.of(affected)));
return affected;
} catch (ExpressionException e) {
@ -443,18 +479,31 @@ public class GenerationCommands {
@CommandPermissions("worldedit.generation.caves")
@Logging(PLACEMENT)
@Confirm(Confirm.Processor.REGION)
public void caves(Actor actor, LocalSession session, EditSession editSession, @Selection Region region,
@Arg(name = "size", desc = "TODO", def = "8") int sizeOpt,
@Arg(name = "frequency", desc = "TODO", def = "40") int frequencyOpt,
@Arg(name = "rarity", desc = "TODO", def = "7") int rarityOpt,
@Arg(name = "minY", desc = "TODO", def = "8") int minYOpt,
@Arg(name = "maxY", desc = "TODO", def = "127") int maxYOpt,
@Arg(name = "systemFrequency", desc = "TODO", def = "1") int systemFrequencyOpt,
@Arg(name = "individualRarity", desc = "TODO", def = "25") int individualRarityOpt,
@Arg(name = "pocketChance", desc = "TODO", def = "0") int pocketChanceOpt,
@Arg(name = "pocketMin", desc = "TODO", def = "0") int pocketMinOpt,
@Arg(name = "pocketMax", desc = "TODO", def = "3") int pocketMaxOpt) throws WorldEditException {
CavesGen gen = new CavesGen(sizeOpt, frequencyOpt, rarityOpt, minYOpt, maxYOpt, systemFrequencyOpt, individualRarityOpt, pocketChanceOpt, pocketMinOpt, pocketMaxOpt);
public void caves(
Actor actor, LocalSession session, EditSession editSession, @Selection Region region,
@Arg(name = "size", desc = "TODO", def = "8") int sizeOpt,
@Arg(name = "frequency", desc = "TODO", def = "40") int frequencyOpt,
@Arg(name = "rarity", desc = "TODO", def = "7") int rarityOpt,
@Arg(name = "minY", desc = "TODO", def = "8") int minYOpt,
@Arg(name = "maxY", desc = "TODO", def = "127") int maxYOpt,
@Arg(name = "systemFrequency", desc = "TODO", def = "1") int systemFrequencyOpt,
@Arg(name = "individualRarity", desc = "TODO", def = "25") int individualRarityOpt,
@Arg(name = "pocketChance", desc = "TODO", def = "0") int pocketChanceOpt,
@Arg(name = "pocketMin", desc = "TODO", def = "0") int pocketMinOpt,
@Arg(name = "pocketMax", desc = "TODO", def = "3") int pocketMaxOpt
) throws WorldEditException {
CavesGen gen = new CavesGen(
sizeOpt,
frequencyOpt,
rarityOpt,
minYOpt,
maxYOpt,
systemFrequencyOpt,
individualRarityOpt,
pocketChanceOpt,
pocketMinOpt,
pocketMaxOpt
);
editSession.generate(region, gen);
actor.print(Caption.of("fawe.worldedit.visitor.visitor.block", editSession.getBlockChangeCount()));
}
@ -467,7 +516,13 @@ public class GenerationCommands {
@CommandPermissions("worldedit.generation.ore")
@Logging(PLACEMENT)
@Confirm(Confirm.Processor.REGION)
public void ores(Actor actor, LocalSession session, EditSession editSession, @Selection Region region, @Arg(desc = "Mask") Mask mask) throws WorldEditException {
public void ores(
Actor actor,
LocalSession session,
EditSession editSession,
@Selection Region region,
@Arg(desc = "Mask") Mask mask
) throws WorldEditException {
if (mask instanceof AbstractExtentMask) {
((AbstractExtentMask) mask).setExtent(editSession);
}
@ -477,18 +532,20 @@ public class GenerationCommands {
@Command(
name = "/img",
aliases = { "/image", "image" },
aliases = {"/image", "image"},
desc = "Generate an image"
)
@CommandPermissions("worldedit.generation.image")
@Logging(PLACEMENT)
public void image(Actor actor,
LocalSession session,
EditSession editSession,
@Arg(desc = "Image URL (imgur only)") String imageURL,
@Arg(desc = "boolean", def = "true") boolean randomize,
@Arg(desc = "TODO", def = "100") int threshold,
@Arg(desc = "BlockVector2", def = "") BlockVector2 dimensions) throws WorldEditException, IOException {
public void image(
Actor actor,
LocalSession session,
EditSession editSession,
@Arg(desc = "Image URL (imgur only)") String imageURL,
@Arg(desc = "boolean", def = "true") boolean randomize,
@Arg(desc = "TODO", def = "100") int threshold,
@Arg(desc = "BlockVector2", def = "") BlockVector2 dimensions
) throws WorldEditException, IOException {
TextureUtil tu = Fawe.get().getCachedTextureUtil(randomize, 0, threshold);
URL url = new URL(imageURL);
if (!url.getHost().equalsIgnoreCase("i.imgur.com")) {
@ -497,7 +554,8 @@ public class GenerationCommands {
BufferedImage image = MainUtil.readImage(url);
if (dimensions != null) {
image = ImageUtil.getScaledInstance(image, dimensions.getBlockX(), dimensions.getBlockZ(),
RenderingHints.VALUE_INTERPOLATION_BILINEAR, false);
RenderingHints.VALUE_INTERPOLATION_BILINEAR, false
);
}
BlockVector3 pos1 = session.getPlacementPosition(actor);
@ -529,17 +587,19 @@ public class GenerationCommands {
@CommandPermissions("worldedit.generation.ore")
@Logging(PLACEMENT)
@Confirm(Confirm.Processor.REGION)
public void ore(Actor actor,
LocalSession session,
EditSession editSession,
@Selection Region region,
@Arg(desc = "Mask") Mask mask,
@Arg(desc = "Pattern") Pattern material,
@Arg(desc = "Ore vein size") @Range(from = 0, to = Integer.MAX_VALUE) int size,
@Arg(desc = "Ore vein frequency (number of times to attempt to place ore)", def = "10") @Range(from = 0, to = Integer.MAX_VALUE) int freq,
@Arg(desc = "Ore vein rarity (% chance each attempt is placed)", def = "100") @Range(from = 0, to = 100) int rarity,
@Arg(desc = "Ore vein min y", def = "0") @Range(from = 0, to = 255) int minY,
@Arg(desc = "Ore vein max y", def = "63") @Range(from = 0, to = 255) int maxY) throws WorldEditException {
public void ore(
Actor actor,
LocalSession session,
EditSession editSession,
@Selection Region region,
@Arg(desc = "Mask") Mask mask,
@Arg(desc = "Pattern") Pattern material,
@Arg(desc = "Ore vein size") @Range(from = 0, to = Integer.MAX_VALUE) int size,
@Arg(desc = "Ore vein frequency (number of times to attempt to place ore)", def = "10") @Range(from = 0, to = Integer.MAX_VALUE) int freq,
@Arg(desc = "Ore vein rarity (% chance each attempt is placed)", def = "100") @Range(from = 0, to = 100) int rarity,
@Arg(desc = "Ore vein min y", def = "0") @Range(from = 0, to = 255) int minY,
@Arg(desc = "Ore vein max y", def = "63") @Range(from = 0, to = 255) int maxY
) throws WorldEditException {
if (mask instanceof AbstractExtentMask) {
((AbstractExtentMask) mask).setExtent(editSession);
}

View File

@ -56,16 +56,18 @@ public class HistoryCommands {
}
@Command(
name = "undo",
aliases = { "/undo" },
desc = "Undoes the last action (from history)"
name = "undo",
aliases = {"/undo"},
desc = "Undoes the last action (from history)"
)
@CommandPermissions({"worldedit.history.undo", "worldedit.history.undo.self"})
public void undo(Actor actor, LocalSession session,
@Confirm(Confirm.Processor.LIMIT) @Arg(desc = "Number of undoes to perform", def = "1")
int times,
@Arg(name = "player", desc = "Undo this player's operations", def = "")
String playerName) throws WorldEditException {
public void undo(
Actor actor, LocalSession session,
@Confirm(Confirm.Processor.LIMIT) @Arg(desc = "Number of undoes to perform", def = "1")
int times,
@Arg(name = "player", desc = "Undo this player's operations", def = "")
String playerName
) throws WorldEditException {
times = Math.max(1, times);
LocalSession undoSession = session;
//FAWE start - Add fastmode check
@ -101,16 +103,18 @@ public class HistoryCommands {
}
@Command(
name = "redo",
aliases = { "/redo" },
desc = "Redoes the last action (from history)"
name = "redo",
aliases = {"/redo"},
desc = "Redoes the last action (from history)"
)
@CommandPermissions({"worldedit.history.redo", "worldedit.history.redo.self"})
public void redo(Actor actor, LocalSession session,
@Confirm(Confirm.Processor.LIMIT) @Arg(desc = "Number of redoes to perform", def = "1")
int times,
@Arg(name = "player", desc = "Redo this player's operations", def = "")
String playerName) throws WorldEditException {
public void redo(
Actor actor, LocalSession session,
@Confirm(Confirm.Processor.LIMIT) @Arg(desc = "Number of redoes to perform", def = "1")
int times,
@Arg(name = "player", desc = "Redo this player's operations", def = "")
String playerName
) throws WorldEditException {
times = Math.max(1, times);
LocalSession redoSession = session;
if (playerName != null) {
@ -140,9 +144,9 @@ public class HistoryCommands {
}
@Command(
name = "clearhistory",
aliases = { "/clearhistory" },
desc = "Clear your history"
name = "clearhistory",
aliases = {"/clearhistory"},
desc = "Clear your history"
)
@CommandPermissions("worldedit.history.clear")
public void clearHistory(Actor actor, LocalSession session) {

View File

@ -7,8 +7,8 @@ import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.database.DBHandler;
import com.fastasyncworldedit.core.database.RollbackDatabase;
import com.fastasyncworldedit.core.history.RollbackOptimizedHistory;
import com.fastasyncworldedit.core.regions.RegionWrapper;
import com.fastasyncworldedit.core.history.changeset.SimpleChangeSetSummary;
import com.fastasyncworldedit.core.regions.RegionWrapper;
import com.fastasyncworldedit.core.util.MainUtil;
import com.fastasyncworldedit.core.util.StringMan;
import com.google.common.base.Function;
@ -18,12 +18,12 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.argument.Arguments;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.annotation.AllowedRegion;
import com.sk89q.worldedit.command.util.annotation.Confirm;
import com.sk89q.worldedit.command.util.annotation.Time;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.history.changeset.ChangeSet;
import com.sk89q.worldedit.command.util.annotation.AllowedRegion;
import com.sk89q.worldedit.command.util.annotation.Time;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
@ -45,9 +45,10 @@ import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch;
import javax.annotation.Nonnull;
import org.jetbrains.annotations.Range;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
@ -56,7 +57,6 @@ import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import static com.sk89q.worldedit.internal.command.CommandUtil.checkCommandArgument;
@ -70,46 +70,50 @@ public class HistorySubCommands {
}
@Command(
name = "restore",
aliases = {"rerun"},
desc = "Rerun edits"
+ " - The time uses s, m, h, d, y.\n"
+ " - Import from disk: /history import"
name = "restore",
aliases = {"rerun"},
desc = "Rerun edits"
+ " - The time uses s, m, h, d, y.\n"
+ " - Import from disk: /history import"
)
@CommandPermissions("worldedit.history.restore")
@Confirm
public synchronized void rerun(Player player, World world, RollbackDatabase database,
@AllowedRegion Region[] allowedRegions,
@ArgFlag(name = 'u', desc = "String user", def = "me")
UUID other,
@ArgFlag(name = 'r', def = "0", desc = "radius")
@Range(from = 0, to = Integer.MAX_VALUE)
int radius,
@ArgFlag(name = 't', desc = "Time e.g. 20s", def = "0")
@Time
long timeDiff) throws WorldEditException {
public synchronized void rerun(
Player player, World world, RollbackDatabase database,
@AllowedRegion Region[] allowedRegions,
@ArgFlag(name = 'u', desc = "String user", def = "me")
UUID other,
@ArgFlag(name = 'r', def = "0", desc = "radius")
@Range(from = 0, to = Integer.MAX_VALUE)
int radius,
@ArgFlag(name = 't', desc = "Time e.g. 20s", def = "0")
@Time
long timeDiff
) throws WorldEditException {
rollback(player, world, database, allowedRegions, other, radius, timeDiff, true);
}
@Command(
name = "rollback",
desc = "Undo a specific edit. "
+ " - The time uses s, m, h, d, y."
name = "rollback",
desc = "Undo a specific edit. "
+ " - The time uses s, m, h, d, y."
)
@CommandPermissions("worldedit.history.rollback")
@Confirm
public synchronized void rollback(Player player, World world, RollbackDatabase database,
@AllowedRegion Region[] allowedRegions,
@ArgFlag(name = 'u', desc = "String user", def = "")
UUID other,
@ArgFlag(name = 'r', def = "0", desc = "radius")
@Range(from = 0, to = Integer.MAX_VALUE)
int radius,
@ArgFlag(name = 't', desc = "Time e.g. 20s", def = "0")
@Time
long timeDiff,
@Switch(name = 'f', desc = "Restore instead of rollback")
boolean restore) throws WorldEditException {
public synchronized void rollback(
Player player, World world, RollbackDatabase database,
@AllowedRegion Region[] allowedRegions,
@ArgFlag(name = 'u', desc = "String user", def = "")
UUID other,
@ArgFlag(name = 'r', def = "0", desc = "radius")
@Range(from = 0, to = Integer.MAX_VALUE)
int radius,
@ArgFlag(name = 't', desc = "Time e.g. 20s", def = "0")
@Time
long timeDiff,
@Switch(name = 'f', desc = "Restore instead of rollback")
boolean restore
) throws WorldEditException {
if (!Settings.IMP.HISTORY.USE_DATABASE) {
player.print(Caption.of("fawe.error.setting.disable", "history.use-database (Import with /history import )"));
return;
@ -152,10 +156,10 @@ public class HistorySubCommands {
}
@Command(
name = "import",
desc = "Import history into the database"
+ " - The time uses s, m, h, d, y.\n"
+ " - Import from disk: /history import"
name = "import",
desc = "Import history into the database"
+ " - The time uses s, m, h, d, y.\n"
+ " - Import from disk: /history import"
)
@CommandPermissions("fawe.rollback.import")
@Confirm
@ -182,14 +186,16 @@ public class HistorySubCommands {
RollbackOptimizedHistory rollback = new RollbackOptimizedHistory(
world, uuid,
Integer.parseInt(
name.substring(0, name.length() - 3)));
name.substring(0, name.length() - 3))
);
SimpleChangeSetSummary summary = rollback
.summarize(RegionWrapper.GLOBAL(), false);
if (summary != null) {
rollback.setDimensions(
BlockVector3.at(summary.minX, 0, summary.minZ),
BlockVector3
.at(summary.maxX, 255, summary.maxZ));
.at(summary.maxX, 255, summary.maxZ)
);
rollback.setTime(historyFile.lastModified());
RollbackDatabase db = DBHandler.IMP
.getDatabase(world);
@ -209,16 +215,18 @@ public class HistorySubCommands {
}
@Command(
name = "info",
aliases = {"summary", "summarize"},
desc = "Summarize an edit"
name = "info",
aliases = {"summary", "summarize"},
desc = "Summarize an edit"
)
@CommandPermissions("worldedit.history.info")
public synchronized void summary(Player player, RollbackDatabase database, Arguments arguments,
@Arg(desc = "Player uuid/name")
UUID other,
@Arg(desc = "edit index")
Integer index) throws WorldEditException, ExecutionException, InterruptedException {
public synchronized void summary(
Player player, RollbackDatabase database, Arguments arguments,
@Arg(desc = "Player uuid/name")
UUID other,
@Arg(desc = "edit index")
Integer index
) throws WorldEditException, ExecutionException, InterruptedException {
RollbackOptimizedHistory edit = database.getEdit(other, index).get();
if (edit == null) {
player.print(Caption.of("fawe.worldedit.schematic.schematic.none"));
@ -231,8 +239,8 @@ public class HistorySubCommands {
BlockVector3 pos1 = edit.getMinimumPoint();
BlockVector3 pos2 = edit.getMaximumPoint();
double distanceX = Math.min( Math.abs(pos1.getX() - origin.getX()), Math.abs(pos2.getX() - origin.getX()));
double distanceZ = Math.min( Math.abs(pos1.getZ() - origin.getZ()), Math.abs(pos2.getZ() - origin.getZ()));
double distanceX = Math.min(Math.abs(pos1.getX() - origin.getX()), Math.abs(pos2.getX() - origin.getX()));
double distanceZ = Math.min(Math.abs(pos1.getZ() - origin.getZ()), Math.abs(pos2.getZ() - origin.getZ()));
int distance = (int) Math.sqrt(distanceX * distanceX + distanceZ * distanceZ);
BlockVector2 dirVec = BlockVector2.at(edit.getOriginX() - origin.getX(), edit.getOriginZ() - origin.getZ());
@ -248,7 +256,14 @@ public class HistorySubCommands {
boolean createdTiles = edit.getNbttFile().exists();
boolean removedTiles = edit.getNbtfFile().exists();
TranslatableComponent header = Caption.of("fawe.worldedit.history.find.element", name, timeStr, distance, direction.name(), cmd);
TranslatableComponent header = Caption.of(
"fawe.worldedit.history.find.element",
name,
timeStr,
distance,
direction.name(),
cmd
);
String sizeStr = StringMan.humanReadableByteCountBin(edit.getSizeOnDisk());
String extra = "";
@ -268,74 +283,101 @@ public class HistorySubCommands {
extra += "-tile, ";
}
TranslatableComponent body = Caption.of("fawe.worldedit.history.find.element.more", size, edit.getMinimumPoint(), edit.getMaximumPoint(), extra.trim(), sizeStr);
Component distr = TextComponent.of("/history distr").clickEvent(ClickEvent.suggestCommand("//history distr " + other + " " + index));
TranslatableComponent body = Caption.of(
"fawe.worldedit.history.find.element.more",
size,
edit.getMinimumPoint(),
edit.getMaximumPoint(),
extra.trim(),
sizeStr
);
Component distr = TextComponent
.of("/history distr")
.clickEvent(ClickEvent.suggestCommand("//history distr " + other + " " + index));
TextComponentProducer content = new TextComponentProducer().append(header).newline().append(body).newline().append(distr);
player.print(content.create());
}
private PaginationBox list(RollbackDatabase database, String pageCommand, List<Supplier<? extends ChangeSet>> histories, BlockVector3 origin) {
return PaginationBox.fromStrings("Edits:", pageCommand, histories, new Function<Supplier<? extends ChangeSet>, Component>() {
@Nonnull
@Override
public Component apply(@Nullable Supplier<? extends ChangeSet> input) {
ChangeSet edit = input.get();
private PaginationBox list(
RollbackDatabase database,
String pageCommand,
List<Supplier<? extends ChangeSet>> histories,
BlockVector3 origin
) {
return PaginationBox.fromStrings("Edits:", pageCommand, histories, new Function<>() {
@Nonnull
@Override
public Component apply(@Nullable Supplier<? extends ChangeSet> input) {
ChangeSet edit = input.get();
if (edit instanceof RollbackOptimizedHistory) {
RollbackOptimizedHistory rollback = (RollbackOptimizedHistory) edit;
if (edit instanceof RollbackOptimizedHistory) {
RollbackOptimizedHistory rollback = (RollbackOptimizedHistory) edit;
UUID uuid = rollback.getUUID();
int index = rollback.getIndex();
String name = Fawe.imp().getName(rollback.getUUID());
UUID uuid = rollback.getUUID();
int index = rollback.getIndex();
String name = Fawe.imp().getName(rollback.getUUID());
String cmd = rollback.getCommand();
BlockVector3 pos1 = rollback.getMinimumPoint();
BlockVector3 pos2 = rollback.getMaximumPoint();
String cmd = rollback.getCommand();
BlockVector3 pos1 = rollback.getMinimumPoint();
BlockVector3 pos2 = rollback.getMaximumPoint();
double distanceX = Math.min(Math.abs(pos1.getX() - origin.getX()), Math.abs(pos2.getX() - origin.getX()));
double distanceZ = Math.min(Math.abs(pos1.getZ() - origin.getZ()), Math.abs(pos2.getZ() - origin.getZ()));
int distance = (int) Math.sqrt(distanceX * distanceX + distanceZ * distanceZ);
double distanceX = Math.min(Math.abs(pos1.getX() - origin.getX()), Math.abs(pos2.getX() - origin.getX()));
double distanceZ = Math.min(Math.abs(pos1.getZ() - origin.getZ()), Math.abs(pos2.getZ() - origin.getZ()));
int distance = (int) Math.sqrt(distanceX * distanceX + distanceZ * distanceZ);
BlockVector2 dirVec = BlockVector2.at(rollback.getOriginX() - origin.getX(), rollback.getOriginZ() - origin.getZ());
Direction direction = Direction.findClosest(dirVec.toVector3(), Direction.Flag.ALL);
BlockVector2 dirVec = BlockVector2.at(
rollback.getOriginX() - origin.getX(),
rollback.getOriginZ() - origin.getZ()
);
Direction direction = Direction.findClosest(dirVec.toVector3(), Direction.Flag.ALL);
long seconds = (System.currentTimeMillis() - rollback.getBDFile().lastModified()) / 1000;
String timeStr = MainUtil.secToTime(seconds);
long seconds = (System.currentTimeMillis() - rollback.getBDFile().lastModified()) / 1000;
String timeStr = MainUtil.secToTime(seconds);
int size = edit.size();
int size = edit.size();
TranslatableComponent elem = Caption.of("fawe.worldedit.history.find.element", name, timeStr, distance, direction.name(), cmd);
TranslatableComponent elem = Caption.of(
"fawe.worldedit.history.find.element",
name,
timeStr,
distance,
direction.name(),
cmd
);
String infoCmd = "//history summary " + uuid + " " + index;
TranslatableComponent hover = Caption.of("fawe.worldedit.history.find.hover", size);
elem = elem.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, hover));
elem = elem.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, infoCmd));
return elem;
} else {
// TODO
return TextComponent.empty();
String infoCmd = "//history summary " + uuid + " " + index;
TranslatableComponent hover = Caption.of("fawe.worldedit.history.find.hover", size);
elem = elem.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, hover));
elem = elem.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, infoCmd));
return elem;
} else {
// TODO
return TextComponent.empty();
}
}
}
}
});
);
}
@Command(
name = "find",
aliases = {"inspect", "search", "near"},
desc = "Find nearby edits"
name = "find",
aliases = {"inspect", "search", "near"},
desc = "Find nearby edits"
)
@CommandPermissions("worldedit.history.find")
public synchronized void find(Player player, World world, RollbackDatabase database, Arguments arguments,
@ArgFlag(name = 'u', def = "", desc = "String user")
UUID other,
@ArgFlag(name = 'r', def = "0", desc = "radius")
@Range(from = 0, to = Integer.MAX_VALUE)
Integer radius,
@ArgFlag(name = 't', desc = "Time e.g. 20s", def = "0")
@Time
Long timeDiff,
@ArgFlag(name = 'p', desc = "Page to view.", def = "")
Integer page) throws WorldEditException {
public synchronized void find(
Player player, World world, RollbackDatabase database, Arguments arguments,
@ArgFlag(name = 'u', def = "", desc = "String user")
UUID other,
@ArgFlag(name = 'r', def = "0", desc = "radius")
@Range(from = 0, to = Integer.MAX_VALUE)
Integer radius,
@ArgFlag(name = 't', desc = "Time e.g. 20s", def = "0")
@Time
Long timeDiff,
@ArgFlag(name = 'p', desc = "Page to view.", def = "")
Integer page
) throws WorldEditException {
if (!Settings.IMP.HISTORY.USE_DATABASE) {
player.print(Caption.of("fawe.error.setting.disable", "history.use-database (Import with //history import )"));
return;
@ -379,18 +421,20 @@ public class HistorySubCommands {
}
@Command(
name = "distr",
aliases = {"distribution"},
desc = "View block distribution for an edit"
name = "distr",
aliases = {"distribution"},
desc = "View block distribution for an edit"
)
@CommandPermissions("worldedit.history.distr")
public void distr(Player player, LocalSession session, RollbackDatabase database, Arguments arguments,
@Arg(desc = "Player uuid/name")
UUID other,
@Arg(desc = "edit index")
Integer index,
@ArgFlag(name = 'p', desc = "Page to view.", def = "")
Integer page) throws ExecutionException, InterruptedException {
public void distr(
Player player, LocalSession session, RollbackDatabase database, Arguments arguments,
@Arg(desc = "Player uuid/name")
UUID other,
@Arg(desc = "edit index")
Integer index,
@ArgFlag(name = 'p', desc = "Page to view.", def = "")
Integer page
) throws ExecutionException, InterruptedException {
String pageCommand = "/" + arguments.get().replaceAll("-p [0-9]+", "").trim();
Reference<PaginationBox> cached = player.getMeta(pageCommand);
PaginationBox pages = cached == null ? null : cached.get();
@ -399,7 +443,11 @@ public class HistorySubCommands {
SimpleChangeSetSummary summary = edit.summarize(RegionWrapper.GLOBAL(), false);
if (summary != null) {
List<Countable<BlockState>> distr = summary.getBlockDistributionWithData();
SelectionCommands.BlockDistributionResult distrPages = new SelectionCommands.BlockDistributionResult((List) distr, true, pageCommand);
SelectionCommands.BlockDistributionResult distrPages = new SelectionCommands.BlockDistributionResult(
distr,
true,
pageCommand
);
pages = new PaginationBox.MergedPaginationBox("Block Distribution", pageCommand, pages, distrPages);
player.setMeta(pageCommand, new SoftReference<>(pages));
}
@ -413,17 +461,22 @@ public class HistorySubCommands {
}
@Command(
name = "list",
desc = "List your history"
name = "list",
desc = "List your history"
)
@CommandPermissions("worldedit.history.list")
public void list(Player player, LocalSession session, RollbackDatabase database, Arguments arguments,
@Arg(desc = "Player uuid/name")
UUID other,
@ArgFlag(name = 'p', desc = "Page to view.", def = "")
Integer page) {
public void list(
Player player, LocalSession session, RollbackDatabase database, Arguments arguments,
@Arg(desc = "Player uuid/name")
UUID other,
@ArgFlag(name = 'p', desc = "Page to view.", def = "")
Integer page
) {
int index = session.getHistoryIndex();
List<Supplier<? extends ChangeSet>> history = Lists.transform(session.getHistory(), (Function<ChangeSet, Supplier<ChangeSet>>) input -> () -> input);
List<Supplier<? extends ChangeSet>> history = Lists.transform(
session.getHistory(),
(Function<ChangeSet, Supplier<ChangeSet>>) input -> () -> input
);
Location origin = player.getLocation();
String pageCommand = "/" + arguments.get().replaceAll("-p [0-9]+", "").trim();
Reference<PaginationBox> cached = player.getMeta(pageCommand);
@ -436,11 +489,12 @@ public class HistorySubCommands {
}
@Command(
name = "clear",
desc = "Clear your history"
name = "clear",
desc = "Clear your history"
)
@CommandPermissions("worldedit.history.clear")
public void clearHistory(Actor actor, LocalSession session) {
parent.clearHistory(actor, session);
}
}

View File

@ -74,11 +74,11 @@ class LegacySnapshotCommands {
try {
WorldEdit.logger.info("WorldEdit found no snapshots: looked in: "
+ dir.getCanonicalPath());
+ dir.getCanonicalPath());
} catch (IOException e) {
WorldEdit.logger.info("WorldEdit found no snapshots: looked in "
+ "(NON-RESOLVABLE PATH - does it exist?): "
+ dir.getPath());
+ "(NON-RESOLVABLE PATH - does it exist?): "
+ dir.getPath());
}
}
} catch (MissingWorldException ex) {
@ -147,8 +147,9 @@ class LegacySnapshotCommands {
if (snapshot == null) {
actor.print(Caption.of(
"worldedit.snapshot.none-before",
TextComponent.of(dateFormat.withZone(session.getTimeZone()).format(date)))
"worldedit.snapshot.none-before",
TextComponent.of(dateFormat.withZone(session.getTimeZone()).format(date))
)
);
} else {
session.setSnapshot(snapshot);
@ -166,8 +167,9 @@ class LegacySnapshotCommands {
Snapshot snapshot = config.snapshotRepo.getSnapshotAfter(date, world.getName());
if (snapshot == null) {
actor.print(Caption.of(
"worldedit.snapshot.none-after",
TextComponent.of(dateFormat.withZone(session.getTimeZone()).format(date)))
"worldedit.snapshot.none-after",
TextComponent.of(dateFormat.withZone(session.getTimeZone()).format(date))
)
);
} else {
session.setSnapshot(snapshot);
@ -179,6 +181,7 @@ class LegacySnapshotCommands {
}
private static class SnapshotListBox extends PaginationBox {
private final List<Snapshot> snapshots;
SnapshotListBox(String world, List<Snapshot> snapshots) {
@ -199,5 +202,7 @@ class LegacySnapshotCommands {
public int getComponentsSize() {
return snapshots.size();
}
}
}

View File

@ -47,8 +47,10 @@ class LegacySnapshotUtilCommands {
this.we = we;
}
void restore(Actor actor, World world, LocalSession session, EditSession editSession,
String snapshotName) throws WorldEditException {
void restore(
Actor actor, World world, LocalSession session, EditSession editSession,
String snapshotName
) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
Region region = session.getSelection(world);
@ -78,11 +80,11 @@ class LegacySnapshotUtilCommands {
try {
WorldEdit.logger.info("WorldEdit found no snapshots: looked in: "
+ dir.getCanonicalPath());
+ dir.getCanonicalPath());
} catch (IOException e) {
WorldEdit.logger.info("WorldEdit found no snapshots: looked in "
+ "(NON-RESOLVABLE PATH - does it exist?): "
+ dir.getPath());
+ "(NON-RESOLVABLE PATH - does it exist?): "
+ dir.getPath());
}
return;
@ -122,9 +124,11 @@ class LegacySnapshotUtilCommands {
actor.print(Caption.of("worldedit.restore.chunk-load-failed"));
}
} else {
actor.print(Caption.of("worldedit.restore.restored",
TextComponent.of(restore.getMissingChunks().size()),
TextComponent.of(restore.getErrorChunks().size())));
actor.print(Caption.of(
"worldedit.restore.restored",
TextComponent.of(restore.getMissingChunks().size()),
TextComponent.of(restore.getErrorChunks().size())
));
}
} finally {
try {
@ -133,4 +137,5 @@ class LegacySnapshotUtilCommands {
}
}
}
}

View File

@ -56,9 +56,9 @@ public class NavigationCommands {
}
@Command(
name = "unstuck",
aliases = { "!", "/unstuck" },
desc = "Escape from being stuck inside a block"
name = "unstuck",
aliases = {"!", "/unstuck"},
desc = "Escape from being stuck inside a block"
)
@CommandPermissions("worldedit.navigation.unstuck")
public void unstuck(Player player) throws WorldEditException {
@ -67,14 +67,16 @@ public class NavigationCommands {
}
@Command(
name = "ascend",
aliases = { "asc", "/asc", "/ascend" },
desc = "Go up a floor"
name = "ascend",
aliases = {"asc", "/asc", "/ascend"},
desc = "Go up a floor"
)
@CommandPermissions("worldedit.navigation.ascend")
public void ascend(Player player,
@Arg(desc = "# of levels to ascend", def = "1")
int levels) throws WorldEditException {
public void ascend(
Player player,
@Arg(desc = "# of levels to ascend", def = "1")
int levels
) throws WorldEditException {
int ascentLevels = 0;
while (player.ascendLevel()) {
++ascentLevels;
@ -90,14 +92,16 @@ public class NavigationCommands {
}
@Command(
name = "descend",
aliases = { "desc", "/desc", "/descend" },
desc = "Go down a floor"
name = "descend",
aliases = {"desc", "/desc", "/descend"},
desc = "Go down a floor"
)
@CommandPermissions("worldedit.navigation.descend")
public void descend(Player player,
@Arg(desc = "# of levels to descend", def = "1")
int levels) throws WorldEditException {
public void descend(
Player player,
@Arg(desc = "# of levels to descend", def = "1")
int levels
) throws WorldEditException {
int descentLevels = 0;
while (player.descendLevel()) {
++descentLevels;
@ -113,19 +117,21 @@ public class NavigationCommands {
}
@Command(
name = "ceil",
aliases = { "/ceil", "/ceiling" },
desc = "Go to the ceiling"
name = "ceil",
aliases = {"/ceil", "/ceiling"},
desc = "Go to the ceiling"
)
@CommandPermissions("worldedit.navigation.ceiling")
@Logging(POSITION)
public void ceiling(Player player,
@Arg(desc = "# of blocks to leave above you", def = "0")
int clearance,
@Switch(name = 'f', desc = "Force using flight to keep you still")
boolean forceFlight,
@Switch(name = 'g', desc = "Force using glass to keep you still")
boolean forceGlass) throws WorldEditException {
public void ceiling(
Player player,
@Arg(desc = "# of blocks to leave above you", def = "0")
int clearance,
@Switch(name = 'f', desc = "Force using flight to keep you still")
boolean forceFlight,
@Switch(name = 'g', desc = "Force using glass to keep you still")
boolean forceGlass
) throws WorldEditException {
clearance = Math.max(0, clearance);
boolean alwaysGlass = getAlwaysGlass(forceFlight, forceGlass);
@ -137,9 +143,9 @@ public class NavigationCommands {
}
@Command(
name = "thru",
aliases = { "/thru" },
desc = "Pass through walls"
name = "thru",
aliases = {"/thru"},
desc = "Pass through walls"
)
@CommandPermissions("worldedit.navigation.thru.command")
public void thru(Player player) throws WorldEditException {
@ -152,16 +158,18 @@ public class NavigationCommands {
@Command(
name = "jumpto",
aliases = { "j", "/jumpto", "/j" },
aliases = {"j", "/jumpto", "/j"},
desc = "Teleport to a location"
)
@CommandPermissions("worldedit.navigation.jumpto.command")
public void jumpTo(Player player,
@Arg(desc = "Location to jump to", def = "")
Location pos,
//FAWE start
@Switch(name = 'f', desc = "force teleport")
boolean force) throws WorldEditException {
public void jumpTo(
Player player,
@Arg(desc = "Location to jump to", def = "")
Location pos,
//FAWE start
@Switch(name = 'f', desc = "force teleport")
boolean force
) throws WorldEditException {
if (pos == null) {
pos = player.getSolidBlockTrace(300);
@ -176,19 +184,21 @@ public class NavigationCommands {
}
@Command(
name = "up",
aliases = { "/up" },
desc = "Go upwards some distance"
name = "up",
aliases = {"/up"},
desc = "Go upwards some distance"
)
@CommandPermissions("worldedit.navigation.up")
@Logging(POSITION)
public void up(Player player,
@Arg(desc = "Distance to go upwards")
int distance,
@Switch(name = 'f', desc = "Force using flight to keep you still")
boolean forceFlight,
@Switch(name = 'g', desc = "Force using glass to keep you still")
boolean forceGlass) throws WorldEditException {
public void up(
Player player,
@Arg(desc = "Distance to go upwards")
int distance,
@Switch(name = 'f', desc = "Force using flight to keep you still")
boolean forceFlight,
@Switch(name = 'g', desc = "Force using glass to keep you still")
boolean forceGlass
) throws WorldEditException {
boolean alwaysGlass = getAlwaysGlass(forceFlight, forceGlass);
if (player.ascendUpwards(distance, alwaysGlass)) {
player.print(Caption.of("worldedit.up.moved"));
@ -201,7 +211,7 @@ public class NavigationCommands {
* Helper function for /up and /ceil.
*
* @param forceFlight if flight should be used, rather than the default config option
* @param forceGlass if glass should always be placed, rather than the default config option
* @param forceGlass if glass should always be placed, rather than the default config option
* @return true, if glass should always be put under the player
*/
private boolean getAlwaysGlass(boolean forceFlight, boolean forceGlass) {
@ -209,4 +219,5 @@ public class NavigationCommands {
return forceGlass || (config.navigationUseGlass && !forceFlight);
}
}

View File

@ -60,88 +60,110 @@ import static org.enginehub.piston.part.CommandParts.arg;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class PaintBrushCommands {
private static final CommandArgument REGION_FACTORY = arg(TranslatableComponent.of("shape") , Caption.of("worldedit.brush.paint.shape"))
.defaultsTo(ImmutableList.of())
.ofTypes(ImmutableList.of(Key.of(RegionFactory.class)))
.build();
private static final CommandArgument REGION_FACTORY = arg(
TranslatableComponent.of("shape"),
Caption.of("worldedit.brush.paint.shape")
)
.defaultsTo(ImmutableList.of())
.ofTypes(ImmutableList.of(Key.of(RegionFactory.class)))
.build();
private static final CommandArgument RADIUS = arg(TranslatableComponent.of("radius") , Caption.of("worldedit.brush.paint.size"))
.defaultsTo(ImmutableList.of("5"))
.ofTypes(ImmutableList.of(Key.of(double.class)))
.build();
private static final CommandArgument RADIUS = arg(
TranslatableComponent.of("radius"),
Caption.of("worldedit.brush.paint.size")
)
.defaultsTo(ImmutableList.of("5"))
.ofTypes(ImmutableList.of(Key.of(double.class)))
.build();
private static final CommandArgument DENSITY = arg(TranslatableComponent.of("density") , Caption.of("worldedit.brush.paint.density"))
.defaultsTo(ImmutableList.of("20"))
.ofTypes(ImmutableList.of(Key.of(double.class)))
.build();
private static final CommandArgument DENSITY = arg(
TranslatableComponent.of("density"),
Caption.of("worldedit.brush.paint.density")
)
.defaultsTo(ImmutableList.of("20"))
.ofTypes(ImmutableList.of(Key.of(double.class)))
.build();
public static void register(CommandManagerService service, CommandManager commandManager, CommandRegistrationHandler registration) {
public static void register(
CommandManagerService service,
CommandManager commandManager,
CommandRegistrationHandler registration
) {
commandManager.register("paint", builder -> {
builder.description(Caption.of("worldedit.brush.paint.description"));
builder.action(org.enginehub.piston.Command.Action.NULL_ACTION);
CommandManager manager = service.newCommandManager();
registration.register(
manager,
PaintBrushCommandsRegistration.builder(),
new PaintBrushCommands()
manager,
PaintBrushCommandsRegistration.builder(),
new PaintBrushCommands()
);
builder.condition(new PermissionCondition(ImmutableSet.of("worldedit.brush.paint")));
builder.addParts(REGION_FACTORY, RADIUS, DENSITY);
builder.addPart(SubCommandPart.builder(TranslatableComponent.of("type") , Caption.of("worldedit.brush.paint.type"))
.withCommands(manager.getAllCommands().collect(Collectors.toList()))
.required()
.build());
builder.addPart(SubCommandPart.builder(TranslatableComponent.of("type"), Caption.of("worldedit.brush.paint.type"))
.withCommands(manager.getAllCommands().collect(Collectors.toList()))
.required()
.build());
});
}
private void setPaintBrush(CommandParameters parameters, Player player, LocalSession localSession,
Contextual<? extends RegionFunction> generatorFactory) throws WorldEditException {
private void setPaintBrush(
CommandParameters parameters, Player player, LocalSession localSession,
Contextual<? extends RegionFunction> generatorFactory
) throws WorldEditException {
double radius = requireNonNull(RADIUS.value(parameters).asSingle(double.class));
double density = requireNonNull(DENSITY.value(parameters).asSingle(double.class)) / 100;
RegionFactory regionFactory = REGION_FACTORY.value(parameters).asSingle(RegionFactory.class);
BrushCommands.setOperationBasedBrush(player, localSession, radius,
new Paint(generatorFactory, density), regionFactory, "worldedit.brush.paint");
new Paint(generatorFactory, density), regionFactory, "worldedit.brush.paint"
);
}
@Command(
name = "forest",
desc = "Plant trees"
name = "forest",
desc = "Plant trees"
)
public void forest(CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The type of tree to plant")
TreeGenerator.TreeType type) throws WorldEditException {
public void forest(
CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The type of tree to plant")
TreeGenerator.TreeType type
) throws WorldEditException {
setPaintBrush(parameters, player, localSession, new TreeGeneratorFactory(type));
}
@Command(
name = "item",
desc = "Use an item"
name = "item",
desc = "Use an item"
)
@CommandPermissions("worldedit.brush.item")
public void item(CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The type of item to use")
BaseItem item,
@Arg(desc = "The direction in which the item will be applied", def = "up")
@Direction(includeDiagonals = true)
com.sk89q.worldedit.util.Direction direction) throws WorldEditException {
public void item(
CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The type of item to use")
BaseItem item,
@Arg(desc = "The direction in which the item will be applied", def = "up")
@Direction(includeDiagonals = true)
com.sk89q.worldedit.util.Direction direction
) throws WorldEditException {
player.print(TextComponent.builder().append("WARNING: ")
.append(Caption.of("worldedit.brush.paint.item.warning")).build());
setPaintBrush(parameters, player, localSession, new ItemUseFactory(item, direction));
}
@Command(
name = "set",
desc = "Place a block"
name = "set",
desc = "Place a block"
)
public void set(CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The pattern of blocks to use")
Pattern pattern) throws WorldEditException {
public void set(
CommandParameters parameters,
Player player, LocalSession localSession,
@Arg(desc = "The pattern of blocks to use")
Pattern pattern
) throws WorldEditException {
setPaintBrush(parameters, player, localSession, new ReplaceFactory(pattern));
}

View File

@ -22,8 +22,8 @@ package com.sk89q.worldedit.command;
import com.fastasyncworldedit.core.FaweAPI;
import com.fastasyncworldedit.core.FaweCache;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.object.FaweLimit;
import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode;
import com.fastasyncworldedit.core.object.FaweLimit;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
@ -99,16 +99,18 @@ public class RegionCommands {
}
@Command(
name = "/set",
desc = "Sets all the blocks in the region"
name = "/set",
desc = "Sets all the blocks in the region"
)
@CommandPermissions("worldedit.region.set")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public int set(Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern) {
public int set(
Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern
) {
int affected = editSession.setBlocks(region, pattern);
if (affected != 0) {
actor.print(Caption.of("worldedit.set.done"));
@ -117,9 +119,9 @@ public class RegionCommands {
}
@Command(
name = "/air",
aliases = {"/0"},
desc = "Sets all the blocks in the region to air"
name = "/air",
aliases = {"/0"},
desc = "Sets all the blocks in the region to air"
)
@CommandPermissions("worldedit.region.set")
@Logging(REGION)
@ -128,19 +130,21 @@ public class RegionCommands {
}
@Command(
name = "/test",
desc = "test region"
name = "/test",
desc = "test region"
)
@CommandPermissions("worldedit.region.test")
@Logging(REGION)
public void test(Player player, EditSession editSession,
@Arg(desc = "test") double testValue) throws WorldEditException {
public void test(
Player player, EditSession editSession,
@Arg(desc = "test") double testValue
) throws WorldEditException {
player.print(TextComponent.of(testValue));
}
@Command(
name = "/fixlighting",
desc = "Get the light at a position"
name = "/fixlighting",
desc = "Get the light at a position"
)
@CommandPermissions("worldedit.light.fix")
public void fixLighting(Player player) throws WorldEditException {
@ -149,7 +153,10 @@ public class RegionCommands {
if (selection == null) {
final int cx = loc.getBlockX() >> 4;
final int cz = loc.getBlockZ() >> 4;
selection = new CuboidRegion(BlockVector3.at(cx - 8, 0, cz - 8).multiply(16), BlockVector3.at(cx + 8, 0, cz + 8).multiply(16));
selection = new CuboidRegion(
BlockVector3.at(cx - 8, 0, cz - 8).multiply(16),
BlockVector3.at(cx + 8, 0, cz + 8).multiply(16)
);
}
int count = FaweAPI.fixLighting(player.getWorld(), selection, null, RelightMode.ALL);
player.print(Caption.of("fawe.info.lighting.propagate.selection", count));
@ -168,9 +175,9 @@ public class RegionCommands {
// }
@Command(
name = "/removelighting",
aliases = "/removelight",
desc = "Removing lighting in a selection"
name = "/removelighting",
aliases = "/removelight",
desc = "Removing lighting in a selection"
)
@CommandPermissions("worldedit.light.remove")
public void removeLighting(Player player) {
@ -178,16 +185,19 @@ public class RegionCommands {
if (selection == null) {
final int cx = player.getLocation().getBlockX() >> 4;
final int cz = player.getLocation().getBlockZ() >> 4;
selection = new CuboidRegion(BlockVector3.at(cx - 8, 0, cz - 8).multiply(16), BlockVector3.at(cx + 8, 0, cz + 8).multiply(16));
selection = new CuboidRegion(
BlockVector3.at(cx - 8, 0, cz - 8).multiply(16),
BlockVector3.at(cx + 8, 0, cz + 8).multiply(16)
);
}
int count = FaweAPI.fixLighting(player.getWorld(), selection, null, RelightMode.NONE);
player.print(Caption.of("fawe.info.updated.lighting.selection", count));
}
@Command(
name = "/nbtinfo",
aliases = "/nbt",
desc = "View nbt info for a block"
name = "/nbtinfo",
aliases = "/nbt",
desc = "View nbt info for a block"
)
@CommandPermissions("worldedit.nbtinfo")
public void nbtinfo(Player player, EditSession editSession) {
@ -205,9 +215,9 @@ public class RegionCommands {
}
@Command(
name = "/setblocklight",
aliases = "/setlight",
desc = "Set block lighting in a selection"
name = "/setblocklight",
aliases = "/setlight",
desc = "Set block lighting in a selection"
)
@CommandPermissions("worldedit.light.set")
public void setlighting(Player player, EditSession editSession, @Selection Region region) {
@ -215,8 +225,8 @@ public class RegionCommands {
}
@Command(
name = "/setskylight",
desc = "Set sky lighting in a selection"
name = "/setskylight",
desc = "Set sky lighting in a selection"
)
@CommandPermissions("worldedit.light.set")
public void setskylighting(Player player, @Selection Region region) {
@ -224,20 +234,22 @@ public class RegionCommands {
}
@Command(
name = "/line",
desc = "Draws line segments between cuboid selection corners or convex polyhedral selection vertices",
descFooter = "Can only be used with a cuboid selection or a convex polyhedral selection"
name = "/line",
desc = "Draws line segments between cuboid selection corners or convex polyhedral selection vertices",
descFooter = "Can only be used with a cuboid selection or a convex polyhedral selection"
)
@CommandPermissions("worldedit.region.line")
@Logging(REGION)
public int line(Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to place")
Pattern pattern,
@Arg(desc = "The thickness of the line", def = "0")
int thickness,
@Switch(name = 'h', desc = "Generate only a shell")
boolean shell) throws WorldEditException {
public int line(
Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to place")
Pattern pattern,
@Arg(desc = "The thickness of the line", def = "0")
int thickness,
@Switch(name = 'h', desc = "Generate only a shell")
boolean shell
) throws WorldEditException {
if (!(region instanceof CuboidRegion)) {
actor.print(Caption.of("worldedit.line.cuboid-only"));
return 0;
@ -254,21 +266,23 @@ public class RegionCommands {
}
@Command(
name = "/curve",
desc = "Draws a spline through selected points",
descFooter = "Can only be used with a convex polyhedral selection"
name = "/curve",
desc = "Draws a spline through selected points",
descFooter = "Can only be used with a convex polyhedral selection"
)
@CommandPermissions("worldedit.region.curve")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public int curve(Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to place")
Pattern pattern,
@Arg(desc = "The thickness of the curve", def = "0")
int thickness,
@Switch(name = 'h', desc = "Generate only a shell")
boolean shell) throws WorldEditException {
public int curve(
Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to place")
Pattern pattern,
@Arg(desc = "The thickness of the curve", def = "0")
int thickness,
@Switch(name = 'h', desc = "Generate only a shell")
boolean shell
) throws WorldEditException {
if (!(region instanceof ConvexPolyhedralRegion)) {
actor.print(Caption.of("worldedit.curve.invalid-type"));
return 0;
@ -285,18 +299,20 @@ public class RegionCommands {
}
@Command(
name = "/replace",
aliases = { "/re", "/rep" },
desc = "Replace all blocks in the selection with another"
name = "/replace",
aliases = {"/re", "/rep"},
desc = "Replace all blocks in the selection with another"
)
@CommandPermissions("worldedit.region.replace")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public int replace(Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The mask representing blocks to replace", def = "")
Mask from,
@Arg(desc = "The pattern of blocks to replace with")
Pattern to) throws WorldEditException {
public int replace(
Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The mask representing blocks to replace", def = "")
Mask from,
@Arg(desc = "The pattern of blocks to replace with")
Pattern to
) throws WorldEditException {
if (from == null) {
from = new ExistingBlockMask(editSession);
//FAWE start > the mask will have been initialised with a WorldWrapper extent (very bad/slow
@ -313,28 +329,35 @@ public class RegionCommands {
}
@Command(
name = "/overlay",
desc = "Set a block on top of blocks in the region"
name = "/overlay",
desc = "Set a block on top of blocks in the region"
)
@CommandPermissions("worldedit.region.overlay")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public int overlay(Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The pattern of blocks to overlay")
Pattern pattern) throws WorldEditException {
public int overlay(
Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The pattern of blocks to overlay")
Pattern pattern
) throws WorldEditException {
int affected = editSession.overlayCuboidBlocks(region, pattern);
actor.print(Caption.of("worldedit.overlay.overlaid", TextComponent.of(affected)));
return affected;
}
@Command(
name = "/lay",
desc = "Set the top block in the region"
name = "/lay",
desc = "Set the top block in the region"
)
@CommandPermissions("worldedit.region.overlay")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public void lay(Player player, EditSession editSession, @Selection Region region, @Arg(name = "pattern", desc = "The pattern of blocks to lay") Pattern patternArg) throws WorldEditException {
public void lay(
Player player,
EditSession editSession,
@Selection Region region,
@Arg(name = "pattern", desc = "The pattern of blocks to lay") Pattern patternArg
) throws WorldEditException {
BlockVector3 max = region.getMaximumPoint();
int maxY = max.getBlockY();
Iterable<BlockVector2> flat = Regions.asFlatRegion(region).asFlatRegion();
@ -353,23 +376,25 @@ public class RegionCommands {
}
@Command(
name = "/center",
aliases = { "/middle" },
desc = "Set the center block(s)"
name = "/center",
aliases = {"/middle"},
desc = "Set the center block(s)"
)
@Logging(REGION)
@CommandPermissions("worldedit.region.center")
public int center(Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern) throws WorldEditException {
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);
actor.print(Caption.of("worldedit.center.changed", TextComponent.of(affected)));
return affected;
}
@Command(
name = "/naturalize",
desc = "3 layers of dirt on top then rock below"
name = "/naturalize",
desc = "3 layers of dirt on top then rock below"
)
@CommandPermissions("worldedit.region.naturalize")
@Logging(REGION)
@ -381,51 +406,57 @@ public class RegionCommands {
}
@Command(
name = "/walls",
desc = "Build the four sides of the selection"
name = "/walls",
desc = "Build the four sides of the selection"
)
@CommandPermissions("worldedit.region.walls")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public int walls(Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern) throws WorldEditException {
public int walls(
Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern
) throws WorldEditException {
int affected = editSession.makeWalls(region, pattern);
actor.print(Caption.of("worldedit.walls.changed", TextComponent.of(affected)));
return affected;
}
@Command(
name = "/faces",
aliases = { "/outline" },
desc = "Build the walls, ceiling, and floor of a selection"
name = "/faces",
aliases = {"/outline"},
desc = "Build the walls, ceiling, and floor of a selection"
)
@CommandPermissions("worldedit.region.faces")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public int faces(Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern) throws WorldEditException {
public int faces(
Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern
) throws WorldEditException {
int affected = editSession.makeFaces(region, pattern);
actor.print(Caption.of("worldedit.faces.changed", TextComponent.of(affected)));
return affected;
}
@Command(
name = "/smooth",
desc = "Smooth the elevation in the selection",
descFooter = "Example: '//smooth 1 grass_block,dirt,stone' would only smooth natural surface terrain."
name = "/smooth",
desc = "Smooth the elevation in the selection",
descFooter = "Example: '//smooth 1 grass_block,dirt,stone' would only smooth natural surface terrain."
)
@CommandPermissions("worldedit.region.smooth")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public int smooth(Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "# of iterations to perform", def = "1")
int iterations,
@Arg(desc = "The mask of blocks to use as the height map", def = "")
Mask mask,
@Switch(name = 's', desc = "The flag makes it only consider snow")
boolean snow) throws WorldEditException {
public int smooth(
Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "# of iterations to perform", def = "1")
int iterations,
@Arg(desc = "The mask of blocks to use as the height map", def = "")
Mask mask,
@Switch(name = 's', desc = "The flag makes it only consider snow")
boolean snow
) throws WorldEditException {
//FAWE start > the mask will have been initialised with a WorldWrapper extent (very bad/slow)
if (mask instanceof AbstractExtentMask) {
((AbstractExtentMask) mask).setExtent(editSession);
@ -433,7 +464,8 @@ public class RegionCommands {
//FAWE end
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min
.getZ() + 1));
FaweLimit limit = actor.getLimit();
if (volume >= limit.MAX_CHECKS) {
throw FaweCache.MAX_CHECKS;
@ -451,10 +483,10 @@ public class RegionCommands {
}
@Command(
name = "/wea",
aliases = {"wea", "worldeditanywhere", "/worldeditanywhere", "/weanywhere"},
desc = "Bypass region restrictions",
descFooter = "Bypass region restrictions"
name = "/wea",
aliases = {"wea", "worldeditanywhere", "/worldeditanywhere", "/weanywhere"},
desc = "Bypass region restrictions",
descFooter = "Bypass region restrictions"
)
@CommandPermissions("fawe.admin")
public void wea(Actor actor) throws WorldEditException {
@ -466,10 +498,10 @@ public class RegionCommands {
}
@Command(
name = "/wer",
aliases = {"wer", "worldeditregion", "/worldeditregion", "select", "/select"},
desc = "Select your current allowed region",
descFooter = "Select your current allowed region"
name = "/wer",
aliases = {"wer", "worldeditregion", "/worldeditregion", "select", "/select"},
desc = "Select your current allowed region",
descFooter = "Select your current allowed region"
)
@CommandPermissions("fawe.worldeditregion")
public void wer(Player player) throws WorldEditException {
@ -484,33 +516,36 @@ public class RegionCommands {
@Command(
name = "/move",
aliases = {"/mv"},
desc = "Move the contents of the selection"
name = "/move",
aliases = {"/mv"},
desc = "Move the contents of the selection"
)
@CommandPermissions("worldedit.region.move")
@Logging(ORIENTATION_REGION)
@Confirm(Confirm.Processor.REGION)
public int move(Actor actor, World world, EditSession editSession, LocalSession session,
@Selection Region region,
@Arg(desc = "# of blocks to move", def = "1")
int count,
@Arg(desc = "The direction to move", def = Direction.AIM)
@Direction(includeDiagonals = true)
BlockVector3 direction,
@Arg(desc = "The pattern of blocks to leave", def = "air")
Pattern replace,
@Switch(name = 's', desc = "Shift the selection to the target location")
boolean moveSelection,
@Switch(name = 'a', desc = "Ignore air blocks")
boolean ignoreAirBlocks,
@Switch(name = 'e', desc = "Also copy entities")
boolean copyEntities,
@Switch(name = 'b', desc = "Also copy biomes")
boolean copyBiomes,
@ArgFlag(name = 'm', desc = "Set the include mask, non-matching blocks become air")
Mask mask) throws WorldEditException {
public int move(
Actor actor, World world, EditSession editSession, LocalSession session,
@Selection Region region,
@Arg(desc = "# of blocks to move", def = "1")
int count,
@Arg(desc = "The direction to move", def = Direction.AIM)
@Direction(includeDiagonals = true)
BlockVector3 direction,
@Arg(desc = "The pattern of blocks to leave", def = "air")
Pattern replace,
@Switch(name = 's', desc = "Shift the selection to the target location")
boolean moveSelection,
@Switch(name = 'a', desc = "Ignore air blocks")
boolean ignoreAirBlocks,
@Switch(name = 'e', desc = "Also copy entities")
boolean copyEntities,
@Switch(name = 'b', desc = "Also copy biomes")
boolean copyBiomes,
@ArgFlag(name = 'm', desc = "Set the include mask, non-matching blocks become air")
Mask mask
) throws WorldEditException {
checkCommandArgument(count >= 1, "Count must be >= 1");
//FAWE start > the mask will have been initialised with a WorldWrapper extent (very bad/slow)
if (mask instanceof AbstractExtentMask) {
((AbstractExtentMask) mask).setExtent(editSession);
@ -545,47 +580,52 @@ public class RegionCommands {
}
@Command(
name = "/fall",
desc = "Have the blocks in the selection fall",
descFooter = "Make the blocks in the selection fall\n"
name = "/fall",
desc = "Have the blocks in the selection fall",
descFooter = "Make the blocks in the selection fall\n"
)
@CommandPermissions("worldedit.region.fall")
@Logging(ORIENTATION_REGION)
@Confirm(Confirm.Processor.REGION)
public void fall(Player player, EditSession editSession, LocalSession session,
@Selection Region region,
@Arg(desc = "BlockStateHolder", def = "air")
BlockStateHolder replace,
@Switch(name = 'm', desc = "Only fall within the vertical selection")
boolean notFullHeight) throws WorldEditException {
public void fall(
Player player, EditSession editSession, LocalSession session,
@Selection Region region,
@Arg(desc = "BlockStateHolder", def = "air")
BlockStateHolder replace,
@Switch(name = 'm', desc = "Only fall within the vertical selection")
boolean notFullHeight
) throws WorldEditException {
int affected = editSession.fall(region, !notFullHeight, replace);
player.print(Caption.of("fawe.worldedit.visitor.visitor.block", affected));
}
@Command(
name = "/stack",
desc = "Repeat the contents of the selection"
name = "/stack",
desc = "Repeat the contents of the selection"
)
@CommandPermissions("worldedit.region.stack")
@Logging(ORIENTATION_REGION)
public int stack(Actor actor, World world, EditSession editSession, LocalSession session,
@Selection Region region,
@Arg(desc = "# of copies to stack", def = "1")
@Confirm(Confirm.Processor.REGION)
int count,
@Arg(desc = "The direction to stack", def = Direction.AIM)
@Direction(includeDiagonals = true)
BlockVector3 direction,
@Switch(name = 's', desc = "Shift the selection to the last stacked copy")
boolean moveSelection,
@Switch(name = 'a', desc = "Ignore air blocks")
boolean ignoreAirBlocks,
@Switch(name = 'e', desc = "Also copy entities")
boolean copyEntities,
@Switch(name = 'b', desc = "Also copy biomes")
boolean copyBiomes,
@ArgFlag(name = 'm', desc = "Set the include mask, non-matching blocks become air")
Mask mask) throws WorldEditException {
public int stack(
Actor actor, World world, EditSession editSession, LocalSession session,
@Selection Region region,
@Arg(desc = "# of copies to stack", def = "1")
@Confirm(Confirm.Processor.REGION)
int count,
@Arg(desc = "The direction to stack", def = Direction.AIM)
@Direction(includeDiagonals = true)
BlockVector3 direction,
@Switch(name = 's', desc = "Shift the selection to the last stacked copy")
boolean moveSelection,
@Switch(name = 'a', desc = "Ignore air blocks")
boolean ignoreAirBlocks,
@Switch(name = 'e', desc = "Also copy entities")
boolean copyEntities,
@Switch(name = 'b', desc = "Also copy biomes")
boolean copyBiomes,
@ArgFlag(name = 'm', desc = "Set the include mask, non-matching blocks become air")
Mask mask
) throws WorldEditException {
//FAWE start > the mask will have been initialised with a WorldWrapper extent (very bad/slow)
if (mask instanceof AbstractExtentMask) {
((AbstractExtentMask) mask).setExtent(editSession);
@ -623,22 +663,24 @@ public class RegionCommands {
}
@Command(
name = "/regen",
desc = "Regenerates the contents of the selection",
descFooter = "This command might affect things outside the selection,\n"
+ "if they are within the same chunk."
name = "/regen",
desc = "Regenerates the contents of the selection",
descFooter = "This command might affect things outside the selection,\n"
+ "if they are within the same chunk."
)
@CommandPermissions("worldedit.regen")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
void regenerate(Actor actor, World world, LocalSession session, EditSession editSession,
@Selection Region region,
@Arg(desc = "The seed to regenerate with, otherwise uses world seed", def = "")
Long seed,
@Switch(name = 'b', desc = "Regenerate biomes as well")
boolean regenBiomes,
@Arg(desc = "Biome to apply for this regeneration (only works in overworld)", def = "")
BiomeType biomeType) throws WorldEditException {
void regenerate(
Actor actor, World world, LocalSession session, EditSession editSession,
@Selection Region region,
@Arg(desc = "The seed to regenerate with, otherwise uses world seed", def = "")
Long seed,
@Switch(name = 'b', desc = "Regenerate biomes as well")
boolean regenBiomes,
@Arg(desc = "Biome to apply for this regeneration (only works in overworld)", def = "")
BiomeType biomeType
) throws WorldEditException {
Mask mask = session.getMask();
boolean success;
try {
@ -663,25 +705,27 @@ public class RegionCommands {
}
@Command(
name = "/deform",
desc = "Deforms a selected region with an expression",
descFooter = "The expression is executed for each block and is expected\n"
+ "to modify the variables x, y and z to point to a new block\n"
+ "to fetch. See also https://tinyurl.com/weexpr"
name = "/deform",
desc = "Deforms a selected region with an expression",
descFooter = "The expression is executed for each block and is expected\n"
+ "to modify the variables x, y and z to point to a new block\n"
+ "to fetch. See also https://tinyurl.com/weexpr"
)
@CommandPermissions("worldedit.region.deform")
@Logging(ALL)
@Confirm(Confirm.Processor.REGION)
public int deform(Actor actor, LocalSession session, EditSession editSession,
@Selection Region region,
@Arg(desc = "The expression to use", variable = true)
List<String> expression,
@Switch(name = 'r', desc = "Use the game's coordinate origin")
boolean useRawCoords,
@Switch(name = 'o', desc = "Use the placement's coordinate origin")
boolean offset,
@Switch(name = 'c', desc = "Use the selection's center as origin")
boolean offsetCenter) throws WorldEditException {
public int deform(
Actor actor, LocalSession session, EditSession editSession,
@Selection Region region,
@Arg(desc = "The expression to use", variable = true)
List<String> expression,
@Switch(name = 'r', desc = "Use the game's coordinate origin")
boolean useRawCoords,
@Switch(name = 'o', desc = "Use the placement's coordinate origin")
boolean offset,
@Switch(name = 'c', desc = "Use the selection's center as origin")
boolean offsetCenter
) throws WorldEditException {
final Vector3 zero;
Vector3 unit;
@ -717,7 +761,13 @@ public class RegionCommands {
final Vector3 unit1 = unit;
try {
final int affected = editSession.deformRegion(region, zero, unit1, String.join(" ", expression), session.getTimeout());
final int affected = editSession.deformRegion(
region,
zero,
unit1,
String.join(" ", expression),
session.getTimeout()
);
if (actor instanceof Player) {
((Player) actor).findFreePosition();
}
@ -730,25 +780,26 @@ public class RegionCommands {
}
@Command(
name = "/hollow",
desc = "Hollows out the object contained in this selection",
descFooter = "Hollows out the object contained in this selection.\n"
+ "Optionally fills the hollowed out part with the given block.\n"
+ "Thickness is measured in manhattan distance."
name = "/hollow",
desc = "Hollows out the object contained in this selection",
descFooter = "Hollows out the object contained in this selection.\n"
+ "Optionally fills the hollowed out part with the given block.\n"
+ "Thickness is measured in manhattan distance."
)
@CommandPermissions("worldedit.region.hollow")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public int hollow(Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "Thickness of the shell to leave", def = "0")
int thickness,
@Arg(desc = "The pattern of blocks to replace the hollowed area with", def = "air")
Pattern pattern,
@ArgFlag(name = 'm', desc = "Mask to hollow with")
Mask mask) throws WorldEditException {
public int hollow(
Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "Thickness of the shell to leave", def = "0")
int thickness,
@Arg(desc = "The pattern of blocks to replace the hollowed area with", def = "air")
Pattern pattern,
@ArgFlag(name = 'm', desc = "Mask to hollow with")
Mask mask
) throws WorldEditException {
checkCommandArgument(thickness >= 0, "Thickness must be >= 0");
//FAWE start > the mask will have been initialised with a WorldWrapper extent (very bad/slow)
Mask finalMask;
if (mask != null) {
@ -767,17 +818,19 @@ public class RegionCommands {
}
@Command(
name = "/forest",
desc = "Make a forest within the region"
name = "/forest",
desc = "Make a forest within the region"
)
@CommandPermissions("worldedit.region.forest")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public int forest(Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The type of tree to place", def = "tree")
TreeType type,
@Arg(desc = "The density of the forest", def = "5")
double density) throws WorldEditException {
public int forest(
Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The type of tree to place", def = "tree")
TreeType type,
@Arg(desc = "The density of the forest", def = "5")
double density
) throws WorldEditException {
checkCommandArgument(0 <= density && density <= 100, "Density must be in [0, 100]");
int affected = editSession.makeForest(region, density / 100, type);
actor.print(Caption.of("worldedit.forest.created", TextComponent.of(affected)));
@ -785,15 +838,17 @@ public class RegionCommands {
}
@Command(
name = "/flora",
desc = "Make flora within the region"
name = "/flora",
desc = "Make flora within the region"
)
@CommandPermissions("worldedit.region.flora")
@Logging(REGION)
@Confirm(Confirm.Processor.REGION)
public int flora(Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The density of the forest", def = "5")
double density) throws WorldEditException {
public int flora(
Actor actor, EditSession editSession, @Selection Region region,
@Arg(desc = "The density of the forest", def = "5")
double density
) throws WorldEditException {
checkCommandArgument(0 <= density && density <= 100, "Density must be in [0, 100]");
density = density / 100;
FloraGenerator generator = new FloraGenerator(editSession);

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.command;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.event.extent.ActorSaveClipboardEvent;
import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder;
import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder;
import com.fastasyncworldedit.core.extent.clipboard.io.schematic.MinecraftStructure;
@ -36,7 +37,6 @@ 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.entity.Player;
import com.fastasyncworldedit.core.event.extent.ActorSaveClipboardEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
@ -142,18 +142,20 @@ public class SchematicCommands {
}
@Command(
name = "loadall",
desc = "Load multiple clipboards (paste will randomly choose one)"
name = "loadall",
desc = "Load multiple clipboards (paste will randomly choose one)"
)
@Deprecated
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.load.web", "worldedit.schematic.load.asset"})
public void loadall(Player player, LocalSession session,
@Arg(desc = "Format name.", def = "fast")
String formatName,
@Arg(desc = "File name.")
String filename,
@Switch(name = 'r', desc = "Apply random rotation")
boolean randomRotate) throws FilenameException {
public void loadall(
Player player, LocalSession session,
@Arg(desc = "Format name.", def = "fast")
String formatName,
@Arg(desc = "File name.")
String filename,
@Switch(name = 'r', desc = "Apply random rotation")
boolean randomRotate
) throws FilenameException {
final ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
if (format == null) {
player.print(Caption.of("fawe.worldedit.clipboard.clipboard.invalid.format", formatName));
@ -171,8 +173,8 @@ public class SchematicCommands {
}
@Command(
name = "clear",
desc = "Clear your clipboard"
name = "clear",
desc = "Clear your clipboard"
)
@CommandPermissions({"worldedit.clipboard.clear", "worldedit.schematic.clear"})
public void clear(Player player, LocalSession session) throws WorldEditException {
@ -181,8 +183,8 @@ public class SchematicCommands {
}
@Command(
name = "unload",
desc = "Remove a clipboard from your multi-clipboard"
name = "unload",
desc = "Remove a clipboard from your multi-clipboard"
)
@CommandPermissions({"worldedit.clipboard.clear", "worldedit.schematic.clear"})
public void unload(Player player, LocalSession session, String fileName) throws WorldEditException {
@ -232,7 +234,8 @@ public class SchematicCommands {
player.print(Caption.of("worldedit.schematic.directory-does-not-exist", TextComponent.of(String.valueOf(destDir))));
return;
}
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && !MainUtil.isInSubDirectory(dir, destDir) && !player.hasPermission("worldedit.schematic.move.other")) {
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && !MainUtil.isInSubDirectory(dir, destDir) && !player.hasPermission(
"worldedit.schematic.move.other")) {
player.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.move.other"));
return;
}
@ -252,9 +255,13 @@ public class SchematicCommands {
player.print(Caption.of("fawe.worldedit.schematic.schematic.move.exists", destFile));
continue;
}
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && (!MainUtil.isInSubDirectory(dir, destFile) || !MainUtil.isInSubDirectory(dir, source)) && !player.hasPermission("worldedit.schematic.delete.other")) {
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && (!MainUtil.isInSubDirectory(
dir,
destFile
) || !MainUtil.isInSubDirectory(dir, source)) && !player.hasPermission("worldedit.schematic.delete.other")) {
player.print(Caption.of("fawe.worldedit.schematic.schematic.move.failed", destFile,
Caption.of("fawe.error.no-perm", ("worldedit.schematic.move.other"))));
Caption.of("fawe.error.no-perm", ("worldedit.schematic.move.other"))
));
continue;
}
try {
@ -287,15 +294,17 @@ public class SchematicCommands {
//FAWE end
@Command(
name = "load",
desc = "Load a schematic into your clipboard"
name = "load",
desc = "Load a schematic into your clipboard"
)
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.load.asset", "worldedit.schematic.load.web", "worldedit.schematic.load.other"})
public void load(Actor actor, LocalSession session,
@Arg(desc = "File name.")
String filename,
@Arg(desc = "Format name.", def = "fast")
String formatName) throws FilenameException {
public void load(
Actor actor, LocalSession session,
@Arg(desc = "File name.")
String filename,
@Arg(desc = "Format name.", def = "fast")
String formatName
) throws FilenameException {
LocalConfiguration config = worldEdit.getConfiguration();
//FAWE start
@ -338,13 +347,16 @@ public class SchematicCommands {
return;
}
} else {
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && !actor.hasPermission("worldedit.schematic.load.other") && Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").matcher(filename).find()) {
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && !actor.hasPermission("worldedit.schematic.load.other") && Pattern
.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")
.matcher(filename)
.find()) {
actor.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.load.other"));
return;
}
if (filename.matches(".*\\.[\\w].*")) {
format = ClipboardFormats
.findByExtension(filename.substring(filename.lastIndexOf('.') + 1));
.findByExtension(filename.substring(filename.lastIndexOf('.') + 1));
} else {
format = ClipboardFormats.findByAlias(formatName);
}
@ -357,7 +369,9 @@ public class SchematicCommands {
}
}
if (file == null || !file.exists() || !MainUtil.isInSubDirectory(saveDir, file)) {
actor.printError("Schematic " + filename + " does not exist! (" + (file != null && file.exists()) + "|" + file + "|" + (file != null && !MainUtil.isInSubDirectory(saveDir, file)) + ")");
actor.printError(TextComponent.of("Schematic " + filename + " does not exist! (" + (file != null && file.exists()) +
"|" + file + "|" + (file != null && !MainUtil
.isInSubDirectory(saveDir, file)) + ")"));
return;
}
if (format == null) {
@ -389,21 +403,23 @@ public class SchematicCommands {
}
@Command(
name = "save",
desc = "Save your clipboard into a schematic file"
name = "save",
desc = "Save your clipboard into a schematic file"
)
@CommandPermissions({"worldedit.clipboard.save", "worldedit.schematic.save", "worldedit.schematic.save.other"})
public void save(Actor actor, LocalSession session,
@Arg(desc = "File name.")
String filename,
@Arg(desc = "Format name.", def = "fast")
String formatName,
@Switch(name = 'f', desc = "Overwrite an existing file.")
boolean allowOverwrite,
//FAWE start
@Switch(name = 'g', desc = "Bypasses per-player-schematic folders")
boolean global) throws WorldEditException {
//FAWE end
public void save(
Actor actor, LocalSession session,
@Arg(desc = "File name.")
String filename,
@Arg(desc = "Format name.", def = "fast")
String formatName,
@Switch(name = 'f', desc = "Overwrite an existing file.")
boolean allowOverwrite,
//FAWE start
@Switch(name = 'g', desc = "Bypasses per-player-schematic folders")
boolean global
) throws WorldEditException {
//FAWE end
if (worldEdit.getPlatformManager().queryCapability(Capability.GAME_HOOKS).getDataVersion() == -1) {
actor.printError(TranslatableComponent.of("worldedit.schematic.unsupported-minecraft-version"));
return;
@ -462,7 +478,7 @@ public class SchematicCommands {
if (parent != null && !parent.exists()) {
if (!parent.mkdirs()) {
throw new StopExecutionException(Caption.of(
"worldedit.schematic.save.failed-directory"));
"worldedit.schematic.save.failed-directory"));
}
}
@ -470,17 +486,20 @@ public class SchematicCommands {
SchematicSaveTask task = new SchematicSaveTask(actor, f, dir, format, holder, overwrite);
AsyncCommandBuilder.wrap(task, actor)
.registerWithSupervisor(worldEdit.getSupervisor(), "Saving schematic " + filename)
.setDelayMessage(Caption.of("worldedit.schematic.save.saving"))
.onSuccess(filename + " saved" + (overwrite ? " (overwriting previous file)." : "."), null)
.onFailure(Caption.of("worldedit.schematic.failed-to-save"), worldEdit.getPlatformManager().getPlatformCommandManager().getExceptionConverter())
.buildAndExec(worldEdit.getExecutorService());
.registerWithSupervisor(worldEdit.getSupervisor(), "Saving schematic " + filename)
.setDelayMessage(Caption.of("worldedit.schematic.save.saving"))
.onSuccess(filename + " saved" + (overwrite ? " (overwriting previous file)." : "."), null)
.onFailure(
Caption.of("worldedit.schematic.failed-to-save"),
worldEdit.getPlatformManager().getPlatformCommandManager().getExceptionConverter()
)
.buildAndExec(worldEdit.getExecutorService());
}
@Command(
name = "formats",
aliases = {"listformats", "f"},
desc = "List available formats"
name = "formats",
aliases = {"listformats", "f"},
desc = "List available formats"
)
@CommandPermissions("worldedit.schematic.formats")
public void formats(Actor actor) {
@ -503,23 +522,25 @@ public class SchematicCommands {
}
@Command(
name = "list",
aliases = {"all", "ls"},
desc = "List saved schematics",
descFooter = "Note: Format is not fully verified until loading."
name = "list",
aliases = {"all", "ls"},
desc = "List saved schematics",
descFooter = "Note: Format is not fully verified until loading."
)
@CommandPermissions("worldedit.schematic.list")
public void list(Actor actor, LocalSession session,
@ArgFlag(name = 'p', desc = "Page to view.", def = "1")
int page,
@Switch(name = 'd', desc = "Sort by date, oldest first")
boolean oldFirst,
@Switch(name = 'n', desc = "Sort by date, newest first")
boolean newFirst,
@ArgFlag(name = 'f', desc = "Restricts by format.", def = "")
String formatName,
@Arg(name = "filter", desc = "Filter for schematics", def = "all")
String filter, Arguments arguments) throws WorldEditException {
public void list(
Actor actor, LocalSession session,
@ArgFlag(name = 'p', desc = "Page to view.", def = "1")
int page,
@Switch(name = 'd', desc = "Sort by date, oldest first")
boolean oldFirst,
@Switch(name = 'n', desc = "Sort by date, newest first")
boolean newFirst,
@ArgFlag(name = 'f', desc = "Restricts by format.", def = "")
String formatName,
@Arg(name = "filter", desc = "Filter for schematics", def = "all")
String filter, Arguments arguments
) throws WorldEditException {
if (oldFirst && newFirst) {
throw new StopExecutionException(Caption.of("worldedit.schematic.sorting-old-new"));
}
@ -551,60 +572,76 @@ public class SchematicCommands {
Function<URI, Boolean> isLoaded = multi == null ? f -> false : multi::contains;
List<Component> components = UtilityCommands.entryToComponent(dir, entries, isLoaded,
(name, path, type, loaded) -> {
TextComponentProducer msg = new TextComponentProducer();
(name, path, type, loaded) -> {
TextComponentProducer msg = new TextComponentProducer();
msg.append(Caption.of("worldedit.schematic.dash.symbol"));
msg.append(Caption.of("worldedit.schematic.dash.symbol"));
if (loaded) {
msg.append(Caption.of("worldedit.schematic.minus.symbol")
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, unload + " " + path))
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.schematic.unload"))));
} else {
msg.append(Caption.of("worldedit.schematic.plus.symbol")
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, loadMulti + " " + path))
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.schematic.clipboard"))));
}
if (type != UtilityCommands.URIType.DIRECTORY) {
msg.append(Caption.of("worldedit.schematic.x.symbol")
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, delete + " " + path))
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.schematic.delete")))
);
} else if (hasShow) {
msg.append(Caption.of("worldedit.schematic.0.symbol")
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, showCmd + " " + path))
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.schematic.visualize")))
);
}
TextComponent msgElem = TextComponent.of(name);
if (type != UtilityCommands.URIType.DIRECTORY) {
msgElem = msgElem.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, loadSingle + " " + path));
msgElem = msgElem.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.schematic.load")));
} else {
msgElem = msgElem.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, list + " " + path));
msgElem = msgElem.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.schematic.list")));
}
msg.append(msgElem);
if (type == UtilityCommands.URIType.FILE) {
long filesize = 0;
try {
filesize = Files.size(Paths.get(dir.getAbsolutePath() + File.separator
+ (playerFolder ? (uuid.toString() + File.separator) : "") + path));
} catch (IOException e) {
e.printStackTrace();
if (loaded) {
msg.append(Caption.of("worldedit.schematic.minus.symbol")
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, unload + " " + path))
.hoverEvent(HoverEvent.of(
HoverEvent.Action.SHOW_TEXT,
Caption.of("worldedit.schematic.unload")
)));
} else {
msg.append(Caption.of("worldedit.schematic.plus.symbol")
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, loadMulti + " " + path))
.hoverEvent(HoverEvent.of(
HoverEvent.Action.SHOW_TEXT,
Caption.of("worldedit.schematic.clipboard")
)));
}
TextComponent sizeElem = TextComponent.of(String.format(" (%.1f kb)", filesize / 1000.0), TextColor.GRAY);
msg.append(sizeElem);
if (type != UtilityCommands.URIType.DIRECTORY) {
msg.append(Caption.of("worldedit.schematic.x.symbol")
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, delete + " " + path))
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.schematic.delete")))
);
} else if (hasShow) {
msg.append(Caption.of("worldedit.schematic.0.symbol")
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, showCmd + " " + path))
.hoverEvent(HoverEvent.of(
HoverEvent.Action.SHOW_TEXT,
Caption.of("worldedit.schematic.visualize")
))
);
}
TextComponent msgElem = TextComponent.of(name);
if (type != UtilityCommands.URIType.DIRECTORY) {
msgElem = msgElem.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, loadSingle + " " + path));
msgElem = msgElem.hoverEvent(HoverEvent.of(
HoverEvent.Action.SHOW_TEXT,
Caption.of("worldedit.schematic.load")
));
} else {
msgElem = msgElem.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, list + " " + path));
msgElem = msgElem.hoverEvent(HoverEvent.of(
HoverEvent.Action.SHOW_TEXT,
Caption.of("worldedit.schematic.list")
));
}
msg.append(msgElem);
if (type == UtilityCommands.URIType.FILE) {
long filesize = 0;
try {
filesize = Files.size(Paths.get(dir.getAbsolutePath() + File.separator
+ (playerFolder ? (uuid.toString() + File.separator) : "") + path));
} catch (IOException e) {
e.printStackTrace();
}
TextComponent sizeElem = TextComponent.of(String.format(" (%.1f kb)", filesize / 1000.0), TextColor.GRAY);
msg.append(sizeElem);
}
return msg.create();
}
return msg.create();
});
);
long totalBytes = 0;
File parentDir = new File(dir.getAbsolutePath() + (playerFolder ? File.separator + uuid.toString() : ""));
try {
List<File> toAddUp = getFiles(parentDir, null, null);
if (toAddUp != null && toAddUp.size() != 0) {
if (toAddUp != null && toAddUp.size() != 0) {
for (File schem : toAddUp) {
if (schem.getName().endsWith(".schem") || schem.getName().endsWith(".schematic")) {
totalBytes += Files.size(Paths.get(schem.getAbsolutePath()));
@ -618,8 +655,10 @@ public class SchematicCommands {
String headerBytesElem = String.format("%.1fkb", totalBytes / 1000.0);
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Settings.IMP.EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT > -1) {
headerBytesElem += String.format(" / %dkb",
Settings.IMP.EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT);
headerBytesElem += String.format(
" / %dkb",
Settings.IMP.EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT
);
}
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS) {
@ -636,14 +675,16 @@ public class SchematicCommands {
}
@Command(
name = "delete",
aliases = {"d"},
desc = "Delete a saved schematic"
name = "delete",
aliases = {"d"},
desc = "Delete a saved schematic"
)
@CommandPermissions("worldedit.schematic.delete")
public void delete(Actor actor, LocalSession session,
@Arg(desc = "File name.")
String filename) throws WorldEditException, IOException {
public void delete(
Actor actor, LocalSession session,
@Arg(desc = "File name.")
String filename
) throws WorldEditException, IOException {
LocalConfiguration config = worldEdit.getConfiguration();
File working = worldEdit.getWorkingDirectoryPath(config.saveDir).toFile();
//FAWE start
@ -666,7 +707,8 @@ public class SchematicCommands {
actor.print(Caption.of("worldedit.schematic.delete.does-not-exist", TextComponent.of(filename)));
continue;
}
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && !MainUtil.isInSubDirectory(dir, f) && !actor.hasPermission("worldedit.schematic.delete.other")) {
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && !MainUtil.isInSubDirectory(dir, f) && !actor.hasPermission(
"worldedit.schematic.delete.other")) {
actor.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.delete.other"));
continue;
}
@ -690,6 +732,7 @@ public class SchematicCommands {
//FAWE end
private static class SchematicLoadTask implements Callable<ClipboardHolder> {
private final Actor actor;
private final ClipboardFormat format;
private final File file;
@ -712,9 +755,11 @@ public class SchematicCommands {
return new ClipboardHolder(clipboard);
}
}
}
private static class SchematicSaveTask implements Callable<Void> {
private final Actor actor;
private final ClipboardFormat format;
private final ClipboardHolder holder;
@ -722,7 +767,14 @@ public class SchematicCommands {
private final File rootDir;
private File file;
SchematicSaveTask(Actor actor, File file, File rootDir, ClipboardFormat format, ClipboardHolder holder, boolean overwrite) {
SchematicSaveTask(
Actor actor,
File file,
File rootDir,
ClipboardFormat format,
ClipboardHolder holder,
boolean overwrite
) {
this.actor = actor;
this.file = file;
this.rootDir = rootDir;
@ -738,12 +790,8 @@ public class SchematicCommands {
Clipboard target;
//FAWE start
boolean checkFilesize = false;
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS
&& Settings.IMP.EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT > -1) {
checkFilesize = true;
}
boolean checkFilesize = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS
&& Settings.IMP.EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT > -1;
double directorysizeKb = 0;
String curFilepath = file.getAbsolutePath();
@ -755,7 +803,7 @@ public class SchematicCommands {
int numFiles = -1;
if (checkFilesize) {
List<File> toAddUp = getFiles(rootDir, null, null);
if (toAddUp != null && toAddUp.size() != 0) {
if (toAddUp != null && toAddUp.size() != 0) {
for (File child : toAddUp) {
if (child.getName().endsWith(".schem") || child.getName().endsWith(".schematic")) {
directorysizeKb += Files.size(Paths.get(child.getAbsolutePath())) / 1000.0;
@ -779,7 +827,7 @@ public class SchematicCommands {
if (numFiles == -1) {
numFiles = 0;
List<File> toAddUp = getFiles(rootDir, null, null);
if (toAddUp != null && toAddUp.size() != 0) {
if (toAddUp != null && toAddUp.size() != 0) {
for (File child : toAddUp) {
if (child.getName().endsWith(".schem") || child.getName().endsWith(".schematic")) {
numFiles++;
@ -791,8 +839,10 @@ public class SchematicCommands {
if (numFiles >= limit) {
TextComponent noSlotsErr = TextComponent.of( //TODO - to be moved into captions/translatablecomponents
String.format("You have " + numFiles + "/" + limit + " saved schematics. Delete some to save this one!",
TextColor.RED));
String.format(
"You have " + numFiles + "/" + limit + " saved schematics. Delete some to save this one!",
TextColor.RED
));
LOGGER.info(actor.getName() + " failed to save " + file.getCanonicalPath() + " - too many schematics!");
throw new WorldEditException(noSlotsErr) {
};
@ -830,7 +880,7 @@ public class SchematicCommands {
double filesizeKb = Files.size(Paths.get(file.getAbsolutePath())) / 1000.0;
TextComponent filesizeNotif = TextComponent.of( //TODO - to be moved into captions/translatablecomponents
SCHEMATIC_NAME + " size: " + String.format("%.1f", filesizeKb) + "kb", TextColor.GRAY);
SCHEMATIC_NAME + " size: " + String.format("%.1f", filesizeKb) + "kb", TextColor.GRAY);
actor.print(filesizeNotif);
if (checkFilesize) {
@ -844,10 +894,15 @@ public class SchematicCommands {
if ((curKb) > allocatedKb) {
file.delete();
TextComponent notEnoughKbErr = TextComponent.of( //TODO - to be moved into captions/translatablecomponents
"You're about to be at " + String.format("%.1f", curKb) + "kb of schematics. ("
+ String.format("%dkb", allocatedKb) + " available) Delete some first to save this one!",
TextColor.RED);
TextComponent notEnoughKbErr = TextComponent.of(
//TODO - to be moved into captions/translatablecomponents
"You're about to be at " + String.format("%.1f", curKb) + "kb of schematics. ("
+ String.format(
"%dkb",
allocatedKb
) + " available) Delete some first to save this one!",
TextColor.RED
);
LOGGER.info(actor.getName() + " failed to save " + SCHEMATIC_NAME + " - not enough space!");
throw new WorldEditException(notEnoughKbErr) {
};
@ -858,16 +913,22 @@ public class SchematicCommands {
} else {
numFiles++;
}
TextComponent kbRemainingNotif = TextComponent.of( //TODO - to be moved into captions/translatablecomponents
"You have " + String.format("%.1f", (allocatedKb - curKb)) + "kb left for schematics.", TextColor.GRAY);
TextComponent kbRemainingNotif = TextComponent.of(
//TODO - to be moved into captions/translatablecomponents
"You have " + String.format("%.1f", (allocatedKb - curKb)) + "kb left for schematics.",
TextColor.GRAY
);
actor.print(kbRemainingNotif);
}
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Settings.IMP.EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT > -1) {
TextComponent slotsRemainingNotif = TextComponent.of( //TODO - to be moved into captions/translatablecomponents
"You have " + (Settings.IMP.EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT - numFiles)
+ " schematic file slots left.", TextColor.GRAY);
TextComponent slotsRemainingNotif = TextComponent.of(
//TODO - to be moved into captions/translatablecomponents
"You have " + (Settings.IMP.EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT - numFiles)
+ " schematic file slots left.",
TextColor.GRAY
);
actor.print(slotsRemainingNotif);
}
LOGGER.info(actor.getName() + " saved " + file.getCanonicalPath());
@ -878,9 +939,11 @@ public class SchematicCommands {
//FAWE end
return null;
}
}
private static class SchematicListTask implements Callable<Component> {
private final String prefix;
private final int sortType;
private final int page;
@ -889,8 +952,10 @@ public class SchematicCommands {
private final String filter;
private final String formatName;
SchematicListTask(String prefix, int sortType, int page, String pageCommand,
String filter, String formatName) {
SchematicListTask(
String prefix, int sortType, int page, String pageCommand,
String filter, String formatName
) {
this.prefix = prefix;
this.sortType = sortType;
this.page = page;
@ -936,9 +1001,11 @@ public class SchematicCommands {
PaginationBox paginationBox = new SchematicPaginationBox(prefix, files, pageCommand);
return paginationBox.create(page);
}
}
private static class SchematicPaginationBox extends PaginationBox {
//FAWE start - Expand to per player schematics
private final String prefix;
private final File[] files;
@ -957,21 +1024,24 @@ public class SchematicCommands {
File file = files[number];
Multimap<String, ClipboardFormat> exts = ClipboardFormats.getFileExtensionMap();
String format = exts.get(com.google.common.io.Files.getFileExtension(file.getName()))
.stream().findFirst().map(ClipboardFormat::getName).orElse("Unknown");
.stream().findFirst().map(ClipboardFormat::getName).orElse("Unknown");
boolean inRoot = file.getParentFile().getName().equals(prefix);
String path = inRoot ? file.getName() : file.getPath().split(Pattern.quote(prefix + File.separator))[1];
return TextComponent.builder()
.content("")
.append(TranslatableComponent.of("worldedit.schematic.load.symbol")
.clickEvent(ClickEvent
.of(ClickEvent.Action.RUN_COMMAND, "/schem load \"" + path + "\""))
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TranslatableComponent.of("worldedit.schematic.click-to-load"))))
.append(TextComponent.space())
.append(TextComponent.of(path)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of(format))))
.build();
.content("")
.append(TranslatableComponent.of("worldedit.schematic.load.symbol")
.clickEvent(ClickEvent
.of(ClickEvent.Action.RUN_COMMAND, "/schem load \"" + path + "\""))
.hoverEvent(HoverEvent.of(
HoverEvent.Action.SHOW_TEXT,
TranslatableComponent.of("worldedit.schematic.click-to-load")
)))
.append(TextComponent.space())
.append(TextComponent.of(path)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of(format))))
.build();
//FAWE end
}
@ -979,6 +1049,7 @@ public class SchematicCommands {
public int getComponentsSize() {
return files.length;
}
}
}

View File

@ -58,17 +58,19 @@ public class ScriptingCommands {
}
@Command(
name = "cs",
aliases = { "/cs" },
desc = "Execute a CraftScript"
name = "cs",
aliases = {"/cs"},
desc = "Execute a CraftScript"
)
@CommandPermissions("worldedit.scripting.execute")
@Logging(ALL)
public void execute(Player player, LocalSession session,
@Arg(desc = "Filename of the CraftScript to load")
String filename,
@Arg(desc = "Arguments to the CraftScript", def = "", variable = true)
List<String> args) throws WorldEditException {
public void execute(
Player player, LocalSession session,
@Arg(desc = "Filename of the CraftScript to load")
String filename,
@Arg(desc = "Arguments to the CraftScript", def = "", variable = true)
List<String> args
) throws WorldEditException {
if (!player.hasPermission("worldedit.scripting.execute." + filename)) {
player.print(Caption.of("worldedit.execute.script-permissions"));
return;
@ -80,19 +82,21 @@ public class ScriptingCommands {
File f = worldEdit.getSafeOpenFile(player, dir, filename, "js", "js");
worldEdit.runScript(player, f, Stream.concat(Stream.of(filename), args.stream())
.toArray(String[]::new));
.toArray(String[]::new));
}
@Command(
name = ".s",
aliases = { "/.s" },
desc = "Execute last CraftScript"
name = ".s",
aliases = {"/.s"},
desc = "Execute last CraftScript"
)
@CommandPermissions("worldedit.scripting.execute")
@Logging(ALL)
public void executeLast(Player player, LocalSession session,
@Arg(desc = "Arguments to the CraftScript", def = "", variable = true)
List<String> args) throws WorldEditException {
public void executeLast(
Player player, LocalSession session,
@Arg(desc = "Arguments to the CraftScript", def = "", variable = true)
List<String> args
) throws WorldEditException {
String lastScript = session.getLastScript();
@ -110,6 +114,7 @@ public class ScriptingCommands {
File f = worldEdit.getSafeOpenFile(player, dir, lastScript, "js", "js");
worldEdit.runScript(player, f, Stream.concat(Stream.of(lastScript), args.stream())
.toArray(String[]::new));
.toArray(String[]::new));
}
}

View File

@ -110,15 +110,17 @@ public class SelectionCommands {
}
@Command(
name = "/pos1",
aliases = "/1",
desc = "Set position 1"
name = "/pos1",
aliases = "/1",
desc = "Set position 1"
)
@Logging(POSITION)
@CommandPermissions("worldedit.selection.pos")
public void pos1(Actor actor, World world, LocalSession session,
@Arg(desc = "Coordinates to set position 1 to", def = "")
BlockVector3 coordinates) throws WorldEditException {
public void pos1(
Actor actor, World world, LocalSession session,
@Arg(desc = "Coordinates to set position 1 to", def = "")
BlockVector3 coordinates
) throws WorldEditException {
Location pos;
//FAWE start - clamp
if (coordinates != null) {
@ -141,15 +143,17 @@ public class SelectionCommands {
}
@Command(
name = "/pos2",
name = "/pos2",
aliases = "/2",
desc = "Set position 2"
desc = "Set position 2"
)
@Logging(POSITION)
@CommandPermissions("worldedit.selection.pos")
public void pos2(Actor actor, World world, LocalSession session,
@Arg(desc = "Coordinates to set position 2 to", def = "")
BlockVector3 coordinates) throws WorldEditException {
public void pos2(
Actor actor, World world, LocalSession session,
@Arg(desc = "Coordinates to set position 2 to", def = "")
BlockVector3 coordinates
) throws WorldEditException {
Location pos;
if (coordinates != null) {
//FAWE start - clamp
@ -162,7 +166,10 @@ public class SelectionCommands {
return;
}
if (!session.getRegionSelector(world).selectSecondary(pos.toVector().toBlockPoint(), ActorSelectorLimits.forActor(actor))) {
if (!session.getRegionSelector(world).selectSecondary(
pos.toVector().toBlockPoint(),
ActorSelectorLimits.forActor(actor)
)) {
actor.print(Caption.of("worldedit.pos.already-set"));
return;
}
@ -172,8 +179,8 @@ public class SelectionCommands {
}
@Command(
name = "/hpos1",
desc = "Set position 1 to targeted block"
name = "/hpos1",
desc = "Set position 1 to targeted block"
)
@CommandPermissions("worldedit.selection.hpos")
public void hpos1(Player player, LocalSession session) throws WorldEditException {
@ -181,7 +188,10 @@ public class SelectionCommands {
Location pos = player.getBlockTrace(300);
if (pos != null) {
if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos.toVector().toBlockPoint(), ActorSelectorLimits.forActor(player))) {
if (!session.getRegionSelector(player.getWorld()).selectPrimary(
pos.toVector().toBlockPoint(),
ActorSelectorLimits.forActor(player)
)) {
player.print(Caption.of("worldedit.hpos.already-set"));
return;
}
@ -194,8 +204,8 @@ public class SelectionCommands {
}
@Command(
name = "/hpos2",
desc = "Set position 2 to targeted block"
name = "/hpos2",
desc = "Set position 2 to targeted block"
)
@CommandPermissions("worldedit.selection.hpos")
public void hpos2(Player player, LocalSession session) throws WorldEditException {
@ -203,7 +213,10 @@ public class SelectionCommands {
Location pos = player.getBlockTrace(300);
if (pos != null) {
if (!session.getRegionSelector(player.getWorld()).selectSecondary(pos.toVector().toBlockPoint(), ActorSelectorLimits.forActor(player))) {
if (!session.getRegionSelector(player.getWorld()).selectSecondary(
pos.toVector().toBlockPoint(),
ActorSelectorLimits.forActor(player)
)) {
player.print(Caption.of("worldedit.hpos.already-set"));
return;
}
@ -216,19 +229,21 @@ public class SelectionCommands {
}
@Command(
name = "/chunk",
desc = "Set the selection to your current chunk.",
descFooter = "This command selects 256-block-tall areas,\nwhich can be specified by the y-coordinate.\nE.g. -c x,1,z will select from y=256 to y=511."
name = "/chunk",
desc = "Set the selection to your current chunk.",
descFooter = "This command selects 256-block-tall areas,\nwhich can be specified by the y-coordinate.\nE.g. -c x,1,z will select from y=256 to y=511."
)
@Logging(POSITION)
@CommandPermissions("worldedit.selection.chunk")
public void chunk(Actor actor, World world, LocalSession session,
@Arg(desc = "The chunk to select", def = "")
BlockVector3 coordinates,
@Switch(name = 's', desc = "Expand your selection to encompass all chunks that are part of it")
boolean expandSelection,
@Switch(name = 'c', desc = "Use chunk coordinates instead of block coordinates")
boolean useChunkCoordinates) throws WorldEditException {
public void chunk(
Actor actor, World world, LocalSession session,
@Arg(desc = "The chunk to select", def = "")
BlockVector3 coordinates,
@Switch(name = 's', desc = "Expand your selection to encompass all chunks that are part of it")
boolean expandSelection,
@Switch(name = 'c', desc = "Use chunk coordinates instead of block coordinates")
boolean useChunkCoordinates
) throws WorldEditException {
final BlockVector3 min;
final BlockVector3 max;
if (expandSelection) {
@ -259,8 +274,8 @@ public class SelectionCommands {
if (coordinates != null) {
// coords specified
minChunk = useChunkCoordinates
? coordinates
: ChunkStore.toChunk3d(coordinates);
? coordinates
: ChunkStore.toChunk3d(coordinates);
} else {
// use player loc
if (actor instanceof Locatable) {
@ -273,10 +288,12 @@ public class SelectionCommands {
min = minChunk.shl(CHUNK_SHIFTS, CHUNK_SHIFTS_Y, CHUNK_SHIFTS);
max = min.add(15, world.getMaxY(), 15);
actor.print(Caption.of("worldedit.chunk.selected",
actor.print(Caption.of(
"worldedit.chunk.selected",
TextComponent.of(minChunk.getBlockX()),
TextComponent.of(minChunk.getBlockY()),
TextComponent.of(minChunk.getBlockZ())));
TextComponent.of(minChunk.getBlockZ())
));
}
final CuboidRegionSelector selector;
@ -294,12 +311,14 @@ public class SelectionCommands {
}
@Command(
name = "/wand",
desc = "Get the wand object"
name = "/wand",
desc = "Get the wand object"
)
@CommandPermissions("worldedit.wand")
public void wand(Player player, LocalSession session,
@Switch(name = 'n', desc = "Get a navigation wand") boolean navWand) throws WorldEditException {
public void wand(
Player player, LocalSession session,
@Switch(name = 'n', desc = "Get a navigation wand") boolean navWand
) throws WorldEditException {
//FAWE start
session.loadDefaults(player, true);
//FAWE end
@ -325,9 +344,9 @@ public class SelectionCommands {
}
@Command(
name = "toggleeditwand",
aliases = { "/toggleeditwand" },
desc = "Remind the user that the wand is now a tool and can be unbound with /tool none."
name = "toggleeditwand",
aliases = {"/toggleeditwand"},
desc = "Remind the user that the wand is now a tool and can be unbound with /tool none."
)
@CommandPermissions("worldedit.wand.toggle")
public void toggleWand(Player player) {
@ -345,19 +364,21 @@ public class SelectionCommands {
}
@Command(
name = "/contract",
desc = "Contract the selection area"
name = "/contract",
desc = "Contract the selection area"
)
@Logging(REGION)
@CommandPermissions("worldedit.selection.contract")
public void contract(Actor actor, World world, LocalSession session,
@Arg(desc = "Amount to contract the selection by")
int amount,
@Arg(desc = "Amount to contract the selection by in the other direction", def = "0")
int reverseAmount,
@Arg(desc = "Direction to contract", def = Direction.AIM)
@MultiDirection
List<BlockVector3> direction) throws WorldEditException {
public void contract(
Actor actor, World world, LocalSession session,
@Arg(desc = "Amount to contract the selection by")
int amount,
@Arg(desc = "Amount to contract the selection by in the other direction", def = "0")
int reverseAmount,
@Arg(desc = "Direction to contract", def = Direction.AIM)
@MultiDirection
List<BlockVector3> direction
) throws WorldEditException {
try {
Region region = session.getSelection(world);
long oldSize = region.getVolume();
@ -382,17 +403,19 @@ public class SelectionCommands {
}
@Command(
name = "/shift",
desc = "Shift the selection area"
name = "/shift",
desc = "Shift the selection area"
)
@Logging(REGION)
@CommandPermissions("worldedit.selection.shift")
public void shift(Actor actor, World world, LocalSession session,
@Arg(desc = "Amount to shift the selection by")
int amount,
@Arg(desc = "Direction to contract", def = Direction.AIM)
@MultiDirection
List<BlockVector3> direction) throws WorldEditException {
public void shift(
Actor actor, World world, LocalSession session,
@Arg(desc = "Amount to shift the selection by")
int amount,
@Arg(desc = "Direction to contract", def = Direction.AIM)
@MultiDirection
List<BlockVector3> direction
) throws WorldEditException {
try {
Region region = session.getSelection(world);
@ -411,18 +434,20 @@ public class SelectionCommands {
}
@Command(
name = "/outset",
desc = "Outset the selection area"
name = "/outset",
desc = "Outset the selection area"
)
@Logging(REGION)
@CommandPermissions("worldedit.selection.outset")
public void outset(Actor actor, World world, LocalSession session,
@Arg(desc = "Amount to expand the selection by in all directions")
int amount,
@Switch(name = 'h', desc = "Only expand horizontally")
boolean onlyHorizontal,
@Switch(name = 'v', desc = "Only expand vertically")
boolean onlyVertical) throws WorldEditException {
public void outset(
Actor actor, World world, LocalSession session,
@Arg(desc = "Amount to expand the selection by in all directions")
int amount,
@Switch(name = 'h', desc = "Only expand horizontally")
boolean onlyHorizontal,
@Switch(name = 'v', desc = "Only expand vertically")
boolean onlyVertical
) throws WorldEditException {
Region region = session.getSelection(world);
region.expand(getChangesForEachDir(amount, onlyHorizontal, onlyVertical));
session.getRegionSelector(world).learnChanges();
@ -431,18 +456,20 @@ public class SelectionCommands {
}
@Command(
name = "/inset",
desc = "Inset the selection area"
name = "/inset",
desc = "Inset the selection area"
)
@Logging(REGION)
@CommandPermissions("worldedit.selection.inset")
public void inset(Actor actor, World world, LocalSession session,
@Arg(desc = "Amount to contract the selection by in all directions")
int amount,
@Switch(name = 'h', desc = "Only contract horizontally")
boolean onlyHorizontal,
@Switch(name = 'v', desc = "Only contract vertically")
boolean onlyVertical) throws WorldEditException {
public void inset(
Actor actor, World world, LocalSession session,
@Arg(desc = "Amount to contract the selection by in all directions")
int amount,
@Switch(name = 'h', desc = "Only contract horizontally")
boolean onlyHorizontal,
@Switch(name = 'v', desc = "Only contract vertically")
boolean onlyVertical
) throws WorldEditException {
Region region = session.getSelection(world);
region.contract(getChangesForEachDir(amount, onlyHorizontal, onlyVertical));
session.getRegionSelector(world).learnChanges();
@ -469,13 +496,15 @@ public class SelectionCommands {
}
@Command(
name = "/size",
desc = "Get information about the selection"
name = "/size",
desc = "Get information about the selection"
)
@CommandPermissions("worldedit.selection.size")
public void size(Actor actor, World world, LocalSession session,
@Switch(name = 'c', desc = "Get clipboard info instead")
boolean clipboardInfo) throws WorldEditException {
public void size(
Actor actor, World world, LocalSession session,
@Switch(name = 'c', desc = "Get clipboard info instead")
boolean clipboardInfo
) throws WorldEditException {
Region region;
if (clipboardInfo) {
//FAWE start - Modify for cross server clipboards
@ -504,7 +533,13 @@ public class SelectionCommands {
String originStr = origin.getBlockX() + "," + origin.getBlockY() + "," + origin.getBlockZ();
long numBlocks = ((long) size.getBlockX() * size.getBlockY() * size.getBlockZ());
actor.print(Caption.of("worldedit.size.offset", TextComponent.of(name), TextComponent.of(sizeStr), TextComponent.of(originStr), TextComponent.of(numBlocks)));
actor.print(Caption.of(
"worldedit.size.offset",
TextComponent.of(name),
TextComponent.of(sizeStr),
TextComponent.of(originStr),
TextComponent.of(numBlocks)
));
index++;
}
return;
@ -523,18 +558,23 @@ public class SelectionCommands {
.add(1, 1, 1);
actor.print(Caption.of("worldedit.size.size", TextComponent.of(size.toString())));
actor.print(Caption.of("worldedit.size.distance", TextComponent.of(region.getMaximumPoint().distance(region.getMinimumPoint()))));
actor.print(Caption.of(
"worldedit.size.distance",
TextComponent.of(region.getMaximumPoint().distance(region.getMinimumPoint()))
));
actor.print(Caption.of("worldedit.size.blocks", TextComponent.of(region.getVolume())));
}
@Command(
name = "/count",
desc = "Counts the number of blocks matching a mask"
name = "/count",
desc = "Counts the number of blocks matching a mask"
)
@CommandPermissions("worldedit.analysis.count")
public int count(Actor actor, World world, LocalSession session, EditSession editSession,
@Arg(desc = "The mask of blocks to match")
Mask mask) throws WorldEditException {
public int count(
Actor actor, World world, LocalSession session, EditSession editSession,
@Arg(desc = "The mask of blocks to match")
Mask mask
) throws WorldEditException {
//FAWE start > the mask will have been initialised with a WorldWrapper extent (very bad/slow)
if (mask instanceof AbstractExtentMask) {
((AbstractExtentMask) mask).setExtent(editSession);
@ -546,20 +586,22 @@ public class SelectionCommands {
}
@Command(
name = "/distr",
desc = "Get the distribution of blocks in the selection"
name = "/distr",
desc = "Get the distribution of blocks in the selection"
)
@CommandPermissions("worldedit.analysis.distr")
public void distr(Actor actor, World world, LocalSession session,
//FAWE start > add extent to RegionVisitor to allow chunk preloading
EditSession editSession,
//FAWE end
@Switch(name = 'c', desc = "Get the distribution of the clipboard instead")
boolean clipboardDistr,
@Switch(name = 'd', desc = "Separate blocks by state")
boolean separateStates,
@ArgFlag(name = 'p', desc = "Gets page from a previous distribution.")
Integer page) throws WorldEditException {
public void distr(
Actor actor, World world, LocalSession session,
//FAWE start > add extent to RegionVisitor to allow chunk preloading
EditSession editSession,
//FAWE end
@Switch(name = 'c', desc = "Get the distribution of the clipboard instead")
boolean clipboardDistr,
@Switch(name = 'd', desc = "Separate blocks by state")
boolean separateStates,
@ArgFlag(name = 'p', desc = "Gets page from a previous distribution.")
Integer page
) throws WorldEditException {
List<Countable<BlockState>> distribution;
if (page == null) {
@ -572,7 +614,7 @@ public class SelectionCommands {
Operations.completeBlindly(visitor);
distribution = count.getDistribution();
} else {
distribution = editSession.getBlockDistribution(session.getSelection(world), separateStates);
distribution = editSession.getBlockDistribution(session.getSelection(world), separateStates);
}
session.setLastDistribution(distribution);
page = 1;
@ -597,18 +639,20 @@ public class SelectionCommands {
}
@Command(
name = "/sel",
aliases = { ";", "/desel", "/deselect" },
desc = "Choose a region selector"
name = "/sel",
aliases = {";", "/desel", "/deselect"},
desc = "Choose a region selector"
)
//FAWE start
@CommandPermissions("worldedit.analysis.sel")
//FAWE end
public void select(Actor actor, World world, LocalSession session,
@Arg(desc = "Selector to switch to", def = "")
SelectorChoice selector,
@Switch(name = 'd', desc = "Set default selector")
boolean setDefaultSelector) throws WorldEditException {
public void select(
Actor actor, World world, LocalSession session,
@Arg(desc = "Selector to switch to", def = "")
SelectorChoice selector,
@Switch(name = 'd', desc = "Set default selector")
boolean setDefaultSelector
) throws WorldEditException {
if (selector == null) {
session.getRegionSelector(world).clear();
session.dispatchCUISelection(actor);
@ -632,7 +676,10 @@ public class SelectionCommands {
newSelector = new Polygonal2DRegionSelector(oldSelector);
actor.print(Caption.of("worldedit.select.poly.message"));
Optional<Integer> limit = ActorSelectorLimits.forActor(actor).getPolygonVertexLimit();
limit.ifPresent(integer -> actor.print(Caption.of("worldedit.select.poly.limit-message", TextComponent.of(integer))));
limit.ifPresent(integer -> actor.print(Caption.of(
"worldedit.select.poly.limit-message",
TextComponent.of(integer)
)));
break;
}
case ELLIPSOID:
@ -653,7 +700,10 @@ public class SelectionCommands {
newSelector = new ConvexPolyhedralRegionSelector(oldSelector);
actor.print(Caption.of("worldedit.select.convex.message"));
Optional<Integer> limit = ActorSelectorLimits.forActor(actor).getPolyhedronVertexLimit();
limit.ifPresent(integer -> actor.print(Caption.of("worldedit.select.convex.limit-message", TextComponent.of(integer))));
limit.ifPresent(integer -> actor.print(Caption.of(
"worldedit.select.convex.limit-message",
TextComponent.of(integer)
)));
break;
}
//FAWE start
@ -776,5 +826,7 @@ public class SelectionCommands {
.append(TextComponent.newline());
return super.create(page);
}
}
}

View File

@ -75,7 +75,7 @@ public class SnapshotCommands {
static void checkSnapshotsConfigured(LocalConfiguration localConfiguration) {
if (!localConfiguration.snapshotsConfigured) {
throw new StopExecutionException(Caption.of(
"worldedit.restore.not-configured"
"worldedit.restore.not-configured"
));
}
}
@ -95,13 +95,15 @@ public class SnapshotCommands {
@Command(
name = "list",
desc = "List snapshots"
name = "list",
desc = "List snapshots"
)
@CommandPermissions("worldedit.snapshots.list")
void list(Actor actor, World world,
@ArgFlag(name = 'p', desc = "Page of results to return", def = "1")
int page) throws WorldEditException, IOException {
void list(
Actor actor, World world,
@ArgFlag(name = 'p', desc = "Page of results to return", def = "1")
int page
) throws WorldEditException, IOException {
LocalConfiguration config = we.getConfiguration();
checkSnapshotsConfigured(config);
@ -112,17 +114,17 @@ public class SnapshotCommands {
List<Snapshot> snapshots;
try (Stream<Snapshot> snapshotStream =
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
snapshots = snapshotStream
.collect(toList());
.collect(toList());
}
if (!snapshots.isEmpty()) {
actor.print(new SnapshotListBox(world.getName(), snapshots).create(page));
} else {
actor.print(Caption.of(
"worldedit.restore.none-for-specific-world",
TextComponent.of(world.getName())
"worldedit.restore.none-for-specific-world",
TextComponent.of(world.getName())
));
if (config.snapshotDatabase instanceof FileSystemSnapshotDatabase) {
@ -130,23 +132,25 @@ public class SnapshotCommands {
Path root = db.getRoot();
if (Files.isDirectory(root)) {
WorldEdit.logger.info("No snapshots were found for world '"
+ world.getName() + "'; looked in " + root.toRealPath());
+ world.getName() + "'; looked in " + root.toRealPath());
} else {
WorldEdit.logger.info("No snapshots were found for world '"
+ world.getName() + "'; " + root.toRealPath() + " is not a directory");
+ world.getName() + "'; " + root.toRealPath() + " is not a directory");
}
}
}
}
@Command(
name = "use",
desc = "Choose a snapshot to use"
name = "use",
desc = "Choose a snapshot to use"
)
@CommandPermissions("worldedit.snapshots.restore")
void use(Actor actor, World world, LocalSession session,
@Arg(desc = "Snapshot to use")
String name) throws IOException {
void use(
Actor actor, World world, LocalSession session,
@Arg(desc = "Snapshot to use")
String name
) throws IOException {
LocalConfiguration config = we.getConfiguration();
checkSnapshotsConfigured(config);
@ -159,9 +163,9 @@ public class SnapshotCommands {
if (name.equalsIgnoreCase("latest")) {
Snapshot snapshot;
try (Stream<Snapshot> snapshotStream =
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
snapshot = snapshotStream
.findFirst().orElse(null);
.findFirst().orElse(null);
}
if (snapshot != null) {
@ -182,7 +186,7 @@ public class SnapshotCommands {
}
session.setSnapshotExperimental(snapshot.get());
actor.print(Caption.of(
"worldedit.snapshot.use", TextComponent.of(name)
"worldedit.snapshot.use", TextComponent.of(name)
));
} else {
actor.print(Caption.of("worldedit.restore.not-available"));
@ -191,13 +195,15 @@ public class SnapshotCommands {
}
@Command(
name = "sel",
desc = "Choose the snapshot based on the list id"
name = "sel",
desc = "Choose the snapshot based on the list id"
)
@CommandPermissions("worldedit.snapshots.restore")
void sel(Actor actor, World world, LocalSession session,
@Arg(desc = "The list ID to select")
int index) throws IOException {
void sel(
Actor actor, World world, LocalSession session,
@Arg(desc = "The list ID to select")
int index
) throws IOException {
LocalConfiguration config = we.getConfiguration();
checkSnapshotsConfigured(config);
@ -213,14 +219,14 @@ public class SnapshotCommands {
List<Snapshot> snapshots;
try (Stream<Snapshot> snapshotStream =
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
snapshots = snapshotStream
.collect(toList());
.collect(toList());
}
if (snapshots.size() < index) {
actor.print(Caption.of(
"worldedit.snapshot.index-oob",
TextComponent.of(snapshots.size())
"worldedit.snapshot.index-oob",
TextComponent.of(snapshots.size())
));
return;
}
@ -234,19 +240,21 @@ public class SnapshotCommands {
}
session.setSnapshotExperimental(snapshot);
actor.print(Caption.of(
"worldedit.snapshot.use",
TextComponent.of(snapshot.getInfo().getDisplayName())
"worldedit.snapshot.use",
TextComponent.of(snapshot.getInfo().getDisplayName())
));
}
@Command(
name = "before",
desc = "Choose the nearest snapshot before a date"
name = "before",
desc = "Choose the nearest snapshot before a date"
)
@CommandPermissions("worldedit.snapshots.restore")
void before(Actor actor, World world, LocalSession session,
@Arg(desc = "The soonest date that may be used")
ZonedDateTime date) throws IOException {
void before(
Actor actor, World world, LocalSession session,
@Arg(desc = "The soonest date that may be used")
ZonedDateTime date
) throws IOException {
LocalConfiguration config = we.getConfiguration();
checkSnapshotsConfigured(config);
@ -257,15 +265,16 @@ public class SnapshotCommands {
Snapshot snapshot;
try (Stream<Snapshot> snapshotStream =
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
snapshot = snapshotStream
.findFirst().orElse(null);
.findFirst().orElse(null);
}
if (snapshot == null) {
actor.print(Caption.of(
"worldedit.snapshot.none-before",
TextComponent.of(dateFormat.withZone(session.getTimeZone()).format(date)))
"worldedit.snapshot.none-before",
TextComponent.of(dateFormat.withZone(session.getTimeZone()).format(date))
)
);
} else {
if (session.getSnapshotExperimental() != null) {
@ -273,20 +282,22 @@ public class SnapshotCommands {
}
session.setSnapshotExperimental(snapshot);
actor.print(Caption.of(
"worldedit.snapshot.use",
TextComponent.of(snapshot.getInfo().getDisplayName())
"worldedit.snapshot.use",
TextComponent.of(snapshot.getInfo().getDisplayName())
));
}
}
@Command(
name = "after",
desc = "Choose the nearest snapshot after a date"
name = "after",
desc = "Choose the nearest snapshot after a date"
)
@CommandPermissions("worldedit.snapshots.restore")
void after(Actor actor, World world, LocalSession session,
@Arg(desc = "The soonest date that may be used")
ZonedDateTime date) throws IOException {
void after(
Actor actor, World world, LocalSession session,
@Arg(desc = "The soonest date that may be used")
ZonedDateTime date
) throws IOException {
LocalConfiguration config = we.getConfiguration();
checkSnapshotsConfigured(config);
@ -297,14 +308,15 @@ public class SnapshotCommands {
Snapshot snapshot;
try (Stream<Snapshot> snapshotStream =
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
snapshot = snapshotStream
.findFirst().orElse(null);
.findFirst().orElse(null);
}
if (snapshot == null) {
actor.print(Caption.of(
"worldedit.snapshot.none-after",
TextComponent.of(dateFormat.withZone(session.getTimeZone()).format(date)))
"worldedit.snapshot.none-after",
TextComponent.of(dateFormat.withZone(session.getTimeZone()).format(date))
)
);
} else {
if (session.getSnapshotExperimental() != null) {
@ -312,13 +324,14 @@ public class SnapshotCommands {
}
session.setSnapshotExperimental(snapshot);
actor.print(Caption.of(
"worldedit.snapshot.use",
TextComponent.of(snapshot.getInfo().getDisplayName())
"worldedit.snapshot.use",
TextComponent.of(snapshot.getInfo().getDisplayName())
));
}
}
private static class SnapshotListBox extends PaginationBox {
private final List<Snapshot> snapshots;
SnapshotListBox(String world, List<Snapshot> snapshots) {
@ -331,14 +344,16 @@ public class SnapshotCommands {
final Snapshot snapshot = snapshots.get(number);
String displayName = snapshot.getInfo().getDisplayName();
return TextComponent.of(number + 1 + ". ", TextColor.GOLD)
.append(TextComponent.builder(displayName, TextColor.LIGHT_PURPLE)
.hoverEvent(HoverEvent.showText(TextComponent.of("Click to use")))
.clickEvent(ClickEvent.runCommand("/snap use " + displayName)));
.append(TextComponent.builder(displayName, TextColor.LIGHT_PURPLE)
.hoverEvent(HoverEvent.showText(TextComponent.of("Click to use")))
.clickEvent(ClickEvent.runCommand("/snap use " + displayName)));
}
@Override
public int getComponentsSize() {
return snapshots.size();
}
}
}

View File

@ -59,15 +59,17 @@ public class SnapshotUtilCommands {
}
@Command(
name = "restore",
aliases = { "/restore" },
desc = "Restore the selection from a snapshot"
name = "restore",
aliases = {"/restore"},
desc = "Restore the selection from a snapshot"
)
@Logging(REGION)
@CommandPermissions("worldedit.snapshots.restore")
public void restore(Actor actor, World world, LocalSession session, EditSession editSession,
@Arg(name = "snapshot", desc = "The snapshot to restore", def = "")
String snapshotName) throws WorldEditException, IOException {
public void restore(
Actor actor, World world, LocalSession session, EditSession editSession,
@Arg(name = "snapshot", desc = "The snapshot to restore", def = "")
String snapshotName
) throws WorldEditException, IOException {
LocalConfiguration config = we.getConfiguration();
checkSnapshotsConfigured(config);
@ -94,22 +96,22 @@ public class SnapshotUtilCommands {
// No snapshot set?
if (snapshot == null) {
try (Stream<Snapshot> snapshotStream =
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
config.snapshotDatabase.getSnapshotsNewestFirst(world.getName())) {
snapshot = snapshotStream
.findFirst().orElse(null);
.findFirst().orElse(null);
}
if (snapshot == null) {
actor.print(Caption.of(
"worldedit.restore.none-for-specific-world",
TextComponent.of(world.getName())
"worldedit.restore.none-for-specific-world",
TextComponent.of(world.getName())
));
return;
}
}
actor.print(Caption.of(
"worldedit.restore.loaded",
TextComponent.of(snapshot.getInfo().getDisplayName())
"worldedit.restore.loaded",
TextComponent.of(snapshot.getInfo().getDisplayName())
));
try {
@ -130,9 +132,11 @@ public class SnapshotUtilCommands {
actor.print(Caption.of("worldedit.restore.chunk-load-failed"));
}
} else {
actor.print(Caption.of("worldedit.restore.restored",
TextComponent.of(restore.getMissingChunks().size()),
TextComponent.of(restore.getErrorChunks().size())));
actor.print(Caption.of(
"worldedit.restore.restored",
TextComponent.of(restore.getMissingChunks().size()),
TextComponent.of(restore.getErrorChunks().size())
));
}
} finally {
try {
@ -141,4 +145,5 @@ public class SnapshotUtilCommands {
}
}
}
}

View File

@ -37,6 +37,7 @@ import org.enginehub.piston.annotation.param.Arg;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class SuperPickaxeCommands {
private final WorldEdit we;
public SuperPickaxeCommands(WorldEdit we) {
@ -44,8 +45,8 @@ public class SuperPickaxeCommands {
}
@Command(
name = "single",
desc = "Enable the single block super pickaxe mode"
name = "single",
desc = "Enable the single block super pickaxe mode"
)
@CommandPermissions("worldedit.superpickaxe")
public void single(Player player, LocalSession session) throws WorldEditException {
@ -55,13 +56,15 @@ public class SuperPickaxeCommands {
}
@Command(
name = "area",
desc = "Enable the area super pickaxe pickaxe mode"
name = "area",
desc = "Enable the area super pickaxe pickaxe mode"
)
@CommandPermissions("worldedit.superpickaxe.area")
public void area(Player player, LocalSession session,
@Arg(desc = "The range of the area pickaxe")
int range) throws WorldEditException {
public void area(
Player player, LocalSession session,
@Arg(desc = "The range of the area pickaxe")
int range
) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
@ -75,14 +78,16 @@ public class SuperPickaxeCommands {
}
@Command(
name = "recursive",
aliases = { "recur" },
desc = "Enable the recursive super pickaxe pickaxe mode"
name = "recursive",
aliases = {"recur"},
desc = "Enable the recursive super pickaxe pickaxe mode"
)
@CommandPermissions("worldedit.superpickaxe.recursive")
public void recursive(Player player, LocalSession session,
@Arg(desc = "The range of the recursive pickaxe")
double range) throws WorldEditException {
public void recursive(
Player player, LocalSession session,
@Arg(desc = "The range of the recursive pickaxe")
double range
) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
@ -95,4 +100,5 @@ public class SuperPickaxeCommands {
session.enableSuperPickAxe();
player.print(Caption.of("worldedit.tool.superpickaxe.mode.recursive"));
}
}

View File

@ -19,8 +19,8 @@
package com.sk89q.worldedit.command;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.command.tool.brush.InspectBrush;
import com.fastasyncworldedit.core.configuration.Caption;
import com.google.common.collect.Collections2;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
@ -76,27 +76,29 @@ public class ToolCommands {
.clickEvent(ClickEvent.suggestCommand("/tool unbind"))
.build();
public static void register(CommandRegistrationHandler registration,
CommandManager commandManager,
CommandManagerService commandManagerService,
WorldEdit worldEdit) {
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)
collect,
ToolCommandsRegistration.builder(),
new ToolCommands(worldEdit)
);
// Register deprecated global commands
Set<org.enginehub.piston.Command> commands = collect.getAllCommands()
.collect(Collectors.toSet());
.collect(Collectors.toSet());
for (org.enginehub.piston.Command command : commands) {
if (command.getAliases().contains("unbind")) {
// Don't register new /tool <whatever> alias
command = command.toBuilder().aliases(
Collections2.filter(command.getAliases(), alias -> !"unbind".equals(alias))
Collections2.filter(command.getAliases(), alias -> !"unbind".equals(alias))
).build();
}
if (command.getName().equals("stacker")) {
@ -104,45 +106,47 @@ public class ToolCommands {
continue;
}
commandManager.register(CommandUtil.deprecate(
command, "Global tool names cause conflicts "
+ "and will be removed in WorldEdit 8",
CommandUtil.ReplacementMessageGenerator.forNewCommand(ToolCommands::asNonGlobal)
command, "Global tool names cause conflicts "
+ "and will be removed in WorldEdit 8",
CommandUtil.ReplacementMessageGenerator.forNewCommand(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());
.map(command ->
command.toBuilder().aliases(
Collections2.filter(command.getAliases(), alias -> !alias.startsWith("/"))
).build()
)
.collect(Collectors.toSet());
commandManager.register("tool", command -> {
command.addPart(SubCommandPart.builder(
Caption.of("tool"),
TextComponent.of("The tool to bind")
TextComponent.of("The tool to bind")
)
.withCommands(nonGlobalCommands)
.required()
.build());
.withCommands(nonGlobalCommands)
.required()
.build());
command.description(TextComponent.of("Binds a tool to the item in your hand"));
command.condition(new SubCommandPermissionCondition.Generator(nonGlobalCommands).build());
});
}
private static String asNonGlobal(org.enginehub.piston.Command oldCommand,
CommandParameters oldParameters) {
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);
.map(CommandMetadata::getCalledName)
.filter(n -> !n.startsWith("/"))
.orElseGet(oldCommand::getName);
return "/tool " + name;
}
static void setToolNone(Player player, LocalSession session, boolean isBrush)
throws InvalidToolBindException {
throws InvalidToolBindException {
//FAWE start
isBrush = session.getTool(player) instanceof BrushTool;
session.setTool(player.getItemInHand(HandSide.MAIN_HAND).getType(), null);
@ -154,8 +158,10 @@ public class ToolCommands {
sender.print(Caption.of("worldedit.tool.unbind-instruction", commandComponent));
}
private static void setTool(Player player, LocalSession session, Tool tool,
String translationKey) throws InvalidToolBindException {
private static void setTool(
Player player, LocalSession session, Tool tool,
String translationKey
) throws InvalidToolBindException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), tool);
player.print(Caption.of(translationKey, itemStack.getRichName()));
@ -169,9 +175,9 @@ public class ToolCommands {
}
@Command(
name = "none",
aliases = "unbind",
desc = "Unbind a bound tool from your current item"
name = "none",
aliases = "unbind",
desc = "Unbind a bound tool from your current item"
)
@CommandPermissions("worldedit.tool.none")
public void none(Player player, LocalSession session) throws WorldEditException {
@ -179,9 +185,9 @@ public class ToolCommands {
}
@Command(
name = "selwand",
aliases = "/selwand",
desc = "Selection wand tool"
name = "selwand",
aliases = "/selwand",
desc = "Selection wand tool"
)
@CommandPermissions("worldedit.setwand")
public void selwand(Player player, LocalSession session) throws WorldEditException {
@ -191,9 +197,9 @@ public class ToolCommands {
}
@Command(
name = "navwand",
aliases = "/navwand",
desc = "Navigation wand tool"
name = "navwand",
aliases = "/navwand",
desc = "Navigation wand tool"
)
@CommandPermissions("worldedit.setwand")
public void navwand(Player player, LocalSession session) throws WorldEditException {
@ -203,9 +209,9 @@ public class ToolCommands {
}
@Command(
name = "info",
aliases = { "/info" },
desc = "Block information tool"
name = "info",
aliases = {"/info"},
desc = "Block information tool"
)
@CommandPermissions("worldedit.tool.info")
public void info(Player player, LocalSession session) throws WorldEditException {
@ -215,7 +221,7 @@ public class ToolCommands {
//FAWE start
@Command(
name = "inspect",
aliases = { "/inspect" },
aliases = {"/inspect"},
desc = "Inspect edits within a radius"
)
@CommandPermissions("worldedit.tool.inspect")
@ -225,46 +231,52 @@ public class ToolCommands {
//FAWE end
@Command(
name = "tree",
aliases = { "/tree" },
desc = "Tree generator tool"
name = "tree",
aliases = {"/tree"},
desc = "Tree generator tool"
)
@CommandPermissions("worldedit.tool.tree")
public void tree(Player player, LocalSession session,
@Arg(desc = "Type of tree to generate", def = "tree")
TreeGenerator.TreeType type) throws WorldEditException {
public void tree(
Player player, LocalSession session,
@Arg(desc = "Type of tree to generate", def = "tree")
TreeGenerator.TreeType type
) throws WorldEditException {
setTool(player, session, new TreePlanter(type), "worldedit.tool.tree.equip");
}
@Command(
name = "stacker",
desc = "Block stacker tool"
name = "stacker",
desc = "Block stacker tool"
)
@CommandPermissions("worldedit.tool.stack")
public void stacker(Player player, LocalSession session,
@Arg(desc = "The max range of the stack", def = "10")
int range,
@Arg(desc = "The mask to stack until", def = "!#existing")
Mask mask) throws WorldEditException {
public void stacker(
Player player, LocalSession session,
@Arg(desc = "The max range of the stack", def = "10")
int range,
@Arg(desc = "The mask to stack until", def = "!#existing")
Mask mask
) throws WorldEditException {
setTool(player, session, new StackTool(range, mask), "worldedit.tool.stack.equip");
}
@Command(
name = "repl",
aliases = { "/repl" },
desc = "Block replacer tool"
name = "repl",
aliases = {"/repl"},
desc = "Block replacer tool"
)
@CommandPermissions("worldedit.tool.replacer")
public void repl(Player player, LocalSession session,
@Arg(desc = "The pattern of blocks to place")
Pattern pattern) throws WorldEditException {
public void repl(
Player player, LocalSession session,
@Arg(desc = "The pattern of blocks to place")
Pattern pattern
) throws WorldEditException {
setTool(player, session, new BlockReplacer(pattern), "worldedit.tool.repl.equip");
}
@Command(
name = "cycler",
aliases = { "/cycler" },
desc = "Block data cycler tool"
name = "cycler",
aliases = {"/cycler"},
desc = "Block data cycler tool"
)
@CommandPermissions("worldedit.tool.data-cycler")
public void cycler(Player player, LocalSession session) throws WorldEditException {
@ -272,16 +284,18 @@ public class ToolCommands {
}
@Command(
name = "floodfill",
aliases = { "flood", "/flood", "/floodfill" },
desc = "Flood fill tool"
name = "floodfill",
aliases = {"flood", "/flood", "/floodfill"},
desc = "Flood fill tool"
)
@CommandPermissions("worldedit.tool.flood-fill")
public void floodFill(Player player, LocalSession session,
@Arg(desc = "The pattern to flood fill")
Pattern pattern,
@Arg(desc = "The range to perform the fill")
int range) throws WorldEditException {
public void floodFill(
Player player, LocalSession session,
@Arg(desc = "The pattern to flood fill")
Pattern pattern,
@Arg(desc = "The range to perform the fill")
int range
) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
@ -293,9 +307,9 @@ public class ToolCommands {
}
@Command(
name = "deltree",
aliases = { "/deltree" },
desc = "Floating tree remover tool"
name = "deltree",
aliases = {"/deltree"},
desc = "Floating tree remover tool"
)
@CommandPermissions("worldedit.tool.deltree")
public void deltree(Player player, LocalSession session) throws WorldEditException {
@ -303,9 +317,9 @@ public class ToolCommands {
}
@Command(
name = "farwand",
aliases = { "/warwand" },
desc = "Wand at a distance tool"
name = "farwand",
aliases = {"/warwand"},
desc = "Wand at a distance tool"
)
@CommandPermissions("worldedit.tool.farwand")
public void farwand(Player player, LocalSession session) throws WorldEditException {
@ -313,16 +327,18 @@ public class ToolCommands {
}
@Command(
name = "lrbuild",
aliases = { "/lrbuild" },
desc = "Long-range building tool"
name = "lrbuild",
aliases = {"/lrbuild"},
desc = "Long-range building tool"
)
@CommandPermissions("worldedit.tool.lrbuild")
public void longrangebuildtool(Player player, LocalSession session,
@Arg(desc = "Pattern to set on left-click")
Pattern primary,
@Arg(desc = "Pattern to set on right-click")
Pattern secondary) throws WorldEditException {
public void longrangebuildtool(
Player player, LocalSession session,
@Arg(desc = "Pattern to set on left-click")
Pattern primary,
@Arg(desc = "Pattern to set on right-click")
Pattern secondary
) throws WorldEditException {
setTool(player, session, new LongRangeBuildTool(primary, secondary), "worldedit.tool.lrbuild.equip");
Component primaryName;
Component secondaryName;
@ -338,4 +354,5 @@ public class ToolCommands {
}
player.print(Caption.of("worldedit.tool.lrbuild.set", primaryName, secondaryName));
}
}

View File

@ -19,10 +19,10 @@
package com.sk89q.worldedit.command;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.command.tool.brush.BrushSettings;
import com.fastasyncworldedit.core.command.tool.TargetMode;
import com.fastasyncworldedit.core.command.tool.brush.BrushSettings;
import com.fastasyncworldedit.core.command.tool.scroll.Scroll;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.util.MathMan;
import com.fastasyncworldedit.core.util.StringMan;
import com.google.common.collect.Iterables;
@ -55,6 +55,7 @@ import java.util.Locale;
*/
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class ToolUtilCommands {
private final WorldEdit we;
public ToolUtilCommands(WorldEdit we) {
@ -63,16 +64,18 @@ public class ToolUtilCommands {
//FAWE start - destination mask > mask
@Command(
name = "mask",
aliases = "/mask",
desc = "Set the brush destination mask"
name = "mask",
aliases = "/mask",
desc = "Set the brush destination mask"
)
@CommandPermissions({"worldedit.brush.options.mask", "worldedit.mask.brush"})
public void mask(Player player, LocalSession session,
@Switch(name = 'h', desc = "Whether the offhand should be considered or not")
boolean offHand,
@Arg(desc = "The destination mask", def = "")
Mask maskOpt, Arguments arguments) throws WorldEditException {
public void mask(
Player player, LocalSession session,
@Switch(name = 'h', desc = "Whether the offhand should be considered or not")
boolean offHand,
@Arg(desc = "The destination mask", def = "")
Mask maskOpt, Arguments arguments
) throws WorldEditException {
BrushTool tool = session.getBrushTool(player, false);
if (tool == null) {
player.print(Caption.of("fawe.worldedit.brush.brush.none"));
@ -84,7 +87,7 @@ public class ToolUtilCommands {
} else {
BrushSettings settings = offHand ? tool.getOffHand() : tool.getContext();
String lastArg = Iterables.getLast(CommandArgParser.spaceSplit(arguments.get()))
.getSubstring();
.getSubstring();
settings.addSetting(BrushSettings.SettingType.MASK, lastArg);
settings.setMask(maskOpt);
tool.update();
@ -94,17 +97,19 @@ public class ToolUtilCommands {
//FAWE end
@Command(
name = "material",
aliases = {"mat", "/material", "pattern"},
desc = "Set the brush material"
name = "material",
aliases = {"mat", "/material", "pattern"},
desc = "Set the brush material"
)
@CommandPermissions("worldedit.brush.options.material")
public void material(Player player, LocalSession session,
@Arg(desc = "The pattern of blocks to use")
Pattern pattern,
//FAWE start - add offhand
@Switch(name = 'h', desc = "Whether the offhand should be considered or not")
boolean offHand, Arguments arguments) throws WorldEditException {
public void material(
Player player, LocalSession session,
@Arg(desc = "The pattern of blocks to use")
Pattern pattern,
//FAWE start - add offhand
@Switch(name = 'h', desc = "Whether the offhand should be considered or not")
boolean offHand, Arguments arguments
) throws WorldEditException {
BrushTool tool = session.getBrushTool(player, false);
if (tool == null) {
player.print(Caption.of("fawe.worldedit.brush.brush.none"));
@ -124,26 +129,30 @@ public class ToolUtilCommands {
}
@Command(
name = "range",
aliases = "/range",
desc = "Set the brush range"
)
name = "range",
aliases = "/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 {
public void range(
Player player, LocalSession session,
@Arg(desc = "The range of the brush")
int range
) throws WorldEditException {
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setRange(range);
player.print(Caption.of("worldedit.tool.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")
int size) throws WorldEditException {
public void size(
Player player, LocalSession session,
@Arg(desc = "The size of the brush")
int size
) throws WorldEditException {
we.checkMaxBrushRadius(size);
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setSize(size);
@ -151,14 +160,16 @@ public class ToolUtilCommands {
}
@Command(
name = "tracemask",
aliases = {"tarmask", "tm", "targetmask"},
desc = "Set the mask used to stop tool traces"
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 {
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(Caption.of("worldedit.tool.tracemask.disabled"));
@ -168,17 +179,21 @@ public class ToolUtilCommands {
}
@Command(
name = "/superpickaxe",
aliases = {",", "/sp", "/pickaxe", "/"},
desc = "Toggle the super pickaxe function"
name = "/superpickaxe",
aliases = {",", "/sp", "/pickaxe", "/"},
desc = "Toggle the super pickaxe function"
)
@CommandPermissions("worldedit.superpickaxe")
public void togglePickaxe(Player player, LocalSession session,
@Arg(desc = "The new super pickaxe state", def = "")
Boolean superPickaxe) {
public void togglePickaxe(
Player player, LocalSession session,
@Arg(desc = "The new super pickaxe state", def = "")
Boolean superPickaxe
) {
boolean hasSuperPickAxe = session.hasSuperPickAxe();
if (superPickaxe != null && superPickaxe == hasSuperPickAxe) {
player.print(Caption.of(superPickaxe ? "worldedit.tool.superpickaxe.enabled.already" : "worldedit.tool.superpickaxe.disabled.already"));
player.print(Caption.of(superPickaxe
? "worldedit.tool.superpickaxe.enabled.already"
: "worldedit.tool.superpickaxe.disabled.already"));
return;
}
if (hasSuperPickAxe) {
@ -192,14 +207,16 @@ public class ToolUtilCommands {
//FAWE start
@Command(
name = "primary",
aliases = { "/primary" },
desc = "Set the right click brush",
descFooter = "Set the right click brush"
name = "primary",
aliases = {"/primary"},
desc = "Set the right click brush",
descFooter = "Set the right click brush"
)
@CommandPermissions("worldedit.brush.primary")
public void primary(Player player, LocalSession session,
@Arg(desc = "The brush command", variable = true) List<String> commandStr) throws WorldEditException {
public void primary(
Player player, LocalSession session,
@Arg(desc = "The brush command", variable = true) List<String> commandStr
) throws WorldEditException {
BaseItem item = player.getItemInHand(HandSide.MAIN_HAND);
BrushTool tool = session.getBrushTool(player, false);
session.setTool(item, null, player);
@ -213,15 +230,17 @@ public class ToolUtilCommands {
}
@Command(
name = "secondary",
aliases = { "/secondary" },
desc = "Set the left click brush",
descFooter = "Set the left click brush"
name = "secondary",
aliases = {"/secondary"},
desc = "Set the left click brush",
descFooter = "Set the left click brush"
)
@CommandPermissions("worldedit.brush.secondary")
public void secondary(Player player, LocalSession session,
@Arg(desc = "The brush command", variable = true)
List<String> commandStr) throws WorldEditException {
public void secondary(
Player player, LocalSession session,
@Arg(desc = "The brush command", variable = true)
List<String> commandStr
) throws WorldEditException {
BaseItem item = player.getItemInHand(HandSide.MAIN_HAND);
BrushTool tool = session.getBrushTool(player, false);
session.setTool(item, null, player);
@ -235,14 +254,16 @@ public class ToolUtilCommands {
}
@Command(
name = "target",
aliases = {"tar", "/target", "/tar"},
desc = "Toggle between different target modes"
name = "target",
aliases = {"tar", "/target", "/tar"},
desc = "Toggle between different target modes"
)
@CommandPermissions("worldedit.brush.target")
public void target(Player player, LocalSession session,
@Arg(name = "mode", desc = "int", def = "0")
int mode) throws WorldEditException {
public void target(
Player player, LocalSession session,
@Arg(name = "mode", desc = "int", def = "0")
int mode
) throws WorldEditException {
BrushTool tool = session.getBrushTool(player, false);
if (tool == null) {
player.print(Caption.of("fawe.worldedit.brush.brush.none"));
@ -255,13 +276,15 @@ public class ToolUtilCommands {
}
@Command(
name = "targetoffset",
aliases = {"to"},
desc = "Set the targeting mask"
name = "targetoffset",
aliases = {"to"},
desc = "Set the targeting mask"
)
@CommandPermissions("worldedit.brush.targetoffset")
public void targetOffset(Player player, EditSession editSession, LocalSession session,
@Arg(name = "offset", desc = "offset", def = "0") int offset) throws WorldEditException {
public void targetOffset(
Player player, EditSession editSession, LocalSession session,
@Arg(name = "offset", desc = "offset", def = "0") int offset
) throws WorldEditException {
BrushTool tool = session.getBrushTool(player, false);
if (tool == null) {
player.print(Caption.of("fawe.worldedit.brush.brush.none"));
@ -272,17 +295,19 @@ public class ToolUtilCommands {
}
@Command(
name = "scroll",
desc = "Toggle between different target modes"
name = "scroll",
desc = "Toggle between different target modes"
)
@CommandPermissions("worldedit.brush.scroll")
public void scroll(Player player, EditSession editSession, LocalSession session,
@Switch(name = 'h', desc = "Whether the offhand should be considered or not")
boolean offHand,
@Arg(desc = "Target Modes", def = "none")
Scroll.Action mode,
@Arg(desc = "The scroll action", variable = true)
List<String> commandStr) throws WorldEditException {
public void scroll(
Player player, EditSession editSession, LocalSession session,
@Switch(name = 'h', desc = "Whether the offhand should be considered or not")
boolean offHand,
@Arg(desc = "Target Modes", def = "none")
Scroll.Action mode,
@Arg(desc = "The scroll action", variable = true)
List<String> commandStr
) throws WorldEditException {
BrushTool bt = session.getBrushTool(player, false);
if (bt == null) {
player.print(Caption.of("fawe.worldedit.brush.brush.none"));
@ -302,21 +327,21 @@ public class ToolUtilCommands {
bt.update();
}
@Command(
name = "smask",
aliases = {"/smask", "/sourcemask", "sourcemask"},
desc = "Set the brush source mask",
descFooter = "Set the brush source mask"
name = "smask",
aliases = {"/smask", "/sourcemask", "sourcemask"},
desc = "Set the brush source mask",
descFooter = "Set the brush source mask"
)
@CommandPermissions({"worldedit.brush.options.mask", "worldedit.mask.brush"})
public void smask(Player player, LocalSession session, EditSession editSession,
@Arg(desc = "The destination mask", def = "")
Mask maskArg,
@Switch(name = 'h', desc = "Whether the offhand should be considered or not")
boolean offHand,
Arguments arguments) throws WorldEditException {
public void smask(
Player player, LocalSession session, EditSession editSession,
@Arg(desc = "The destination mask", def = "")
Mask maskArg,
@Switch(name = 'h', desc = "Whether the offhand should be considered or not")
boolean offHand,
Arguments arguments
) throws WorldEditException {
BrushTool tool = session.getBrushTool(player, false);
if (tool == null) {
player.print(Caption.of("fawe.worldedit.brush.brush.none"));

View File

@ -22,11 +22,11 @@ package com.sk89q.worldedit.command;
import com.fastasyncworldedit.core.Fawe;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.util.task.DelegateConsumer;
import com.fastasyncworldedit.core.function.QuadFunction;
import com.fastasyncworldedit.core.util.MainUtil;
import com.fastasyncworldedit.core.util.TaskManager;
import com.fastasyncworldedit.core.util.image.ImageUtil;
import com.fastasyncworldedit.core.util.task.DelegateConsumer;
import com.google.common.base.Function;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
@ -79,6 +79,7 @@ import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch;
import org.enginehub.piston.exception.StopExecutionException;
import javax.imageio.ImageIO;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
@ -98,7 +99,6 @@ import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.imageio.ImageIO;
import static com.sk89q.worldedit.command.util.Logging.LogMode.PLACEMENT;
@ -115,8 +115,8 @@ public class UtilityCommands {
}
@Command(
name = "/macro",
desc = "Generate or run a macro"
name = "/macro",
desc = "Generate or run a macro"
)
@CommandPermissions("worldedit.macro")
public void macro(Player player, LocalSession session, String name, String argument) throws IOException {
@ -124,12 +124,16 @@ public class UtilityCommands {
}
@Command(
name = "/heightmapinterface",
aliases = { "/hmi", "hmi" },
desc = "Generate the heightmap interface: https://github.com/IntellectualSites/HeightMap"
name = "/heightmapinterface",
aliases = {"/hmi", "hmi"},
desc = "Generate the heightmap interface: https://github.com/IntellectualSites/HeightMap"
)
@CommandPermissions("fawe.admin")
public void heightmapInterface(Player player, @Arg(name = "min", desc = "int", def = "100") int min, @Arg(name = "max", desc = "int", def = "200") int max) throws IOException {
public void heightmapInterface(
Player player,
@Arg(name = "min", desc = "int", def = "100") int min,
@Arg(name = "max", desc = "int", def = "200") int max
) throws IOException {
player.print(TextComponent.of("Please wait while we generate the minified heightmaps."));
File srcFolder = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.HEIGHTMAP);
@ -152,8 +156,20 @@ public class UtilityCommands {
name = name.replaceFirst(java.util.regex.Pattern.quote(File.separator), "");
}
BufferedImage img = MainUtil.readImage(file);
BufferedImage minImg = ImageUtil.getScaledInstance(img, min, min, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
BufferedImage maxImg = max == -1 ? img : ImageUtil.getScaledInstance(img, max, max, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
BufferedImage minImg = ImageUtil.getScaledInstance(
img,
min,
min,
RenderingHints.VALUE_INTERPOLATION_BILINEAR,
true
);
BufferedImage maxImg = max == -1 ? img : ImageUtil.getScaledInstance(
img,
max,
max,
RenderingHints.VALUE_INTERPOLATION_BILINEAR,
true
);
player.print(TextComponent.of(String.format("Writing %s", name)));
File minFile = new File(minImages, name);
File maxFile = new File(maxImages, name);
@ -185,9 +201,9 @@ public class UtilityCommands {
}
@Command(
name = "/cancel",
aliases = {"fcancel"},
desc = "Cancel your current command"
name = "/cancel",
aliases = {"fcancel"},
desc = "Cancel your current command"
)
@CommandPermissions(value = "fawe.cancel", queued = false)
public void cancel(Player player) {
@ -196,23 +212,25 @@ public class UtilityCommands {
}
@Command(
name = "/fill",
desc = "Fill a hole"
name = "/fill",
desc = "Fill a hole"
)
@CommandPermissions("worldedit.fill")
@Logging(PLACEMENT)
public int fill(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The blocks to fill with")
Pattern pattern,
//FAWE start - we take an expression over a double
@Arg(desc = "The radius to fill in")
Expression radiusExp,
//FAWE end
@Arg(desc = "The depth to fill", def = "1")
int depth,
@Arg(desc = "The direction to move", def = "down")
@Direction BlockVector3 direction) throws WorldEditException, EvaluationException {
public int fill(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The blocks to fill with")
Pattern pattern,
//FAWE start - we take an expression over a double
@Arg(desc = "The radius to fill in")
Expression radiusExp,
//FAWE end
@Arg(desc = "The depth to fill", def = "1")
int depth,
@Arg(desc = "The direction to move", def = "down")
@Direction BlockVector3 direction
) throws WorldEditException, EvaluationException {
//FAWE start
double radius = radiusExp.evaluate();
//FAWE end
@ -284,20 +302,22 @@ public class UtilityCommands {
*/
@Command(
name = "/fillr",
desc = "Fill a hole recursively"
name = "/fillr",
desc = "Fill a hole recursively"
)
@CommandPermissions("worldedit.fill.recursive")
@Logging(PLACEMENT)
public int fillr(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The blocks to fill with")
Pattern pattern,
//FAWE start - we take an expression over a double
@Arg(desc = "The radius to fill in")
Expression radiusExp,
//FAWE end
@Arg(desc = "The depth to fill", def = "")
Integer depth) throws WorldEditException {
public int fillr(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The blocks to fill with")
Pattern pattern,
//FAWE start - we take an expression over a double
@Arg(desc = "The radius to fill in")
Expression radiusExp,
//FAWE end
@Arg(desc = "The depth to fill", def = "")
Integer depth
) throws WorldEditException {
//FAWE start
double radius = radiusExp.evaluate();
//FAWE end
@ -313,22 +333,24 @@ public class UtilityCommands {
}
@Command(
name = "/drain",
desc = "Drain a pool"
name = "/drain",
desc = "Drain a pool"
)
@CommandPermissions("worldedit.drain")
@Logging(PLACEMENT)
public int drain(Actor actor, LocalSession session, EditSession editSession,
//FAWE start - we take an expression over a double
@Arg(desc = "The radius to drain")
Expression radiusExp,
//FAWE end
@Switch(name = 'w', desc = "Also un-waterlog blocks")
boolean waterlogged,
//FAWE start
@Switch(name = 'p', desc = "Also remove water plants")
boolean plants) throws WorldEditException {
//FAWE end
public int drain(
Actor actor, LocalSession session, EditSession editSession,
//FAWE start - we take an expression over a double
@Arg(desc = "The radius to drain")
Expression radiusExp,
//FAWE end
@Switch(name = 'w', desc = "Also un-waterlog blocks")
boolean waterlogged,
//FAWE start
@Switch(name = 'p', desc = "Also remove water plants")
boolean plants
) throws WorldEditException {
//FAWE end
double radius = radiusExp.evaluate();
radius = Math.max(0, radius);
we.checkMaxRadius(radius);
@ -338,15 +360,17 @@ public class UtilityCommands {
}
@Command(
name = "fixlava",
aliases = { "/fixlava" },
desc = "Fix lava to be stationary"
name = "fixlava",
aliases = {"/fixlava"},
desc = "Fix lava to be stationary"
)
@CommandPermissions("worldedit.fixlava")
@Logging(PLACEMENT)
public int fixLava(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius to fix in")
double radius) throws WorldEditException {
public int fixLava(
Actor actor, LocalSession session, EditSession editSession,
@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);
@ -355,15 +379,17 @@ public class UtilityCommands {
}
@Command(
name = "fixwater",
aliases = { "/fixwater" },
desc = "Fix water to be stationary"
name = "fixwater",
aliases = {"/fixwater"},
desc = "Fix water to be stationary"
)
@CommandPermissions("worldedit.fixwater")
@Logging(PLACEMENT)
public int fixWater(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius to fix in")
double radius) throws WorldEditException {
public int fixWater(
Actor actor, LocalSession session, EditSession editSession,
@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);
@ -372,17 +398,19 @@ public class UtilityCommands {
}
@Command(
name = "removeabove",
aliases = { "/removeabove" },
desc = "Remove blocks above your head."
name = "removeabove",
aliases = {"/removeabove"},
desc = "Remove blocks above your head."
)
@CommandPermissions("worldedit.removeabove")
@Logging(PLACEMENT)
public int removeAbove(Actor actor, World world, LocalSession session, EditSession editSession,
@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 {
public int removeAbove(
Actor actor, World world, LocalSession session, EditSession editSession,
@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);
@ -393,17 +421,19 @@ public class UtilityCommands {
}
@Command(
name = "removebelow",
aliases = { "/removebelow" },
desc = "Remove blocks below you."
name = "removebelow",
aliases = {"/removebelow"},
desc = "Remove blocks below you."
)
@CommandPermissions("worldedit.removebelow")
@Logging(PLACEMENT)
public int removeBelow(Actor actor, World world, LocalSession session, EditSession editSession,
@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 {
public int removeBelow(
Actor actor, World world, LocalSession session, EditSession editSession,
@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 {
size = Math.max(1, size);
we.checkMaxRadius(size);
height = height != null ? Math.min((world.getMaxY() + 1), height + 1) : (world.getMaxY() + 1);
@ -414,17 +444,19 @@ public class UtilityCommands {
}
@Command(
name = "removenear",
aliases = { "/removenear" },
desc = "Remove blocks near you."
name = "removenear",
aliases = {"/removenear"},
desc = "Remove blocks near you."
)
@CommandPermissions("worldedit.removenear")
@Logging(PLACEMENT)
public int removeNear(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The mask of blocks to remove")
Mask mask,
@Arg(desc = "The radius of the square to remove from", def = "50")
int radius) throws WorldEditException {
public int removeNear(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The mask of blocks to remove")
Mask mask,
@Arg(desc = "The radius of the square to remove from", def = "50")
int radius
) throws WorldEditException {
//FAWE start > the mask will have been initialised with a WorldWrapper extent (very bad/slow)
if (mask instanceof AbstractExtentMask) {
((AbstractExtentMask) mask).setExtent(editSession);
@ -439,19 +471,21 @@ public class UtilityCommands {
}
@Command(
name = "replacenear",
aliases = { "/replacenear" },
desc = "Replace nearby blocks"
name = "replacenear",
aliases = {"/replacenear"},
desc = "Replace nearby blocks"
)
@CommandPermissions("worldedit.replacenear")
@Logging(PLACEMENT)
public int replaceNear(Actor actor, World world, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the square to remove in")
int radius,
@Arg(desc = "The mask matching blocks to remove", def = "")
Mask from,
@Arg(desc = "The pattern of blocks to replace with")
Pattern to) throws WorldEditException {
public int replaceNear(
Actor actor, World world, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the square to remove in")
int radius,
@Arg(desc = "The mask matching blocks to remove", def = "")
Mask from,
@Arg(desc = "The pattern of blocks to replace with")
Pattern to
) throws WorldEditException {
//FAWE start > the mask will have been initialised with a WorldWrapper extent (very bad/slow)
if (from instanceof AbstractExtentMask) {
((AbstractExtentMask) from).setExtent(editSession);
@ -476,106 +510,119 @@ public class UtilityCommands {
@Command(
name = "snow",
aliases = { "/snow" },
desc = "Simulates snow"
name = "snow",
aliases = {"/snow"},
desc = "Simulates snow"
)
@CommandPermissions("worldedit.snow")
@Logging(PLACEMENT)
public int snow(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the cylinder to snow in", def = "10")
double size,
@Arg(
desc = "The height of the cylinder to snow in",
def = HeightConverter.DEFAULT_VALUE
)
@VertHeight
int height,
@Switch(name = 's', desc = "Stack snow layers")
boolean stack) throws WorldEditException {
public int snow(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the cylinder to snow in", def = "10")
double size,
@Arg(
desc = "The height of the cylinder to snow in",
def = HeightConverter.DEFAULT_VALUE
)
@VertHeight
int height,
@Switch(name = 's', desc = "Stack snow layers")
boolean stack
) throws WorldEditException {
size = Math.max(1, size);
height = Math.max(1, height);
we.checkMaxRadius(size);
BlockVector3 position = session.getPlacementPosition(actor);
CylinderRegion region = new CylinderRegion(position, Vector2.at(size, size), position.getBlockY() - height, position.getBlockY() + height);
CylinderRegion region = new CylinderRegion(
position,
Vector2.at(size, size),
position.getBlockY() - height,
position.getBlockY() + height
);
int affected = editSession.simulateSnow(region, stack);
actor.print(Caption.of(
"worldedit.snow.created", TextComponent.of(affected)
"worldedit.snow.created", TextComponent.of(affected)
));
return affected;
}
@Command(
name = "thaw",
aliases = { "/thaw" },
desc = "Thaws the area"
name = "thaw",
aliases = {"/thaw"},
desc = "Thaws the area"
)
@CommandPermissions("worldedit.thaw")
@Logging(PLACEMENT)
public int thaw(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the cylinder to thaw in", def = "10")
double size,
@Arg(
desc = "The height of the cylinder to thaw in",
def = HeightConverter.DEFAULT_VALUE
)
@VertHeight
int height) throws WorldEditException {
public int thaw(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the cylinder to thaw in", def = "10")
double size,
@Arg(
desc = "The height of the cylinder to thaw in",
def = HeightConverter.DEFAULT_VALUE
)
@VertHeight
int height
) throws WorldEditException {
size = Math.max(1, size);
height = Math.max(1, height);
we.checkMaxRadius(size);
int affected = editSession.thaw(session.getPlacementPosition(actor), size, height);
actor.print(Caption.of(
"worldedit.thaw.removed", TextComponent.of(affected)
"worldedit.thaw.removed", TextComponent.of(affected)
));
return affected;
}
@Command(
name = "green",
aliases = { "/green" },
desc = "Converts dirt to grass blocks in the area"
name = "green",
aliases = {"/green"},
desc = "Converts dirt to grass blocks in the area"
)
@CommandPermissions("worldedit.green")
@Logging(PLACEMENT)
public int green(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the cylinder to convert in", def = "10")
double size,
@Arg(
desc = "The height of the cylinder to convert in",
def = HeightConverter.DEFAULT_VALUE
)
@VertHeight
int height,
@Switch(name = 'f', desc = "Also convert coarse dirt")
boolean convertCoarse) throws WorldEditException {
public int green(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the cylinder to convert in", def = "10")
double size,
@Arg(
desc = "The height of the cylinder to convert in",
def = HeightConverter.DEFAULT_VALUE
)
@VertHeight
int height,
@Switch(name = 'f', desc = "Also convert coarse dirt")
boolean convertCoarse
) throws WorldEditException {
size = Math.max(1, size);
height = Math.max(1, height);
we.checkMaxRadius(size);
final boolean onlyNormalDirt = !convertCoarse;
final int affected = editSession.green(
session.getPlacementPosition(actor), size, height, onlyNormalDirt
session.getPlacementPosition(actor), size, height, onlyNormalDirt
);
actor.print(Caption.of(
"worldedit.green.changed", TextComponent.of(affected)
"worldedit.green.changed", TextComponent.of(affected)
));
return affected;
}
@Command(
name = "extinguish",
aliases = { "/ex", "/ext", "/extinguish", "ex", "ext" },
desc = "Extinguish nearby fire"
name = "extinguish",
aliases = {"/ex", "/ext", "/extinguish", "ex", "ext"},
desc = "Extinguish nearby fire"
)
@CommandPermissions("worldedit.extinguish")
@Logging(PLACEMENT)
public int extinguish(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the square to remove in", def = "")
Integer radius) throws WorldEditException {
public int extinguish(
Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the square to remove in", def = "")
Integer radius
) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
@ -590,33 +637,35 @@ public class UtilityCommands {
}
@Command(
name = "butcher",
aliases = { "/butcher" },
desc = "Kill all or nearby mobs"
name = "butcher",
aliases = {"/butcher"},
desc = "Kill all or nearby mobs"
)
@CommandPermissions("worldedit.butcher")
@Logging(PLACEMENT)
public int butcher(Actor actor,
@Arg(desc = "Radius to kill mobs in", def = "")
Integer radius,
@Switch(name = 'p', desc = "Also kill pets")
boolean killPets,
@Switch(name = 'n', desc = "Also kill NPCs")
boolean killNpcs,
@Switch(name = 'g', desc = "Also kill golems")
boolean killGolems,
@Switch(name = 'a', desc = "Also kill animals")
boolean killAnimals,
@Switch(name = 'b', desc = "Also kill ambient mobs")
boolean killAmbient,
@Switch(name = 't', desc = "Also kill mobs with name tags")
boolean killWithName,
@Switch(name = 'f', desc = "Also kill all friendly mobs (Applies the flags `-abgnpt`)")
boolean killFriendly,
@Switch(name = 'r', desc = "Also destroy armor stands")
boolean killArmorStands,
@Switch(name = 'w', desc = "Also kill water mobs")
boolean killWater) throws WorldEditException {
public int butcher(
Actor actor,
@Arg(desc = "Radius to kill mobs in", def = "")
Integer radius,
@Switch(name = 'p', desc = "Also kill pets")
boolean killPets,
@Switch(name = 'n', desc = "Also kill NPCs")
boolean killNpcs,
@Switch(name = 'g', desc = "Also kill golems")
boolean killGolems,
@Switch(name = 'a', desc = "Also kill animals")
boolean killAnimals,
@Switch(name = 'b', desc = "Also kill ambient mobs")
boolean killAmbient,
@Switch(name = 't', desc = "Also kill mobs with name tags")
boolean killWithName,
@Switch(name = 'f', desc = "Also kill all friendly mobs (Applies the flags `-abgnpt`)")
boolean killFriendly,
@Switch(name = 'r', desc = "Also destroy armor stands")
boolean killArmorStands,
@Switch(name = 'w', desc = "Also kill water mobs")
boolean killWater
) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
if (radius == null) {
@ -634,7 +683,10 @@ public class UtilityCommands {
}
CreatureButcher flags = new CreatureButcher(actor);
flags.or(CreatureButcher.Flags.FRIENDLY, killFriendly); // No permission check here. Flags will instead be filtered by the subsequent calls.
flags.or(
CreatureButcher.Flags.FRIENDLY,
killFriendly
); // No permission check here. Flags will instead be filtered by the subsequent calls.
flags.or(CreatureButcher.Flags.PETS, killPets, "worldedit.butcher.pets");
flags.or(CreatureButcher.Flags.NPCS, killNpcs, "worldedit.butcher.npcs");
flags.or(CreatureButcher.Flags.GOLEMS, killGolems, "worldedit.butcher.golems");
@ -659,24 +711,26 @@ public class UtilityCommands {
}
@Command(
name = "remove",
aliases = { "rem", "rement", "/remove", "/rem", "/rement" },
desc = "Remove all entities of a type"
name = "remove",
aliases = {"rem", "rement", "/remove", "/rem", "/rement"},
desc = "Remove all entities of a type"
)
@CommandPermissions("worldedit.remove")
@Logging(PLACEMENT)
public int remove(Actor actor,
@Arg(desc = "The type of entity to remove")
EntityRemover remover,
@Arg(desc = "The radius of the cuboid to remove from")
int radius) throws WorldEditException {
public int remove(
Actor actor,
@Arg(desc = "The type of entity to remove")
EntityRemover remover,
@Arg(desc = "The radius of the cuboid to remove from")
int radius
) throws WorldEditException {
if (radius < -1) {
actor.print(Caption.of("worldedit.remove.explain-all"));
return 0;
}
//FAWE start - run this sync
int removed = TaskManager.IMP.sync(() -> killMatchingEntities(radius, actor, remover::createFunction));
int removed = TaskManager.IMP.sync(() -> killMatchingEntities(radius, actor, remover::createFunction));
//FAWE end
actor.print(Caption.of("worldedit.remove.removed", TextComponent.of(removed)));
return removed;
@ -716,14 +770,16 @@ public class UtilityCommands {
}
@Command(
name = "/calculate",
aliases = { "/calc", "/eval", "/evaluate", "/solve" },
desc = "Evaluate a mathematical expression"
name = "/calculate",
aliases = {"/calc", "/eval", "/evaluate", "/solve"},
desc = "Evaluate a mathematical expression"
)
@CommandPermissions("worldedit.calc")
public void calc(Actor actor,
@Arg(desc = "Expression to evaluate", variable = true)
List<String> input) {
public void calc(
Actor actor,
@Arg(desc = "Expression to evaluate", variable = true)
List<String> input
) {
Expression expression;
try {
expression = Expression.compile(String.join(" ", input));
@ -744,26 +800,29 @@ public class UtilityCommands {
}
@Command(
name = "/help",
desc = "Displays help for WorldEdit commands"
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 {
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");
we.getPlatformManager().getPlatformCommandManager().getCommandManager(), actor, "//help"
);
}
//FAWE start
@Command(
name = "/confirm",
desc = "Confirm a command"
name = "/confirm",
desc = "Confirm a command"
)
@CommandPermissions(value = "fawe.confirm", queued = false)
public void confirm(Player player) throws WorldEditException {
@ -774,21 +833,26 @@ public class UtilityCommands {
public static List<Map.Entry<URI, String>> filesToEntry(final File root, final List<File> files, final UUID uuid) {
return files.stream()
.map(input -> { // Keep this functional, as transform is evaluated lazily
URI uri = input.toURI();
String path = getPath(root, input, uuid);
return new SimpleEntry<>(uri, path);
}).collect(Collectors.toList());
.map(input -> { // Keep this functional, as transform is evaluated lazily
URI uri = input.toURI();
String path = getPath(root, input, uuid);
return new SimpleEntry<>(uri, path);
}).collect(Collectors.toList());
}
public static enum URIType {
public enum URIType {
URL,
FILE,
DIRECTORY,
OTHER
}
public static List<Component> entryToComponent(File root, List<Map.Entry<URI, String>> entries, Function<URI, Boolean> isLoaded, QuadFunction<String, String, URIType, Boolean, Component> adapter) {
public static List<Component> entryToComponent(
File root,
List<Map.Entry<URI, String>> entries,
Function<URI, Boolean> isLoaded,
QuadFunction<String, String, URIType, Boolean, Component> adapter
) {
return entries.stream().map(input -> {
URI uri = input.getKey();
String path = input.getValue();
@ -813,7 +877,7 @@ public class UtilityCommands {
try {
if (!MainUtil.isInSubDirectory(root, file)) {
throw new RuntimeException(
new StopExecutionException(TextComponent.of("Invalid path")));
new StopExecutionException(TextComponent.of("Invalid path")));
}
} catch (IOException ignored) {
}
@ -827,7 +891,15 @@ public class UtilityCommands {
}).collect(Collectors.toList());
}
public static List<File> getFiles(File dir, Actor actor, List<String> args, String formatName, boolean playerFolder, boolean oldFirst, boolean newFirst) {
public static List<File> getFiles(
File dir,
Actor actor,
List<String> args,
String formatName,
boolean playerFolder,
boolean oldFirst,
boolean newFirst
) {
List<File> fileList = new LinkedList<>();
getFiles(dir, actor, args, formatName, playerFolder, fileList::add);
@ -864,7 +936,14 @@ public class UtilityCommands {
return fileList;
}
public static void getFiles(File dir, Actor actor, List<String> args, String formatName, boolean playerFolder, Consumer<File> forEachFile) {
public static void getFiles(
File dir,
Actor actor,
List<String> args,
String formatName,
boolean playerFolder,
Consumer<File> forEachFile
) {
Consumer<File> rootFunction = forEachFile;
//schem list all <path>
@ -897,9 +976,9 @@ public class UtilityCommands {
arg = arg.replace("/", File.separator);
String newDirFilter = dirFilter + arg;
boolean exists =
new File(dir, newDirFilter).exists() || playerFolder && MainUtil
.resolveRelative(
new File(dir, actor.getUniqueId() + newDirFilter)).exists();
new File(dir, newDirFilter).exists() || playerFolder && MainUtil
.resolveRelative(
new File(dir, actor.getUniqueId() + newDirFilter)).exists();
if (!exists) {
arg = arg.substring(0, arg.length() - File.separator.length());
if (arg.length() > 3 && arg.length() <= 16) {

View File

@ -62,6 +62,7 @@ import java.util.Map;
@CommandContainer(superTypes = {CommandPermissionsConditionGenerator.Registration.class})
public class WorldEditCommands {
private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
private final WorldEdit we;
@ -71,9 +72,9 @@ public class WorldEditCommands {
}
@Command(
name = "version",
aliases = { "ver" },
desc = "Get the FAWE version"
name = "version",
aliases = {"ver"},
desc = "Get the FAWE version"
)
@CommandPermissions(queued = false)
public void version(Actor actor) {
@ -85,7 +86,7 @@ public class WorldEditCommands {
if (fVer != null) {
FaweVersion version = Fawe.get().getVersion();
Date date = new GregorianCalendar(2000 + version.year, version.month - 1, version.day)
.getTime();
.getTime();
TextComponent dateArg = TextComponent.of(date.toLocaleString());
TextComponent commitArg = TextComponent.of(Integer.toHexString(version.hash));
@ -106,7 +107,7 @@ public class WorldEditCommands {
TextComponent.of("* ", TextColor.GRAY)
.append(TextComponent.of(platform.getPlatformName())
.hoverEvent(HoverEvent.showText(TextComponent.of(platform.getId()))))
.append(TextComponent.of("(" + platform.getPlatformVersion() + ")"))
.append(TextComponent.of("(" + platform.getPlatformVersion() + ")"))
).newline();
}
actor.print(new MessageBox("Platforms", producer, TextColor.GRAY).create());
@ -115,9 +116,9 @@ public class WorldEditCommands {
for (Capability capability : Capability.values()) {
Platform platform = pm.queryCapability(capability);
producer.append(
TextComponent.of(capability.name(), TextColor.GRAY)
.append(TextComponent.of(": ")
.append(TextComponent.of(platform != null ? platform.getPlatformName() : "none")))
TextComponent.of(capability.name(), TextColor.GRAY)
.append(TextComponent.of(": ")
.append(TextComponent.of(platform != null ? platform.getPlatformName() : "none")))
).newline();
}
actor.print(new MessageBox("Capabilities", producer, TextColor.GRAY).create());
@ -125,13 +126,16 @@ public class WorldEditCommands {
}
@Command(
name = "reload",
desc = "Reload configuration and translations"
name = "reload",
desc = "Reload configuration and translations"
)
@CommandPermissions("worldedit.reload")
public void reload(Actor actor) {
we.getPlatformManager().queryCapability(Capability.CONFIGURATION).reload();
we.getEventBus().post(new ConfigurationLoadEvent(we.getPlatformManager().queryCapability(Capability.CONFIGURATION).getConfiguration()));
we.getEventBus().post(new ConfigurationLoadEvent(we
.getPlatformManager()
.queryCapability(Capability.CONFIGURATION)
.getConfiguration()));
//FAWE start
Fawe.get().setupConfigs();
//FAWE end
@ -140,8 +144,8 @@ public class WorldEditCommands {
//FAWE start
@Command(
name = "debugpaste",
desc = "Writes a report of latest.log, config.yml, config-legacy.yml, strings.json to https://athion.net/ISPaster/paste"
name = "debugpaste",
desc = "Writes a report of latest.log, config.yml, config-legacy.yml, strings.json to https://athion.net/ISPaster/paste"
)
@CommandPermissions(value = {"worldedit.report", "worldedit.debugpaste"}, queued = false)
public void report(Actor actor) throws WorldEditException {
@ -156,12 +160,12 @@ public class WorldEditCommands {
return;
}
actor.print(Caption.of("worldedit.report.written", TextComponent.of(dest).clickEvent(
ClickEvent.openUrl(dest))));
ClickEvent.openUrl(dest))));
}
@Command(
name = "threads",
desc = "Print all thread stacks"
name = "threads",
desc = "Print all thread stacks"
)
@CommandPermissions(value = "worldedit.threads", queued = false)
public void threads(Actor actor) throws WorldEditException {
@ -169,7 +173,7 @@ public class WorldEditCommands {
for (Map.Entry<Thread, StackTraceElement[]> entry : stacks.entrySet()) {
Thread thread = entry.getKey();
actor.printDebug(TextComponent.of(
"--------------------------------------------------------------------------------------------"));
"--------------------------------------------------------------------------------------------"));
actor.printDebug("Thread: " + thread.getName() + " | Id: " + thread.getId() + " | Alive: " + thread.isAlive());
for (StackTraceElement elem : entry.getValue()) {
actor.printDebug(TextComponent.of(elem.toString()));
@ -179,8 +183,8 @@ public class WorldEditCommands {
//FAWE end
@Command(
name = "cui",
desc = "Complete CUI handshake (internal usage)"
name = "cui",
desc = "Complete CUI handshake (internal usage)"
)
@CommandPermissions(value = "worldedit.cui", queued = false)
public void cui(Player player, LocalSession session) {
@ -189,39 +193,47 @@ public class WorldEditCommands {
}
@Command(
name = "tz",
desc = "Set your timezone for snapshots"
name = "tz",
desc = "Set your timezone for snapshots"
)
@CommandPermissions(value = "worldedit.timezone", queued = false)
public void tz(Actor actor, LocalSession session,
@Arg(desc = "The timezone to set")
String timezone) {
public void tz(
Actor actor, LocalSession session,
@Arg(desc = "The timezone to set")
String timezone
) {
try {
ZoneId tz = ZoneId.of(timezone);
session.setTimezone(tz);
actor.print(Caption.of("worldedit.timezone.set", TextComponent.of(tz.getDisplayName(
TextStyle.FULL, actor.getLocale()
))));
actor.print(Caption.of("worldedit.timezone.current",
TextComponent.of(dateFormat.withLocale(actor.getLocale()).format(ZonedDateTime.now(tz)))));
actor.print(Caption.of(
"worldedit.timezone.current",
TextComponent.of(dateFormat.withLocale(actor.getLocale()).format(ZonedDateTime.now(tz)))
));
} catch (ZoneRulesException e) {
actor.print(Caption.of("worldedit.timezone.invalid"));
}
}
@Command(
name = "help",
desc = "Displays help for WorldEdit commands"
name = "help",
desc = "Displays help for WorldEdit commands"
)
@CommandPermissions(value = "worldedit.help", queued = false)
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 {
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, "/worldedit help");
we.getPlatformManager().getPlatformCommandManager().getCommandManager(), actor, "/worldedit help"
);
}
}

View File

@ -38,8 +38,8 @@ import org.enginehub.piston.converter.SuccessfulConversion;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import java.util.List;
import javax.annotation.Nullable;
import java.util.List;
import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
@ -55,26 +55,28 @@ public abstract class AbstractDirectionConverter<D> implements ArgumentConverter
return new AutoAnnotation_AbstractDirectionConverter_multiDirection(includeDiagonals);
}
protected static <D> void register(CommandManager commandManager, AbstractDirectionConverter<D> converter,
Class<D> keyClass, boolean includeDiagonals) {
protected static <D> void register(
CommandManager commandManager, AbstractDirectionConverter<D> converter,
Class<D> keyClass, boolean includeDiagonals
) {
commandManager.registerConverter(
Key.of(keyClass, direction(includeDiagonals)),
converter
Key.of(keyClass, direction(includeDiagonals)),
converter
);
commandManager.registerConverter(
Key.of(keyClass, multiDirection(includeDiagonals)),
CommaSeparatedValuesConverter.wrap(converter)
Key.of(keyClass, multiDirection(includeDiagonals)),
CommaSeparatedValuesConverter.wrap(converter)
);
}
private static final ImmutableSet<String> ORTHOGONAL = ImmutableSet.of(
"north", "south", "east", "west", "up", "down"
"north", "south", "east", "west", "up", "down"
);
private static final ImmutableSet<String> RELATIVE = ImmutableSet.of(
"me", "forward", "back", "left", "right"
"me", "forward", "back", "left", "right"
);
private static final ImmutableSet<String> DIAGONAL = ImmutableSet.of(
"northeast", "northwest", "southeast", "southwest"
"northeast", "northwest", "southeast", "southwest"
);
private final WorldEdit worldEdit;
@ -85,15 +87,19 @@ public abstract class AbstractDirectionConverter<D> implements ArgumentConverter
this.worldEdit = worldEdit;
this.includeDiagonals = includeDiagonals;
suggestions = ImmutableList.<String>builder()
.addAll(ORTHOGONAL)
.addAll(RELATIVE)
.addAll(includeDiagonals ? DIAGONAL : ImmutableList.of())
.build();
.addAll(ORTHOGONAL)
.addAll(RELATIVE)
.addAll(includeDiagonals ? DIAGONAL : ImmutableList.of())
.build();
}
@Override
public ConversionResult<D> convert(String argument, InjectedValueAccess context) {
Player player = context.injectedValue(Key.of(Actor.class)).filter(Player.class::isInstance).map(Player.class::cast).orElse(null);
Player player = context
.injectedValue(Key.of(Actor.class))
.filter(Player.class::isInstance)
.map(Player.class::cast)
.orElse(null);
try {
return SuccessfulConversion.fromSingle(convertDirection(argument, player, includeDiagonals));
} catch (Exception e) {
@ -101,12 +107,13 @@ public abstract class AbstractDirectionConverter<D> implements ArgumentConverter
}
}
protected abstract D convertDirection(String argument, @Nullable Player player, boolean includeDiagonals) throws UnknownDirectionException;
protected abstract D convertDirection(String argument, @Nullable Player player, boolean includeDiagonals) throws
UnknownDirectionException;
@Override
public Component describeAcceptableArguments() {
return TextComponent.of("`me` to use facing direction, or any "
+ (includeDiagonals ? "direction" : "non-diagonal direction"));
+ (includeDiagonals ? "direction" : "non-diagonal direction"));
}
@Override
@ -117,4 +124,5 @@ public abstract class AbstractDirectionConverter<D> implements ArgumentConverter
protected WorldEdit getWorldEdit() {
return worldEdit;
}
}

View File

@ -27,15 +27,16 @@ import org.enginehub.piston.inject.Key;
public class BooleanConverter {
public static void register(CommandManager commandManager) {
commandManager.registerConverter(Key.of(Boolean.class),
MultiKeyConverter.builder(
ImmutableSetMultimap.<Boolean, String>builder()
.putAll(false, "off", "f", "false", "n", "no")
.putAll(true, "on", "t", "true", "y", "yes")
.build()
)
.errorMessage(arg -> "Not a boolean value: " + arg)
.build()
commandManager.registerConverter(
Key.of(Boolean.class),
MultiKeyConverter.builder(
ImmutableSetMultimap.<Boolean, String>builder()
.putAll(false, "off", "f", "false", "n", "no")
.putAll(true, "on", "t", "true", "y", "yes")
.build()
)
.errorMessage(arg -> "Not a boolean value: " + arg)
.build()
);
}

View File

@ -39,25 +39,29 @@ import java.util.List;
import java.util.function.Function;
public class Chunk3dVectorConverter<C, T> implements ArgumentConverter<T> {
public static void register(CommandManager commandManager) {
CommaSeparatedValuesConverter<Integer> intConverter = CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(TypeToken.of(int.class)));
commandManager.registerConverter(Key.of(BlockVector3.class, Chunk3d.class),
new Chunk3dVectorConverter<>(
intConverter,
Range.closed(2, 3),
cmps -> {
switch (cmps.size()) {
case 2:
return BlockVector3.at(cmps.get(0), 0, cmps.get(1));
case 3:
return BlockVector3.at(cmps.get(0), cmps.get(1), cmps.get(2));
default:
break;
}
throw new AssertionError("Expected 2 or 3 components");
},
"block vector with x,z or x,y,z"
));
CommaSeparatedValuesConverter<Integer> intConverter = CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(TypeToken.of(
int.class)));
commandManager.registerConverter(
Key.of(BlockVector3.class, Chunk3d.class),
new Chunk3dVectorConverter<>(
intConverter,
Range.closed(2, 3),
cmps -> {
switch (cmps.size()) {
case 2:
return BlockVector3.at(cmps.get(0), 0, cmps.get(1));
case 3:
return BlockVector3.at(cmps.get(0), cmps.get(1), cmps.get(2));
default:
break;
}
throw new AssertionError("Expected 2 or 3 components");
},
"block vector with x,z or x,y,z"
)
);
}
private final ArgumentConverter<C> componentConverter;
@ -65,10 +69,12 @@ public class Chunk3dVectorConverter<C, T> implements ArgumentConverter<T> {
private final Function<List<C>, T> vectorConstructor;
private final String acceptableArguments;
private Chunk3dVectorConverter(ArgumentConverter<C> componentConverter,
Range<Integer> componentCount,
Function<List<C>, T> vectorConstructor,
String acceptableArguments) {
private Chunk3dVectorConverter(
ArgumentConverter<C> componentConverter,
Range<Integer> componentCount,
Function<List<C>, T> vectorConstructor,
String acceptableArguments
) {
this.componentConverter = componentConverter;
this.componentCount = componentCount;
this.vectorConstructor = vectorConstructor;
@ -88,9 +94,10 @@ public class Chunk3dVectorConverter<C, T> implements ArgumentConverter<T> {
}
if (!componentCount.contains(components.get().size())) {
return FailedConversion.from(new IllegalArgumentException(
"Must have " + componentCount + " vector components"));
"Must have " + componentCount + " vector components"));
}
T vector = vectorConstructor.apply(ImmutableList.copyOf(components.get()));
return SuccessfulConversion.fromSingle(vector);
}
}

View File

@ -50,8 +50,10 @@ public class CommaSeparatedValuesConverter<T> implements ArgumentConverter<T> {
private final int maximum;
private CommaSeparatedValuesConverter(ArgumentConverter<T> delegate, int maximum) {
checkArgument(maximum == -1 || maximum > 1,
"Maximum must be bigger than 1, or exactly -1");
checkArgument(
maximum == -1 || maximum > 1,
"Maximum must be bigger than 1, or exactly -1"
);
this.delegate = delegate;
this.maximum = maximum;
}
@ -61,11 +63,11 @@ public class CommaSeparatedValuesConverter<T> implements ArgumentConverter<T> {
TextComponent.Builder result = TextComponent.builder("");
if (maximum > -1) {
result.append(TextComponent.of("up to "))
.append(TextComponent.of(maximum))
.append(space());
.append(TextComponent.of(maximum))
.append(space());
}
result.append(TextComponent.of("comma separated values of: "))
.append(delegate.describeAcceptableArguments());
.append(delegate.describeAcceptableArguments());
return result.build();
}

View File

@ -26,8 +26,8 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Direction;
import org.enginehub.piston.CommandManager;
import java.util.Optional;
import javax.annotation.Nullable;
import java.util.Optional;
public final class DirectionConverter extends AbstractDirectionConverter<Direction> {
@ -36,14 +36,15 @@ public final class DirectionConverter extends AbstractDirectionConverter<Directi
}
public static void register(WorldEdit worldEdit, CommandManager commandManager) {
for (boolean includeDiagonals : new boolean[] { false, true }) {
for (boolean includeDiagonals : new boolean[]{false, true}) {
DirectionConverter directionConverter = new DirectionConverter(worldEdit, includeDiagonals);
register(commandManager, directionConverter, Direction.class, includeDiagonals);
}
}
@Override
protected Direction convertDirection(String argument, @Nullable Player player, boolean includeDiagonals) throws UnknownDirectionException {
protected Direction convertDirection(String argument, @Nullable Player player, boolean includeDiagonals) throws
UnknownDirectionException {
final BlockVector3 vec = includeDiagonals
? getWorldEdit().getDiagonalDirection(player, argument)
: getWorldEdit().getDirection(player, argument);

View File

@ -34,16 +34,18 @@ public final class DirectionVectorConverter extends AbstractDirectionConverter<B
}
public static void register(WorldEdit worldEdit, CommandManager commandManager) {
for (boolean includeDiagonals : new boolean[] { false, true }) {
for (boolean includeDiagonals : new boolean[]{false, true}) {
DirectionVectorConverter directionConverter = new DirectionVectorConverter(worldEdit, includeDiagonals);
register(commandManager, directionConverter, BlockVector3.class, includeDiagonals);
}
}
@Override
protected BlockVector3 convertDirection(String argument, @Nullable Player player, boolean includeDiagonals) throws UnknownDirectionException {
protected BlockVector3 convertDirection(String argument, @Nullable Player player, boolean includeDiagonals) throws
UnknownDirectionException {
return includeDiagonals
? getWorldEdit().getDiagonalDirection(player, argument)
: getWorldEdit().getDirection(player, argument);
}
}

View File

@ -50,7 +50,7 @@ public class EntityRemoverConverter implements ArgumentConverter<EntityRemover>
@Override
public Component describeAcceptableArguments() {
return TextComponent.of(
"projectiles, items, paintings, itemframes, boats, minecarts, tnt, xp, or all"
"projectiles, items, paintings, itemframes, boats, minecarts, tnt, xp, or all"
);
}
@ -67,4 +67,5 @@ public class EntityRemoverConverter implements ArgumentConverter<EntityRemover>
return FailedConversion.from(e);
}
}
}

View File

@ -31,36 +31,55 @@ import org.enginehub.piston.converter.ArgumentConverter;
import org.enginehub.piston.converter.MultiKeyConverter;
import org.enginehub.piston.inject.Key;
import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Set;
import java.util.function.Function;
import javax.annotation.Nullable;
public final class EnumConverter {
public static void register(CommandManager commandManager) {
commandManager.registerConverter(Key.of(SelectorChoice.class),
basic(SelectorChoice.class));
commandManager.registerConverter(Key.of(TreeGenerator.TreeType.class),
full(TreeGenerator.TreeType.class,
t -> ImmutableSet.copyOf(t.lookupKeys),
null));
commandManager.registerConverter(Key.of(EditSession.ReorderMode.class),
full(EditSession.ReorderMode.class,
r -> ImmutableSet.of(r.getDisplayName()),
null));
commandManager.registerConverter(Key.of(SideEffect.State.class),
commandManager.registerConverter(
Key.of(SelectorChoice.class),
basic(SelectorChoice.class)
);
commandManager.registerConverter(
Key.of(TreeGenerator.TreeType.class),
full(
TreeGenerator.TreeType.class,
t -> ImmutableSet.copyOf(t.lookupKeys),
null
)
);
commandManager.registerConverter(
Key.of(EditSession.ReorderMode.class),
full(
EditSession.ReorderMode.class,
r -> ImmutableSet.of(r.getDisplayName()),
null
)
);
commandManager.registerConverter(
Key.of(SideEffect.State.class),
MultiKeyConverter.from(
EnumSet.of(SideEffect.State.OFF, SideEffect.State.ON),
r -> ImmutableSet.of(r.name().toLowerCase(Locale.US)),
null));
commandManager.registerConverter(Key.of(HookMode.class),
basic(HookMode.class));
commandManager.registerConverter(Key.of(Scroll.Action.class),
basic(Scroll.Action.class));
commandManager.registerConverter(Key.of(TracingExtent.Action.class),
basic(TracingExtent.Action.class));
EnumSet.of(SideEffect.State.OFF, SideEffect.State.ON),
r -> ImmutableSet.of(r.name().toLowerCase(Locale.US)),
null
)
);
commandManager.registerConverter(
Key.of(HookMode.class),
basic(HookMode.class)
);
commandManager.registerConverter(
Key.of(Scroll.Action.class),
basic(Scroll.Action.class)
);
commandManager.registerConverter(
Key.of(TracingExtent.Action.class),
basic(TracingExtent.Action.class)
);
}
private static <E extends Enum<E>> ArgumentConverter<E> basic(Class<E> enumClass) {
@ -71,13 +90,15 @@ public final class EnumConverter {
return full(enumClass, e -> ImmutableSet.of(e.name().toLowerCase(Locale.ROOT)), unknownValue);
}
private static <E extends Enum<E>> ArgumentConverter<E> full(Class<E> enumClass,
Function<E, Set<String>> lookupKeys,
@Nullable E unknownValue) {
private static <E extends Enum<E>> ArgumentConverter<E> full(
Class<E> enumClass,
Function<E, Set<String>> lookupKeys,
@Nullable E unknownValue
) {
return MultiKeyConverter.from(
EnumSet.allOf(enumClass),
lookupKeys,
unknownValue
EnumSet.allOf(enumClass),
lookupKeys,
unknownValue
);
}

View File

@ -33,4 +33,5 @@ public class ExpressionConverter implements ArgumentConverter<Expression> {
return FailedConversion.from(e);
}
}
}

View File

@ -47,49 +47,61 @@ import org.enginehub.piston.converter.SuccessfulConversion;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import javax.annotation.Nullable;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.annotation.Nullable;
public class FactoryConverter<T> implements ArgumentConverter<T> {
public static void register(WorldEdit worldEdit, CommandManager commandManager) {
commandManager.registerConverter(Key.of(Pattern.class),
new FactoryConverter<>(worldEdit, WorldEdit::getPatternFactory, "pattern", null));
commandManager.registerConverter(Key.of(Mask.class),
new FactoryConverter<>(worldEdit, WorldEdit::getMaskFactory, "mask", null));
commandManager.registerConverter(Key.of(BaseItem.class),
new FactoryConverter<>(worldEdit, WorldEdit::getItemFactory, "item", null));
commandManager.registerConverter(
Key.of(Pattern.class),
new FactoryConverter<>(worldEdit, WorldEdit::getPatternFactory, "pattern", null)
);
commandManager.registerConverter(
Key.of(Mask.class),
new FactoryConverter<>(worldEdit, WorldEdit::getMaskFactory, "mask", null)
);
commandManager.registerConverter(
Key.of(BaseItem.class),
new FactoryConverter<>(worldEdit, WorldEdit::getItemFactory, "item", null)
);
commandManager.registerConverter(Key.of(Mask.class, ClipboardMask.class),
new FactoryConverter<>(worldEdit, WorldEdit::getMaskFactory, "mask",
context -> {
try {
ClipboardHolder holder = context.getSession().getClipboard();
Transform transform = holder.getTransform();
Extent target;
if (transform.isIdentity()) {
target = holder.getClipboard();
} else {
target = new BlockTransformExtent(holder.getClipboard(), transform);
commandManager.registerConverter(
Key.of(Mask.class, ClipboardMask.class),
new FactoryConverter<>(worldEdit, WorldEdit::getMaskFactory, "mask",
context -> {
try {
ClipboardHolder holder = context.getSession().getClipboard();
Transform transform = holder.getTransform();
Extent target;
if (transform.isIdentity()) {
target = holder.getClipboard();
} else {
target = new BlockTransformExtent(holder.getClipboard(), transform);
}
context.setExtent(target);
} catch (EmptyClipboardException e) {
throw new IllegalStateException(e);
}
}
context.setExtent(target);
} catch (EmptyClipboardException e) {
throw new IllegalStateException(e);
}
}));
)
);
}
private final WorldEdit worldEdit;
private final Function<WorldEdit, AbstractFactory<T>> factoryExtractor;
private final String description;
@Nullable private final Consumer<ParserContext> contextTweaker;
@Nullable
private final Consumer<ParserContext> contextTweaker;
private FactoryConverter(WorldEdit worldEdit,
Function<WorldEdit, AbstractFactory<T>> factoryExtractor,
String description,
@Nullable Consumer<ParserContext> contextTweaker) {
private FactoryConverter(
WorldEdit worldEdit,
Function<WorldEdit, AbstractFactory<T>> factoryExtractor,
String description,
@Nullable Consumer<ParserContext> contextTweaker
) {
this.worldEdit = worldEdit;
this.factoryExtractor = factoryExtractor;
this.description = description;
@ -99,7 +111,7 @@ public class FactoryConverter<T> implements ArgumentConverter<T> {
@Override
public ConversionResult<T> convert(String argument, InjectedValueAccess context) {
Actor actor = context.injectedValue(Key.of(Actor.class))
.orElseThrow(() -> new IllegalStateException("No actor"));
.orElseThrow(() -> new IllegalStateException("No actor"));
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
ParserContext parserContext = new ParserContext();
@ -124,7 +136,7 @@ public class FactoryConverter<T> implements ArgumentConverter<T> {
try {
return SuccessfulConversion.fromSingle(
factoryExtractor.apply(worldEdit).parseFromInput(argument, parserContext)
factoryExtractor.apply(worldEdit).parseFromInput(argument, parserContext)
);
} catch (InputParseException e) {
return FailedConversion.from(e);
@ -140,4 +152,5 @@ public class FactoryConverter<T> implements ArgumentConverter<T> {
public Component describeAcceptableArguments() {
return TextComponent.of("any " + description);
}
}

View File

@ -46,11 +46,12 @@ public class HeightConverter implements ArgumentConverter<Integer> {
public static final String DEFAULT_VALUE = "default-vertical-height";
private static final ArgumentConverter<Integer> INT_CONVERTER =
ArgumentConverters.get(TypeToken.of(int.class));
ArgumentConverters.get(TypeToken.of(int.class));
public static void register(CommandManager commandManager) {
commandManager.registerConverter(Key.of(int.class, VertHeight.class),
new HeightConverter()
commandManager.registerConverter(
Key.of(int.class, VertHeight.class),
new HeightConverter()
);
}
@ -66,9 +67,10 @@ public class HeightConverter implements ArgumentConverter<Integer> {
public ConversionResult<Integer> convert(String argument, InjectedValueAccess context) {
if (DEFAULT_VALUE.equals(argument)) {
return SuccessfulConversion.fromSingle(
WorldEdit.getInstance().getConfiguration().defaultVerticalHeight
WorldEdit.getInstance().getConfiguration().defaultVerticalHeight
);
}
return INT_CONVERTER.convert(argument, context);
}
}

View File

@ -21,7 +21,7 @@ public class LocationConverter implements ArgumentConverter<Location> {
public static void register(CommandManager commandManager) {
commandManager.registerConverter(Key.of(Location.class), LOCATION_CONVERTER);
}
public static final LocationConverter LOCATION_CONVERTER = new LocationConverter();
private final WorldConverter worldConverter = WorldConverter.WORLD_CONVERTER;
@ -66,4 +66,5 @@ public class LocationConverter implements ArgumentConverter<Location> {
Location location = new Location(world.get().iterator().next(), vector.get().iterator().next().toVector3());
return SuccessfulConversion.fromSingle(location);
}
}

View File

@ -46,14 +46,14 @@ public class OffsetConverter implements ArgumentConverter<BlockVector3> {
public static void register(WorldEdit worldEdit, CommandManager commandManager) {
commandManager.registerConverter(
Key.of(BlockVector3.class, Offset.class),
new OffsetConverter(worldEdit)
Key.of(BlockVector3.class, Offset.class),
new OffsetConverter(worldEdit)
);
}
private final DirectionVectorConverter directionVectorConverter;
private final VectorConverter<Integer, BlockVector3> vectorConverter =
VectorConverter.BLOCK_VECTOR_3_CONVERTER;
VectorConverter.BLOCK_VECTOR_3_CONVERTER;
private OffsetConverter(WorldEdit worldEdit) {
directionVectorConverter = new DirectionVectorConverter(worldEdit, true);
@ -62,23 +62,23 @@ public class OffsetConverter implements ArgumentConverter<BlockVector3> {
@Override
public Component describeAcceptableArguments() {
return TextComponent.builder()
.append(directionVectorConverter.describeAcceptableArguments())
.append(", or ")
.append(vectorConverter.describeAcceptableArguments())
.build();
.append(directionVectorConverter.describeAcceptableArguments())
.append(", or ")
.append(vectorConverter.describeAcceptableArguments())
.build();
}
@Override
public List<String> getSuggestions(String input, InjectedValueAccess context) {
if (input.startsWith("^") && context.injectedValue(Key.of(Actor.class))
.filter(actor -> actor instanceof Locatable).isPresent()) {
.filter(actor -> actor instanceof Locatable).isPresent()) {
return vectorConverter.getSuggestions(input.substring(1), context).stream()
.map(s -> "^" + s)
.collect(Collectors.toList());
.map(s -> "^" + s)
.collect(Collectors.toList());
}
return ImmutableList.copyOf(Iterables.concat(
directionVectorConverter.getSuggestions(input, context),
vectorConverter.getSuggestions(input, context)
directionVectorConverter.getSuggestions(input, context),
vectorConverter.getSuggestions(input, context)
));
}
@ -98,15 +98,15 @@ public class OffsetConverter implements ArgumentConverter<BlockVector3> {
// Create an affine transform of the columns (col4 is empty due to no translation)
AffineTransform transform = new AffineTransform(
m1.getX(), m2.getX(), m3.getX(), 0,
m1.getY(), m2.getY(), m3.getY(), 0,
m1.getZ(), m2.getZ(), m3.getZ(), 0
m1.getX(), m2.getX(), m3.getX(), 0,
m1.getY(), m2.getY(), m3.getY(), 0,
m1.getZ(), m2.getZ(), m3.getZ(), 0
);
return transform
.apply(relativeOffset.toVector3())
// This *MUST* be rounded before converting to block points
.round().toBlockPoint();
.apply(relativeOffset.toVector3())
// This *MUST* be rounded before converting to block points
.round().toBlockPoint();
}
@Override
@ -115,7 +115,7 @@ public class OffsetConverter implements ArgumentConverter<BlockVector3> {
try {
// Looking at a relative vector.
Actor actor = context.injectedValue(Key.of(Actor.class))
.orElseThrow(() -> new IllegalStateException("An actor is required to use relative offsets"));
.orElseThrow(() -> new IllegalStateException("An actor is required to use relative offsets"));
if (!(actor instanceof Locatable)) {
throw new IllegalStateException("Only a locatable actor may use relative offsets");
@ -124,16 +124,17 @@ public class OffsetConverter implements ArgumentConverter<BlockVector3> {
Location location = ((Locatable) actor).getLocation();
return vectorConverter.convert(input.substring(1), context).map(blockVector3s ->
blockVector3s.stream()
.map(vector -> rotateToRelative(location, vector))
.collect(Collectors.toList())
blockVector3s.stream()
.map(vector -> rotateToRelative(location, vector))
.collect(Collectors.toList())
);
} catch (IllegalStateException e) {
return FailedConversion.from(e);
}
} else {
return directionVectorConverter.convert(input, context)
.orElse(vectorConverter.convert(input, context));
.orElse(vectorConverter.convert(input, context));
}
}
}

View File

@ -31,19 +31,21 @@ import org.enginehub.piston.inject.Key;
public class RegionFactoryConverter {
public static void register(CommandManager commandManager) {
commandManager.registerConverter(Key.of(RegionFactory.class),
MultiKeyConverter.builder(
ImmutableSetMultimap.<RegionFactory, String>builder()
.put(new CuboidRegionFactory(), "cuboid")
.put(new SphereRegionFactory(), "sphere")
.putAll(new CylinderRegionFactory(1), "cyl", "cylinder")
.build()
)
.errorMessage(arg -> "Not a known region type: " + arg)
.build()
commandManager.registerConverter(
Key.of(RegionFactory.class),
MultiKeyConverter.builder(
ImmutableSetMultimap.<RegionFactory, String>builder()
.put(new CuboidRegionFactory(), "cuboid")
.put(new SphereRegionFactory(), "sphere")
.putAll(new CylinderRegionFactory(1), "cyl", "cylinder")
.build()
)
.errorMessage(arg -> "Not a known region type: " + arg)
.build()
);
}
private RegionFactoryConverter() {
}
}

View File

@ -53,22 +53,22 @@ public final class RegistryConverter<V extends Keyed> implements ArgumentConvert
@SuppressWarnings("unchecked")
public static void register(CommandManager commandManager) {
ImmutableList.of(
BlockType.class,
BlockCategory.class,
ItemType.class,
ItemCategory.class,
BiomeType.class,
EntityType.class,
FluidType.class,
FluidCategory.class,
GameMode.class,
WeatherType.class
BlockType.class,
BlockCategory.class,
ItemType.class,
ItemCategory.class,
BiomeType.class,
EntityType.class,
FluidType.class,
FluidCategory.class,
GameMode.class,
WeatherType.class
)
.stream()
.map(c -> (Class<Keyed>) c)
.forEach(registryType ->
commandManager.registerConverter(Key.of(registryType), from(registryType))
);
.stream()
.map(c -> (Class<Keyed>) c)
.forEach(registryType ->
commandManager.registerConverter(Key.of(registryType), from(registryType))
);
}
@SuppressWarnings("unchecked")
@ -102,7 +102,7 @@ public final class RegistryConverter<V extends Keyed> implements ArgumentConvert
V result = registry.get(argument.toLowerCase(Locale.ROOT));
return result == null
? FailedConversion.from(new IllegalArgumentException(
"Not a valid " + registry.getName() + ": " + argument))
"Not a valid " + registry.getName() + ": " + argument))
: SuccessfulConversion.fromSingle(result);
}
@ -110,4 +110,5 @@ public final class RegistryConverter<V extends Keyed> implements ArgumentConvert
public List<String> getSuggestions(String input, InjectedValueAccess context) {
return SuggestionHelper.getRegistrySuggestions(registry, input).collect(Collectors.toList());
}
}

View File

@ -70,4 +70,5 @@ public class SideEffectConverter implements ArgumentConverter<SideEffect> {
return FailedConversion.from(e);
}
}
}

View File

@ -42,39 +42,46 @@ import java.util.function.Function;
public class VectorConverter<C, T> implements ArgumentConverter<T> {
private static final CommaSeparatedValuesConverter<Integer> INT_CONVERTER =
CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(TypeToken.of(int.class)));
CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(TypeToken.of(int.class)));
public static final VectorConverter<Integer, BlockVector3> BLOCK_VECTOR_3_CONVERTER = new VectorConverter<>(
INT_CONVERTER,
3,
cmps -> BlockVector3.at(cmps.get(0), cmps.get(1), cmps.get(2)),
"block vector with x, y, and z"
INT_CONVERTER,
3,
cmps -> BlockVector3.at(cmps.get(0), cmps.get(1), cmps.get(2)),
"block vector with x, y, and z"
);
public static void register(CommandManager commandManager) {
CommaSeparatedValuesConverter<Double> doubleConverter = CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(TypeToken.of(double.class)));
commandManager.registerConverter(Key.of(BlockVector2.class),
new VectorConverter<>(
INT_CONVERTER,
2,
cmps -> BlockVector2.at(cmps.get(0), cmps.get(1)),
"block vector with x and z"
));
commandManager.registerConverter(Key.of(Vector2.class),
new VectorConverter<>(
doubleConverter,
2,
cmps -> Vector2.at(cmps.get(0), cmps.get(1)),
"vector with x and z"
));
CommaSeparatedValuesConverter<Double> doubleConverter = CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(
TypeToken.of(double.class)));
commandManager.registerConverter(
Key.of(BlockVector2.class),
new VectorConverter<>(
INT_CONVERTER,
2,
cmps -> BlockVector2.at(cmps.get(0), cmps.get(1)),
"block vector with x and z"
)
);
commandManager.registerConverter(
Key.of(Vector2.class),
new VectorConverter<>(
doubleConverter,
2,
cmps -> Vector2.at(cmps.get(0), cmps.get(1)),
"vector with x and z"
)
);
commandManager.registerConverter(Key.of(BlockVector3.class), BLOCK_VECTOR_3_CONVERTER);
commandManager.registerConverter(Key.of(Vector3.class),
new VectorConverter<>(
doubleConverter,
3,
cmps -> Vector3.at(cmps.get(0), cmps.get(1), cmps.get(2)),
"vector with x, y, and z"
));
commandManager.registerConverter(
Key.of(Vector3.class),
new VectorConverter<>(
doubleConverter,
3,
cmps -> Vector3.at(cmps.get(0), cmps.get(1), cmps.get(2)),
"vector with x, y, and z"
)
);
}
private final ArgumentConverter<C> componentConverter;
@ -83,10 +90,12 @@ public class VectorConverter<C, T> implements ArgumentConverter<T> {
private final String acceptableArguments;
private VectorConverter(ArgumentConverter<C> componentConverter,
int componentCount,
Function<List<C>, T> vectorConstructor,
String acceptableArguments) {
private VectorConverter(
ArgumentConverter<C> componentConverter,
int componentCount,
Function<List<C>, T> vectorConstructor,
String acceptableArguments
) {
this.componentConverter = componentConverter;
this.componentCount = componentCount;
this.vectorConstructor = vectorConstructor;
@ -106,9 +115,10 @@ public class VectorConverter<C, T> implements ArgumentConverter<T> {
}
if (components.get().size() != componentCount) {
return FailedConversion.from(new IllegalArgumentException(
"Must have exactly " + componentCount + " vector components"));
"Must have exactly " + componentCount + " vector components"));
}
T vector = vectorConstructor.apply(ImmutableList.copyOf(components.get()));
return SuccessfulConversion.fromSingle(vector);
}
}

View File

@ -41,7 +41,7 @@ public class WorldConverter implements ArgumentConverter<World> {
public static void register(CommandManager commandManager) {
commandManager.registerConverter(Key.of(World.class), WORLD_CONVERTER);
}
//FAWE start - Accessed by LocationConverter
public static final WorldConverter WORLD_CONVERTER = new WorldConverter();
//FAWE end
@ -80,4 +80,5 @@ public class WorldConverter implements ArgumentConverter<World> {
"Not a valid world: " + s))
: SuccessfulConversion.fromSingle(result);
}
}

View File

@ -51,11 +51,12 @@ public class ZonedDateTimeConverter implements ArgumentConverter<ZonedDateTime>
@Override
public ConversionResult<ZonedDateTime> convert(String argument, InjectedValueAccess context) {
LocalSession session = context.injectedValue(Key.of(LocalSession.class))
.orElseThrow(() -> new IllegalStateException("Need a local session"));
.orElseThrow(() -> new IllegalStateException("Need a local session"));
Calendar date = session.detectDate(argument);
if (date == null) {
return FailedConversion.from(new IllegalArgumentException("Not a date: " + argument));
}
return SuccessfulConversion.fromSingle(date.toInstant().atZone(ZoneOffset.UTC));
}
}

View File

@ -29,6 +29,7 @@ import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.World;
public final class ItemUseFactory implements Contextual<RegionFunction> {
private final BaseItem item;
private final Direction dir;
@ -51,4 +52,5 @@ public final class ItemUseFactory implements Contextual<RegionFunction> {
public String toString() {
return "application of the item " + item.getType();
}
}

View File

@ -29,6 +29,7 @@ import com.sk89q.worldedit.function.pattern.Pattern;
import static com.sk89q.worldedit.util.GuavaUtil.firstNonNull;
public class ReplaceFactory implements Contextual<RegionFunction> {
private final Pattern fill;
public ReplaceFactory(Pattern fill) {
@ -38,12 +39,14 @@ public class ReplaceFactory implements Contextual<RegionFunction> {
@Override
public RegionFunction createFromContext(EditContext context) {
return new BlockReplace(
firstNonNull(context.getDestination(), new NullExtent()),
firstNonNull(context.getFill(), fill));
firstNonNull(context.getDestination(), new NullExtent()),
firstNonNull(context.getFill(), fill)
);
}
@Override
public String toString() {
return "replace blocks";
}
}

View File

@ -26,6 +26,7 @@ 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) {
@ -41,4 +42,5 @@ public final class TreeGeneratorFactory implements Contextual<ForestGenerator> {
public String toString() {
return "tree of type " + type;
}
}

View File

@ -36,11 +36,11 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockState;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
/**
* A mode that cycles the data values of supported blocks.
@ -54,8 +54,10 @@ public class BlockDataCyler implements DoubleActionBlockTool {
private final Map<UUID, Property<?>> selectedProperties = new HashMap<>();
private boolean handleCycle(LocalConfiguration config, Player player, LocalSession session,
Location clicked, boolean forward) {
private boolean handleCycle(
LocalConfiguration config, Player player, LocalSession session,
Location clicked, boolean forward
) {
World world = (World) clicked.getExtent();
@ -117,12 +119,26 @@ public class BlockDataCyler implements DoubleActionBlockTool {
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actPrimary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
return handleCycle(config, player, session, clicked, true);
}
@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actSecondary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
return handleCycle(config, player, session, clicked, false);
}

View File

@ -53,7 +53,14 @@ public class BlockReplacer implements DoubleActionBlockTool {
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actPrimary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
BlockBag bag = session.getBlockBag(player);
try (EditSession editSession = session.createEditSession(player)) {
@ -76,7 +83,14 @@ public class BlockReplacer implements DoubleActionBlockTool {
@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actSecondary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
BaseBlock targetBlock = player.getWorld().getFullBlock(clicked.toVector().toBlockPoint());
if (targetBlock != null) {

View File

@ -37,33 +37,45 @@ public interface BlockTool extends Tool {
*
* @return true to cancel the original event which triggered this action (if possible)
* @deprecated New subclasses should override
* {@link #actPrimary(Platform, LocalConfiguration, Player, LocalSession, Location, Direction)}
* instead
* {@link #actPrimary(Platform, LocalConfiguration, Player, LocalSession, Location, Direction)}
* instead
*/
@Deprecated
default boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
default boolean actPrimary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked
) {
return actPrimary(server, config, player, session, clicked, null);
}
/**
* Perform the primary action of this tool.
*
* @param server The platform
* @param config The config instance
* @param player The player
* @param server The platform
* @param config The config instance
* @param player The player
* @param session The local session
* @param clicked The location that was clicked
* @param face The face that was clicked
* @param face The face that was clicked
* @return true to cancel the original event which triggered this action (if possible)
* @apiNote This must be overridden by new subclasses. See {@link NonAbstractForCompatibility}
* for details
*/
@NonAbstractForCompatibility(
delegateName = "actPrimary",
delegateParams = { Platform.class, LocalConfiguration.class, Player.class, LocalSession.class, Location.class }
delegateName = "actPrimary",
delegateParams = {Platform.class, LocalConfiguration.class, Player.class, LocalSession.class, Location.class}
)
default boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
default boolean actPrimary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
DeprecationUtil.checkDelegatingOverride(getClass());
return actPrimary(server, config, player, session, clicked);
}
}

View File

@ -19,13 +19,13 @@
package com.sk89q.worldedit.command.tool;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.command.tool.brush.BrushSettings;
import com.fastasyncworldedit.core.command.tool.MovableTool;
import com.fastasyncworldedit.core.command.tool.ResettableTool;
import com.fastasyncworldedit.core.command.tool.TargetMode;
import com.fastasyncworldedit.core.command.tool.brush.BrushSettings;
import com.fastasyncworldedit.core.command.tool.scroll.Scroll;
import com.fastasyncworldedit.core.command.tool.scroll.ScrollTool;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.function.mask.MaskedTargetBlock;
import com.fastasyncworldedit.core.function.pattern.PatternTraverser;
@ -54,10 +54,10 @@ import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.block.BlockType;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
@ -65,8 +65,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
* Builds a shape at the place being looked at.
*/
public class BrushTool
//FAWE start - All implements but TraceTool
implements DoubleActionTraceTool, ScrollTool, MovableTool, ResettableTool, Serializable, TraceTool {
//FAWE start - All implements but TraceTool
implements DoubleActionTraceTool, ScrollTool, MovableTool, ResettableTool, Serializable, TraceTool {
// TODO:
// Serialize methods
// serialize BrushSettings (primary and secondary only if different)
@ -74,7 +74,8 @@ public class BrushTool
enum BrushAction {
PRIMARY, SECONDARY
PRIMARY,
SECONDARY
}
//FAWE end
@ -256,6 +257,7 @@ public class BrushTool
}
//FAWE start
/**
* Set the block filter used for identifying blocks to replace.
*
@ -270,7 +272,7 @@ public class BrushTool
/**
* Set the brush.
*
* @param brush the brush
* @param brush the brush
* @param permission the permission
*/
public void setBrush(Brush brush, String permission) {
@ -357,8 +359,10 @@ public class BrushTool
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player,
LocalSession session) {
public boolean actPrimary(
Platform server, LocalConfiguration config, Player player,
LocalSession session
) {
//FAWE start - Use logic previously declared as FAWE-like
return act(BrushAction.PRIMARY, player, session);
//FAWE end
@ -376,7 +380,7 @@ public class BrushTool
pitch = 23 - (pitch / 4);
d += (int) (Math.sin(Math.toRadians(pitch)) * 50);
final Vector3 vector = loc.getDirection().withY(0).normalize().multiply(d)
.add(loc.getX(), loc.getY(), loc.getZ());
.add(loc.getX(), loc.getY(), loc.getZ());
return offset(vector, loc).toBlockPoint();
}
case TARGET_POINT_HEIGHT: {
@ -433,7 +437,7 @@ public class BrushTool
if (!current.canUse(player)) {
player.print(
Caption.of("fawe.error.no-perm", StringMan.join(current.getPermissions(), ",")));
Caption.of("fawe.error.no-perm", StringMan.join(current.getPermissions(), ",")));
return false;
}
try (EditSession editSession = session.createEditSession(player, current.toString())) {
@ -491,13 +495,14 @@ public class BrushTool
}
@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player,
LocalSession session) {
public boolean actSecondary(
Platform server, LocalConfiguration config, Player player,
LocalSession session
) {
return act(BrushAction.SECONDARY, player, session);
}
public void setScrollAction(Scroll scrollAction) {
this.getContext().setScrollAction(scrollAction);
update();

View File

@ -85,4 +85,5 @@ public class DistanceWand extends BrushTool implements DoubleActionTraceTool {
return target;
}
}

View File

@ -40,32 +40,43 @@ public interface DoubleActionBlockTool extends BlockTool {
*
* @return true to cancel the original event which triggered this action (if possible)
* @deprecated New subclasses must override
* {@link #actSecondary(Platform, LocalConfiguration, Player, LocalSession, Location, Direction)}
* instead
* {@link #actSecondary(Platform, LocalConfiguration, Player, LocalSession, Location, Direction)}
* instead
*/
@Deprecated
default boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
default boolean actSecondary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked
) {
return actSecondary(server, config, player, session, clicked, null);
}
/**
* Perform the secondary action of this block tool.
*
* @param server The platform
* @param config The config instance
* @param player The player
* @param server The platform
* @param config The config instance
* @param player The player
* @param session The local session
* @param clicked The location that was clicked
* @param face The face that was clicked
* @param face The face that was clicked
* @return true to cancel the original event which triggered this action (if possible)
* @apiNote This must be overridden by new subclasses. See {@link NonAbstractForCompatibility}
* for details
*/
@NonAbstractForCompatibility(
delegateName = "actSecondary",
delegateParams = { Platform.class, LocalConfiguration.class, Player.class, LocalSession.class, Location.class }
delegateName = "actSecondary",
delegateParams = {Platform.class, LocalConfiguration.class, Player.class, LocalSession.class, Location.class}
)
default boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
default boolean actSecondary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
DeprecationUtil.checkDelegatingOverride(getClass());
return actSecondary(server, config, player, session, clicked);
}

View File

@ -32,9 +32,9 @@ public interface DoubleActionTraceTool extends TraceTool {
/**
* Perform the secondary function of this tool.
*
* @param server The platform
* @param config The config instance
* @param player The player
* @param server The platform
* @param config The config instance
* @param player The player
* @param session The local session
* @return true to cancel the original event which triggered this action (if possible)
*/

View File

@ -36,8 +36,8 @@ import com.sk89q.worldedit.world.block.BlockCategories;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import javax.annotation.Nullable;
import javax.annotation.Nullable;
import java.util.Iterator;
import java.util.Set;
@ -46,6 +46,7 @@ import java.util.Set;
* to anything else).
*/
public class FloatingTreeRemover implements BlockTool {
private final int rangeSq;
public FloatingTreeRemover() {
@ -67,9 +68,11 @@ public class FloatingTreeRemover implements BlockTool {
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config,
Player player, LocalSession session, Location clicked,
@Nullable Direction face) {
public boolean actPrimary(
Platform server, LocalConfiguration config,
Player player, LocalSession session, Location clicked,
@Nullable Direction face
) {
final World world = (World) clicked.getExtent();
final BlockState state = world.getBlock(clicked.toVector().toBlockPoint());
@ -115,7 +118,7 @@ public class FloatingTreeRemover implements BlockTool {
/**
* Helper method.
*
* @param world the world that contains the tree
* @param world the world that contains the tree
* @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.
*/
@ -143,7 +146,7 @@ public class FloatingTreeRemover implements BlockTool {
if (visited.add(next)) {
BlockState state = world.getBlock(next);
if (state.getBlockType().getMaterial().isAir()
|| state.getBlockType() == BlockTypes.SNOW) {
|| state.getBlockType() == BlockTypes.SNOW) {
continue;
}
if (isTreeBlock(state.getBlockType())) {
@ -152,7 +155,7 @@ public class FloatingTreeRemover implements BlockTool {
// we hit something solid - evaluate where we came from
final BlockType currentType = world.getBlock(current).getBlockType();
if (!BlockCategories.LEAVES.contains(currentType)
&& currentType != BlockTypes.VINE) {
&& currentType != BlockTypes.VINE) {
// log/shroom touching a wall/the ground => this is not a floating tree, bail out
return null;
}
@ -164,4 +167,5 @@ public class FloatingTreeRemover implements BlockTool {
return visited;
}
}

View File

@ -38,8 +38,8 @@ import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import javax.annotation.Nullable;
import javax.annotation.Nullable;
import java.util.Set;
/**
@ -61,7 +61,14 @@ public class FloodFillTool implements BlockTool {
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actPrimary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
World world = (World) clicked.getExtent();
BlockVector3 origin = clicked.toVector().toBlockPoint();
@ -94,8 +101,10 @@ public class FloodFillTool implements BlockTool {
return true;
}
private void recurse(EditSession editSession, BlockVector3 pos, BlockVector3 origin, int size, BlockType initialType,
Set<BlockVector3> visited) throws MaxChangedBlocksException {
private void recurse(
EditSession editSession, BlockVector3 pos, BlockVector3 origin, int size, BlockType initialType,
Set<BlockVector3> visited
) throws MaxChangedBlocksException {
if (origin.distance(pos) > size || visited.contains(pos)) {
return;
@ -110,17 +119,23 @@ public class FloodFillTool implements BlockTool {
}
recurse(editSession, pos.add(1, 0, 0),
origin, size, initialType, visited);
origin, size, initialType, visited
);
recurse(editSession, pos.add(-1, 0, 0),
origin, size, initialType, visited);
origin, size, initialType, visited
);
recurse(editSession, pos.add(0, 0, 1),
origin, size, initialType, visited);
origin, size, initialType, visited
);
recurse(editSession, pos.add(0, 0, -1),
origin, size, initialType, visited);
origin, size, initialType, visited
);
recurse(editSession, pos.add(0, 1, 0),
origin, size, initialType, visited);
origin, size, initialType, visited
);
recurse(editSession, pos.add(0, -1, 0),
origin, size, initialType, visited);
origin, size, initialType, visited
);
}
}

View File

@ -20,8 +20,8 @@
package com.sk89q.worldedit.command.tool;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.world.item.ItemType;
public class InvalidToolBindException extends WorldEditException {

View File

@ -29,29 +29,29 @@ import com.sk89q.worldedit.util.Location;
//FAWE start - enum-ized
public enum NavigationWand implements DoubleActionTraceTool {
INSTANCE;
INSTANCE;
//FAWE end
private static final String PRIMARY_PERMISSION = "worldedit.navigation.thru.tool";
private static final String SECONDARY_PERMISSION = "worldedit.navigation.jumpto.tool";
@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
if (!player.hasPermission(SECONDARY_PERMISSION)) {
return false;
}
final int maxDist = config.navigationWandMaxDistance;
if (maxDist <= 0) {
return false;
}
Location pos = player.getSolidBlockTrace(maxDist);
if (pos != null) {
player.findFreePosition(pos);
} else {
player.print(Caption.of("worldedit.jumpto.none"));
}
return true;
}
@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
if (!player.hasPermission(SECONDARY_PERMISSION)) {
return false;
}
final int maxDist = config.navigationWandMaxDistance;
if (maxDist <= 0) {
return false;
}
Location pos = player.getSolidBlockTrace(maxDist);
if (pos != null) {
player.findFreePosition(pos);
} else {
player.print(Caption.of("worldedit.jumpto.none"));
}
return true;
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) {

View File

@ -36,6 +36,7 @@ import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import javax.annotation.Nullable;
/**
@ -49,8 +50,10 @@ public class QueryTool implements BlockTool {
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable
Direction face) {
public boolean actPrimary(
Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable
Direction face
) {
World world = (World) clicked.getExtent();
EditSession editSession = session.createEditSession(player);
@ -61,21 +64,21 @@ public class QueryTool implements BlockTool {
builder.append(TextComponent.of("@" + clicked.toVector().toBlockPoint() + ": ", TextColor.BLUE));
builder.append(block.getBlockType().getRichName().color(TextColor.YELLOW));
builder.append(TextComponent.of(" (" + block + ") ", TextColor.GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.tool.info.blockstate.hover"))));
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.tool.info.blockstate.hover"))));
final int internalId = BlockStateIdAccess.getBlockStateId(block.toImmutableState());
if (BlockStateIdAccess.isValidInternalId(internalId)) {
builder.append(TextComponent.of(" (" + internalId + ") ", TextColor.DARK_GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.tool.info.internalid.hover"))));
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.tool.info.internalid.hover"))));
}
final int[] legacy = LegacyMapper.getInstance().getLegacyFromBlock(block.toImmutableState());
if (legacy != null) {
builder.append(TextComponent.of(" (" + legacy[0] + ":" + legacy[1] + ") ", TextColor.DARK_GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.tool.info.legacy.hover"))));
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.tool.info.legacy.hover"))));
}
builder.append(TextComponent.of(" (" + world.getBlockLightLevel(blockPoint) + "/"
+ world.getBlockLightLevel(blockPoint.add(0, 1, 0)) + ")", TextColor.WHITE)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.tool.info.light.hover"))));
+ world.getBlockLightLevel(blockPoint.add(0, 1, 0)) + ")", TextColor.WHITE)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, Caption.of("worldedit.tool.info.light.hover"))));
player.print(builder.build());

View File

@ -35,8 +35,8 @@ import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import javax.annotation.Nullable;
import javax.annotation.Nullable;
import java.util.Set;
/**
@ -57,7 +57,14 @@ public class RecursivePickaxe implements BlockTool {
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actPrimary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
World world = (World) clicked.getExtent();
final BlockVector3 pos = clicked.toBlockPoint();
@ -92,8 +99,10 @@ 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 {
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)) {
@ -111,17 +120,23 @@ public class RecursivePickaxe implements BlockTool {
world.queueBlockBreakEffect(server, pos, initialType, distanceSq);
recurse(server, editSession, world, pos.add(1, 0, 0),
origin, size, initialType, visited);
origin, size, initialType, visited
);
recurse(server, editSession, world, pos.add(-1, 0, 0),
origin, size, initialType, visited);
origin, size, initialType, visited
);
recurse(server, editSession, world, pos.add(0, 0, 1),
origin, size, initialType, visited);
origin, size, initialType, visited
);
recurse(server, editSession, world, pos.add(0, 0, -1),
origin, size, initialType, visited);
origin, size, initialType, visited
);
recurse(server, editSession, world, pos.add(0, 1, 0),
origin, size, initialType, visited);
origin, size, initialType, visited
);
recurse(server, editSession, world, pos.add(0, -1, 0),
origin, size, initialType, visited);
origin, size, initialType, visited
);
}
}

View File

@ -43,7 +43,14 @@ public enum SelectionWand implements DoubleActionBlockTool {
private static final Logger LOGGER = LogManagerCompat.getLogger();
@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actSecondary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
RegionSelector selector = session.getRegionSelector(player.getWorld());
BlockVector3 blockPoint = clicked.toVector().toBlockPoint();
@ -59,7 +66,14 @@ public enum SelectionWand implements DoubleActionBlockTool {
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actPrimary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
RegionSelector selector = session.getRegionSelector(player.getWorld());
BlockVector3 blockPoint = clicked.toVector().toBlockPoint();

View File

@ -47,7 +47,14 @@ public class SinglePickaxe implements BlockTool {
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actPrimary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
World world = (World) clicked.getExtent();
BlockVector3 blockPoint = clicked.toBlockPoint();
final BlockType blockType = world.getBlock(blockPoint).getBlockType();

View File

@ -46,7 +46,14 @@ public class StackTool implements BlockTool {
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actPrimary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
if (face == null) {
return false;
}
@ -82,4 +89,5 @@ public class StackTool implements BlockTool {
public boolean canUse(Actor actor) {
return actor.hasPermission("worldedit.tool.stack");
}
}

View File

@ -29,11 +29,12 @@ public interface TraceTool extends Tool {
/**
* Perform the primary action of this trace tool.
*
* @param server The platform
* @param config The config instance
* @param player The player
* @param server The platform
* @param config The config instance
* @param player The player
* @param session The local session
* @return true to cancel the original event which triggered this action (if possible)
*/
boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session);
}

View File

@ -51,7 +51,14 @@ public class TreePlanter implements BlockTool {
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
public boolean actPrimary(
Platform server,
LocalConfiguration config,
Player player,
LocalSession session,
Location clicked,
@Nullable Direction face
) {
try (EditSession editSession = session.createEditSession(player)) {
try {

View File

@ -33,9 +33,9 @@ public interface Brush {
* Build the object.
*
* @param editSession the {@code EditSession}
* @param position the position
* @param pattern the pattern
* @param size the size of the brush
* @param position the position
* @param pattern the pattern
* @param size the size of the brush
* @throws MaxChangedBlocksException if the maximum block change limit is exceeded
*/
void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException;

View File

@ -40,7 +40,8 @@ public class ButcherBrush implements Brush {
}
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
MaxChangedBlocksException {
CylinderRegion region = CylinderRegion.createRadius(editSession, position, size);
List<? extends Entity> entities = editSession.getEntities(region);
Operations.completeLegacy(new EntityVisitor(entities.iterator(), flags.createFunction()));

View File

@ -48,8 +48,10 @@ public class ClipboardBrush implements Brush {
this.sourceMask = null;
}
public ClipboardBrush(ClipboardHolder holder, boolean ignoreAirBlocks, boolean usingOrigin, boolean pasteEntities,
boolean pasteBiomes, Mask sourceMask) {
public ClipboardBrush(
ClipboardHolder holder, boolean ignoreAirBlocks, boolean usingOrigin, boolean pasteEntities,
boolean pasteBiomes, Mask sourceMask
) {
this.holder = holder;
this.ignoreAirBlocks = ignoreAirBlocks;
this.usingOrigin = usingOrigin;
@ -59,7 +61,8 @@ public class ClipboardBrush implements Brush {
}
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
MaxChangedBlocksException {
Clipboard clipboard = holder.getClipboard();
Region region = clipboard.getRegion();
BlockVector3 centerOffset = region.getCenter().toBlockPoint().subtract(clipboard.getOrigin());

View File

@ -34,7 +34,8 @@ public class CylinderBrush implements Brush {
}
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
MaxChangedBlocksException {
if (pattern == null) {
pattern = BlockTypes.COBBLESTONE.getDefaultState();
}

View File

@ -35,7 +35,8 @@ public class GravityBrush implements Brush {
}
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
MaxChangedBlocksException {
//FAWE start - Ours operates differently to upstream, but does the same
double endY = position.getY() + size;
double startPerformY = Math.max(0, position.getY() - size);
@ -44,11 +45,11 @@ public class GravityBrush implements Brush {
for (double z = position.getZ() + size; z > position.getZ() - size; --z) {
double freeSpot = startCheckY;
for (double y = startCheckY; y <= endY; y++) {
BlockState block = editSession.getBlock((int)x, (int)y, (int)z);
BlockState block = editSession.getBlock((int) x, (int) y, (int) z);
if (!block.getBlockType().getMaterial().isAir()) {
if (y != freeSpot) {
editSession.setBlock((int)x, (int)y, (int)z, BlockTypes.AIR.getDefaultState());
editSession.setBlock((int)x, (int)freeSpot, (int)z, block);
editSession.setBlock((int) x, (int) y, (int) z, BlockTypes.AIR.getDefaultState());
editSession.setBlock((int) x, (int) freeSpot, (int) z, block);
}
freeSpot = y + 1;
}
@ -57,4 +58,5 @@ public class GravityBrush implements Brush {
}
//FAWE end
}
}

View File

@ -34,7 +34,8 @@ public class HollowCylinderBrush implements Brush {
}
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
MaxChangedBlocksException {
if (pattern == null) {
pattern = BlockTypes.COBBLESTONE.getDefaultState();
}

View File

@ -28,10 +28,12 @@ import com.sk89q.worldedit.world.block.BlockTypes;
public class HollowSphereBrush implements Brush {
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
MaxChangedBlocksException {
if (pattern == null) {
pattern = BlockTypes.COBBLESTONE.getDefaultState();
}
editSession.makeSphere(position, pattern, size, size, size, false);
}
}

View File

@ -40,14 +40,19 @@ public class OperationFactoryBrush implements Brush {
this(operationFactory, regionFactory, null);
}
public OperationFactoryBrush(Contextual<? extends Operation> operationFactory, RegionFactory regionFactory, LocalSession session) {
public OperationFactoryBrush(
Contextual<? extends Operation> operationFactory,
RegionFactory regionFactory,
LocalSession session
) {
this.operationFactory = operationFactory;
this.regionFactory = regionFactory;
this.session = session;
}
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
MaxChangedBlocksException {
EditContext context = new EditContext();
context.setDestination(editSession);
context.setRegion(regionFactory.createCenteredAt(position, size));

View File

@ -49,7 +49,8 @@ public class SmoothBrush implements Brush {
}
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
MaxChangedBlocksException {
Vector3 posDouble = position.toVector3();
Location min = new Location(editSession.getWorld(), posDouble.subtract(size, size, size));
BlockVector3 max = posDouble.add(size, size + 10, size).toBlockPoint();

View File

@ -28,10 +28,12 @@ import com.sk89q.worldedit.world.block.BlockTypes;
public class SphereBrush implements Brush {
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
MaxChangedBlocksException {
if (pattern == null) {
pattern = BlockTypes.COBBLESTONE.getDefaultState();
}
editSession.makeSphere(position, pattern, size, size, size, true);
}
}

View File

@ -37,9 +37,9 @@ import org.apache.logging.log4j.Logger;
import org.enginehub.piston.exception.CommandException;
import org.enginehub.piston.exception.CommandExecutionException;
import javax.annotation.Nullable;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
@ -215,4 +215,5 @@ public final class AsyncCommandBuilder<T> {
}
return message;
}
}

View File

@ -37,4 +37,5 @@ public @interface CommandPermissions {
String[] value() default {};
boolean queued() default true;
}

View File

@ -33,7 +33,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
public final class CommandPermissionsConditionGenerator implements CommandConditionGenerator {
public interface Registration {
Registration commandPermissionsConditionGenerator(CommandPermissionsConditionGenerator generator);
}
@Override
@ -43,4 +45,5 @@ public final class CommandPermissionsConditionGenerator implements CommandCondit
Set<String> permissions = ImmutableSet.copyOf(annotation.value());
return new PermissionCondition(permissions, annotation.queued());
}
}

View File

@ -29,6 +29,7 @@ import com.sk89q.worldedit.function.EntityFunction;
public class CreatureButcher {
public final class Flags {
@SuppressWarnings("PointlessBitwiseExpression")
public static final int PETS = 1 << 0;
public static final int NPCS = 1 << 1;
@ -42,6 +43,7 @@ public class CreatureButcher {
private Flags() {
}
}
private final Actor player;

View File

@ -23,8 +23,8 @@ import com.fastasyncworldedit.core.util.TaskManager;
import com.sk89q.worldedit.entity.metadata.EntityProperties;
import com.sk89q.worldedit.function.EntityFunction;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.checkNotNull;
@ -129,7 +129,8 @@ public class EntityRemover {
if (type != null) {
return new EntityRemover(type);
} else {
throw new IllegalArgumentException("Acceptable types: projectiles, items, paintings, itemframes, boats, minecarts, tnt, xp, or all");
throw new IllegalArgumentException(
"Acceptable types: projectiles, items, paintings, itemframes, boats, minecarts, tnt, xp, or all");
}
}

View File

@ -69,7 +69,12 @@ public class FutureProgressListener implements Runnable {
future.addListener(new FutureProgressListener(sender, message), MoreExecutors.directExecutor());
}
public static void addProgressListener(ListenableFuture<?> future, Actor sender, Component message, Component workingMessage) {
public static void addProgressListener(
ListenableFuture<?> future,
Actor sender,
Component message,
Component workingMessage
) {
future.addListener(new FutureProgressListener(sender, message, workingMessage), MoreExecutors.directExecutor());
}

View File

@ -20,5 +20,6 @@
package com.sk89q.worldedit.command.util;
public enum HookMode {
ACTIVE, INACTIVE
ACTIVE,
INACTIVE
}

View File

@ -51,9 +51,9 @@ public class PermissionCondition implements Command.Condition {
@Override
public boolean satisfied(InjectedValueAccess context) {
return permissions.isEmpty()
|| context.injectedValue(ACTOR_KEY)
.map(actor -> permissions.stream().anyMatch(actor::hasPermission))
.orElse(false);
|| context.injectedValue(ACTOR_KEY)
.map(actor -> permissions.stream().anyMatch(actor::hasPermission))
.orElse(false);
}
//FAWE start

View File

@ -68,8 +68,10 @@ public class PrintCommandHelp {
return mapping.orElse(null);
}
public static void help(List<String> commandPath, int page, boolean listSubCommands,
CommandManager manager, Actor actor, String helpRootCommand) throws InvalidComponentException {
public static void help(
List<String> commandPath, int page, boolean listSubCommands,
CommandManager manager, Actor actor, String helpRootCommand
) throws InvalidComponentException {
if (commandPath.isEmpty()) {
printCommands(page, manager.getAllCommands(), actor, ImmutableList.of(), helpRootCommand);
@ -91,7 +93,8 @@ public class PrintCommandHelp {
if (subCommands.isEmpty()) {
actor.print(Caption.of("worldedit.help.no-subcommands",
TextComponent.of(toCommandString(visited)), TextComponent.of(subCommand)));
TextComponent.of(toCommandString(visited)), TextComponent.of(subCommand)
));
// full help for single command
CommandUsageBox box = new CommandUsageBox(visited, visited.stream()
.map(Command::getName).collect(Collectors.joining(" ")), helpRootCommand);
@ -104,9 +107,16 @@ public class PrintCommandHelp {
visited.add(currentCommand);
} else {
actor.print(Caption.of("worldedit.help.subcommand-not-found",
TextComponent.of(subCommand), TextComponent.of(toCommandString(visited))));
TextComponent.of(subCommand), TextComponent.of(toCommandString(visited))
));
// list subcommands for currentCommand
printCommands(page, getSubCommands(Iterables.getLast(visited)).values().stream(), actor, visited, helpRootCommand);
printCommands(
page,
getSubCommands(Iterables.getLast(visited)).values().stream(),
actor,
visited,
helpRootCommand
);
return;
}
}
@ -126,18 +136,21 @@ public class PrintCommandHelp {
return "/" + Joiner.on(" ").join(visited.stream().map(Command::getName).iterator());
}
private static void printCommands(int page, Stream<Command> commandStream, Actor actor,
List<Command> commandList, String helpRootCommand) throws InvalidComponentException {
private static void printCommands(
int page, Stream<Command> commandStream, Actor actor,
List<Command> commandList, String helpRootCommand
) throws InvalidComponentException {
// Get a list of aliases
List<Command> commands = commandStream
.sorted(byCleanName())
.collect(toList());
.sorted(byCleanName())
.collect(toList());
String used = commandList.isEmpty() ? null : toCommandString(commandList);
CommandListBox box = new CommandListBox(
(used == null ? "Help" : "Subcommands: " + used),
helpRootCommand + " -s -p %page%" + (used == null ? "" : " " + used),
helpRootCommand);
helpRootCommand
);
if (!actor.isPlayer()) {
box.formatForConsole();
}
@ -145,8 +158,8 @@ public class PrintCommandHelp {
for (Command mapping : commands) {
String alias = (commandList.isEmpty() ? "/" : "") + mapping.getName();
String command = Stream.concat(commandList.stream(), Stream.of(mapping))
.map(Command::getName)
.collect(Collectors.joining(" ", "/", ""));
.map(Command::getName)
.collect(Collectors.joining(" ", "/", ""));
box.appendCommand(alias, mapping.getDescription(), command);
}
@ -155,4 +168,5 @@ public class PrintCommandHelp {
private PrintCommandHelp() {
}
}

View File

@ -45,6 +45,7 @@ public final class SubCommandPermissionCondition extends PermissionCondition {
}
public static class Generator {
private final List<Command> subCommands;
public Generator(Collection<? extends Command> subCommands) {
@ -52,18 +53,30 @@ public final class SubCommandPermissionCondition extends PermissionCondition {
}
public Command.Condition build() {
final List<Command.Condition> conditions = subCommands.stream().map(Command::getCondition).collect(Collectors.toList());
final List<Optional<PermissionCondition>> permConds = conditions.stream().map(c -> c.as(PermissionCondition.class)).collect(Collectors.toList());
final List<Command.Condition> conditions = subCommands
.stream()
.map(Command::getCondition)
.collect(Collectors.toList());
final List<Optional<PermissionCondition>> permConds = conditions
.stream()
.map(c -> c.as(PermissionCondition.class))
.collect(Collectors.toList());
if (permConds.stream().anyMatch(o -> !o.isPresent())) {
// if any sub-command doesn't require permissions, then this command doesn't require permissions
return new PermissionCondition(ImmutableSet.of());
}
// otherwise, this command requires any one subcommand to be available
final Set<String> perms = permConds.stream().map(Optional::get).flatMap(cond -> cond.getPermissions().stream()).collect(Collectors.toSet());
final Set<String> perms = permConds
.stream()
.map(Optional::get)
.flatMap(cond -> cond.getPermissions().stream())
.collect(Collectors.toSet());
final Command.Condition aggregate = permConds.stream().map(Optional::get)
.map(c -> (Command.Condition) c)
.reduce(Command.Condition::or).orElse(TRUE);
return new SubCommandPermissionCondition(perms, aggregate);
}
}
}

View File

@ -46,6 +46,7 @@ import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
* Internal class for generating common command suggestions.
*/
public final class SuggestionHelper {
private SuggestionHelper() {
}
@ -55,13 +56,17 @@ public final class SuggestionHelper {
}
if (tag.startsWith("##")) {
if (tag.equals("##")) {
return Stream.concat(allowRandom ? Stream.of("##*") : Stream.empty(),
getNamespacedRegistrySuggestions(BlockCategory.REGISTRY, tag.substring(2)).map(s -> "##" + s));
return Stream.concat(
allowRandom ? Stream.of("##*") : Stream.empty(),
getNamespacedRegistrySuggestions(BlockCategory.REGISTRY, tag.substring(2)).map(s -> "##" + s)
);
} else if (tag.equals("##*") && allowRandom) {
return getNamespacedRegistrySuggestions(BlockCategory.REGISTRY, tag.substring(3)).map(s -> "##*" + s);
} else {
boolean wild = tag.startsWith("##*") && allowRandom;
return getNamespacedRegistrySuggestions(BlockCategory.REGISTRY, tag.substring(wild ? 3 : 2)).map(s -> (wild ? "##*" : "##") + s);
return getNamespacedRegistrySuggestions(BlockCategory.REGISTRY, tag.substring(wild ? 3 : 2)).map(s -> (wild
? "##*"
: "##") + s);
}
}
return Stream.empty();
@ -97,7 +102,7 @@ public final class SuggestionHelper {
lastValidInput + prop + "=");
case 1:
return matchingProps.get(0).getValues().stream().map(val ->
lastValidInput + matchingProps.get(0).getName() + "="
lastValidInput + matchingProps.get(0).getName() + "="
+ val.toString().toLowerCase(Locale.ROOT));
default:
return matchingProps.stream().map(p -> lastValidInput + p.getName() + "=");
@ -107,9 +112,13 @@ public final class SuggestionHelper {
if (prop == null) {
return propertyMap.keySet().stream().map(p -> lastValidInput + p);
}
final List<String> values = prop.getValues().stream().map(v -> v.toString().toLowerCase(Locale.ROOT)).collect(Collectors.toList());
final List<String> values = prop.getValues().stream().map(v -> v.toString().toLowerCase(Locale.ROOT)).collect(
Collectors.toList());
String matchVal = propVal[1].toLowerCase(Locale.ROOT);
List<String> matchingVals = values.stream().filter(val -> val.startsWith(matchVal)).collect(Collectors.toList());
List<String> matchingVals = values
.stream()
.filter(val -> val.startsWith(matchVal))
.collect(Collectors.toList());
if (matchingVals.isEmpty()) {
return values.stream().map(val -> lastValidInput + prop.getName() + "=" + val);
} else {
@ -150,7 +159,10 @@ public final class SuggestionHelper {
return limitByPrefix(registry.keySet().stream(), input).stream();
}
public static <V extends Keyed> Stream<String> getNamespacedRegistrySuggestions(NamespacedRegistry<V> registry, String input) {
public static <V extends Keyed> Stream<String> getNamespacedRegistrySuggestions(
NamespacedRegistry<V> registry,
String input
) {
if (input.isEmpty() || input.equals(":")) {
final Set<String> namespaces = registry.getKnownNamespaces();
if (namespaces.size() == 1) {
@ -171,8 +183,10 @@ public final class SuggestionHelper {
final String lowerSearch = input.toLowerCase(Locale.ROOT);
String defKey = registry.getDefaultNamespace() + ":" + lowerSearch;
int defLength = registry.getDefaultNamespace().length() + 1;
return Stream.concat(registry.keySet().stream().filter(s -> s.startsWith(defKey)).map(s -> s.substring(defLength)),
registry.getKnownNamespaces().stream().filter(n -> n.startsWith(lowerSearch)).map(n -> n + ":"));
return Stream.concat(
registry.keySet().stream().filter(s -> s.startsWith(defKey)).map(s -> s.substring(defLength)),
registry.getKnownNamespaces().stream().filter(n -> n.startsWith(lowerSearch)).map(n -> n + ":")
);
}
// have a namespace - search that
Predicate<String> search = byPrefix(input.toLowerCase(Locale.ROOT));
@ -180,6 +194,7 @@ public final class SuggestionHelper {
}
//FAWE start
/**
* Returns a stream of suggestions for positive doubles.
*

View File

@ -24,13 +24,14 @@ import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.concurrent.Callable;
import javax.annotation.Nullable;
import java.util.concurrent.Callable;
/**
* For internal WorldEdit use only.
*/
public final class WorldEditAsyncCommandBuilder {
private WorldEditAsyncCommandBuilder() {
}
@ -46,7 +47,11 @@ public final class WorldEditAsyncCommandBuilder {
}
builder
.onSuccess((String) null, actor::printInfo)
.onFailure((String) null, WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getExceptionConverter())
.onFailure(
(String) null,
WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getExceptionConverter()
)
.buildAndExec(WorldEdit.getInstance().getExecutorService());
}
}

View File

@ -12,5 +12,7 @@ import java.lang.annotation.Target;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@InjectAnnotation
public @interface AllowedRegion {
FaweMaskManager.MaskType value() default FaweMaskManager.MaskType.OWNER;
}

View File

@ -37,11 +37,12 @@ import java.util.stream.Stream;
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.PARAMETER,
ElementType.METHOD
})
ElementType.PARAMETER,
ElementType.METHOD
})
@InjectAnnotation
public @interface Confirm {
Processor value() default Processor.ALWAYS;
enum Processor {
@ -51,15 +52,18 @@ public @interface Confirm {
if (checkExisting(context)) {
return true;
}
Region region = context.injectedValue(Key.of(Region.class, Selection.class)).orElseThrow(IncompleteRegionException::new);
Region region = context
.injectedValue(Key.of(Region.class, Selection.class))
.orElseThrow(IncompleteRegionException::new);
BlockVector3 pos1 = region.getMinimumPoint();
BlockVector3 pos2 = region.getMaximumPoint();
long area = (pos2.getX() - pos1.getX()) * (pos2.getZ() - pos1.getZ() + 1)
* (long) value;
* (long) value;
long max = 2 << 18;
if (max != -1 && area > max) {
actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.region",
pos1, pos2, getArgs(context), region.getHeight() * area));
pos1, pos2, getArgs(context), region.getHeight() * area
));
return confirm(actor, context);
}
return true;
@ -74,7 +78,8 @@ public @interface Confirm {
int max = WorldEdit.getInstance().getConfiguration().maxRadius;
if (max != -1 && value > max) {
actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.radius",
value, max, getArgs(context)));
value, max, getArgs(context)
));
return confirm(actor, context);
}
return true;
@ -89,7 +94,8 @@ public @interface Confirm {
int max = 50; //TODO configurable, get Key.of(Method.class) @Limit
if (max != -1 && value > max) {
actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.limit",
value, max, getArgs(context)));
value, max, getArgs(context)
));
return confirm(actor, context);
}
return true;
@ -190,8 +196,10 @@ public @interface Confirm {
}
class Reflect {
static final Field memory;
static final Field injectedValues;
static {
Field memoryField;
try {
@ -215,4 +223,5 @@ public @interface Confirm {
injectedValues = injectedValuesField;
}
}
}

View File

@ -1,7 +1,6 @@
package com.sk89q.worldedit.command.util.annotation;
import com.fastasyncworldedit.core.configuration.Settings;
import com.sk89q.worldedit.command.util.annotation.Confirm;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import org.enginehub.piston.CommandParameters;
@ -16,6 +15,7 @@ import java.util.Optional;
* Logs called commands to a logger.
*/
public class ConfirmHandler implements CommandCallListener {
@Override
public void beforeCall(Method method, CommandParameters parameters) {
Confirm confirmAnnotation = method.getAnnotation(Confirm.class);
@ -36,4 +36,5 @@ public class ConfirmHandler implements CommandCallListener {
throw new StopExecutionException(TextComponent.empty());
}
}
}

View File

@ -7,5 +7,7 @@ import java.lang.annotation.RetentionPolicy;
public @interface Link {
Class clazz() default Link.class;
String value();
}

View File

@ -14,4 +14,5 @@ import java.lang.annotation.Target;
@Target(ElementType.PARAMETER)
@InjectAnnotation
public @interface PatternList {
}

View File

@ -5,7 +5,9 @@ import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Step {
Class clazz() default Link.class;
double value() default 1;
}

View File

@ -11,4 +11,5 @@ import java.lang.annotation.Target;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@InjectAnnotation
public @interface Time {
}