diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index 8a1056f4..b1e92758 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -25,17 +25,25 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.blocks.BlockData; +import com.sk89q.worldedit.command.BiomeCommands; import com.sk89q.worldedit.command.BrushCommands; +import com.sk89q.worldedit.command.ChunkCommands; import com.sk89q.worldedit.command.ClipboardCommands; import com.sk89q.worldedit.command.FlattenedClipboardTransform; import com.sk89q.worldedit.command.GeneralCommands; +import com.sk89q.worldedit.command.GenerationCommands; import com.sk89q.worldedit.command.HistoryCommands; import com.sk89q.worldedit.command.NavigationCommands; import com.sk89q.worldedit.command.RegionCommands; import com.sk89q.worldedit.command.SchematicCommands; import com.sk89q.worldedit.command.ScriptingCommands; +import com.sk89q.worldedit.command.SnapshotCommands; +import com.sk89q.worldedit.command.SnapshotUtilCommands; +import com.sk89q.worldedit.command.SuperPickaxeCommands; import com.sk89q.worldedit.command.ToolCommands; import com.sk89q.worldedit.command.ToolUtilCommands; +import com.sk89q.worldedit.command.UtilityCommands; +import com.sk89q.worldedit.command.WorldEditCommands; import com.sk89q.worldedit.command.composition.SelectionCommand; import com.sk89q.worldedit.command.tool.AreaPickaxe; import com.sk89q.worldedit.command.tool.BrushTool; @@ -346,6 +354,14 @@ public class Fawe { SessionManager.inject(); // Faster custom session saving + Memory improvements Request.inject(); // Custom pattern extent // Commands + BiomeCommands.inject(); // Translations + Optimizations + ChunkCommands.inject(); // Translations + Optimizations + GenerationCommands.inject(); // Translations + Optimizations + SnapshotCommands.inject(); // Translations + Optimizations + SnapshotUtilCommands.inject(); // Translations + Optimizations + SuperPickaxeCommands.inject(); // Translations + Optimizations + UtilityCommands.inject(); // Translations + Optimizations + WorldEditCommands.inject(); // Translations + Optimizations BrushCommands.inject(); // Translations + heightmap ToolCommands.inject(); // Translations + inspect ClipboardCommands.inject(); // Translations + lazycopy + paste optimizations diff --git a/core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java new file mode 100644 index 00000000..58fa5b0a --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java @@ -0,0 +1,213 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command; + +import com.boydti.fawe.config.BBC; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.minecraft.util.commands.Logging; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.function.FlatRegionFunction; +import com.sk89q.worldedit.function.FlatRegionMaskingFilter; +import com.sk89q.worldedit.function.biome.BiomeReplace; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.mask.Mask2D; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.function.visitor.FlatRegionVisitor; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.FlatRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.regions.Regions; +import com.sk89q.worldedit.util.command.binding.Switch; +import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.BiomeData; +import com.sk89q.worldedit.world.registry.BiomeRegistry; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION; + +/** + * Implements biome-related commands such as "/biomelist". + */ +public class BiomeCommands { + + private final WorldEdit worldEdit; + + /** + * Create a new instance. + * + * @param worldEdit reference to WorldEdit + */ + public BiomeCommands(WorldEdit worldEdit) { + checkNotNull(worldEdit); + this.worldEdit = worldEdit; + } + + @Command( + aliases = { "biomelist", "biomels" }, + usage = "[page]", + desc = "Gets all biomes available.", + max = 1 + ) + @CommandPermissions("worldedit.biome.list") + public void biomeList(Player player, CommandContext args) throws WorldEditException { + int page; + int offset; + int count = 0; + + if (args.argsLength() == 0 || (page = args.getInteger(0)) < 2) { + page = 1; + offset = 0; + } else { + offset = (page - 1) * 19; + } + + BiomeRegistry biomeRegistry = player.getWorld().getWorldData().getBiomeRegistry(); + List biomes = biomeRegistry.getBiomes(); + int totalPages = biomes.size() / 19 + 1; + player.print(BBC.getPrefix() + "Available Biomes (page " + page + "/" + totalPages + ") :"); + for (BaseBiome biome : biomes) { + if (offset > 0) { + offset--; + } else { + BiomeData data = biomeRegistry.getData(biome); + if (data != null) { + player.print(BBC.getPrefix() + " " + data.getName()); + if (++count == 19) { + break; + } + } else { + player.print(BBC.getPrefix() + " "); + } + } + } + } + + @Command( + aliases = { "biomeinfo" }, + flags = "pt", + desc = "Get the biome of the targeted block.", + help = + "Get the biome of the block.\n" + + "By default use all the blocks contained in your selection.\n" + + "-t use the block you are looking at.\n" + + "-p use the block you are currently in", + max = 0 + ) + @CommandPermissions("worldedit.biome.info") + public void biomeInfo(Player player, LocalSession session, CommandContext args) throws WorldEditException { + BiomeRegistry biomeRegistry = player.getWorld().getWorldData().getBiomeRegistry(); + Set biomes = new HashSet(); + String qualifier; + + if (args.hasFlag('t')) { + Vector blockPosition = player.getBlockTrace(300); + if (blockPosition == null) { + player.printError("No block in sight!"); + return; + } + + BaseBiome biome = player.getWorld().getBiome(blockPosition.toVector2D()); + biomes.add(biome); + + qualifier = "at line of sight point"; + } else if (args.hasFlag('p')) { + BaseBiome biome = player.getWorld().getBiome(player.getPosition().toVector2D()); + biomes.add(biome); + + qualifier = "at your position"; + } else { + World world = player.getWorld(); + Region region = session.getSelection(world); + + if (region instanceof FlatRegion) { + for (Vector2D pt : ((FlatRegion) region).asFlatRegion()) { + biomes.add(world.getBiome(pt)); + } + } else { + for (Vector pt : region) { + biomes.add(world.getBiome(pt.toVector2D())); + } + } + + qualifier = "in your selection"; + } + + player.print(biomes.size() != 1 ? "Biomes " + qualifier + ":" : "Biome " + qualifier + ":"); + for (BaseBiome biome : biomes) { + BiomeData data = biomeRegistry.getData(biome); + if (data != null) { + player.print(BBC.getPrefix() + " " + data.getName()); + } else { + player.print(BBC.getPrefix() + " "); + } + } + } + + @Command( + aliases = { "/setbiome" }, + usage = "", + flags = "p", + desc = "Sets the biome of the player's current block or region.", + help = + "Set the biome of the region.\n" + + "By default use all the blocks contained in your selection.\n" + + "-p use the block you are currently in" + ) + @Logging(REGION) + @CommandPermissions("worldedit.biome.set") + public void setBiome(Player player, LocalSession session, EditSession editSession, BaseBiome target, @Switch('p') boolean atPosition) throws WorldEditException { + World world = player.getWorld(); + Region region; + Mask mask = editSession.getMask(); + Mask2D mask2d = mask != null ? mask.toMask2D() : null; + + if (atPosition) { + region = new CuboidRegion(player.getPosition(), player.getPosition()); + } else { + region = session.getSelection(world); + } + + FlatRegionFunction replace = new BiomeReplace(editSession, target); + if (mask2d != null) { + replace = new FlatRegionMaskingFilter(mask2d, replace); + } + FlatRegionVisitor visitor = new FlatRegionVisitor(Regions.asFlatRegion(region), replace); + Operations.completeLegacy(visitor); + + player.print(BBC.getPrefix() + "Biomes were changed in " + visitor.getAffected() + " columns. You may have to rejoin your game (or close and reopen your world) to see a change."); + } + + public static Class inject() { + return BiomeCommands.class; + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index f5aa694a..6e41332b 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -95,7 +95,7 @@ public class BrushCommands { max = 1 ) @CommandPermissions("worldedit.brush.blendball") - public void blendBallBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius) throws WorldEditException { + public void blendBallBrush(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); BrushTool tool = session.getBrushTool(player.getItemInHand()); tool.setSize(radius); @@ -112,7 +112,7 @@ public class BrushCommands { max = 1 ) @CommandPermissions("worldedit.brush.erode") - public void erodeBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius) throws WorldEditException { + public void erodeBrush(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand()); tool.setSize(radius); @@ -154,7 +154,7 @@ public class BrushCommands { max = 2 ) @CommandPermissions("worldedit.brush.line") - public void lineBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('f') boolean flat) throws WorldEditException { + public void lineBrush(Player player, LocalSession session, Pattern fill, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('f') boolean flat) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand()); tool.setFill(fill); @@ -172,7 +172,7 @@ public class BrushCommands { max = 2 ) @CommandPermissions("worldedit.brush.spline") - public void splineBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("25") double radius) throws WorldEditException { + public void splineBrush(Player player, LocalSession session, Pattern fill, @Optional("25") double radius) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand()); tool.setFill(fill); @@ -193,7 +193,7 @@ public class BrushCommands { max = 2 ) @CommandPermissions("worldedit.brush.sphere") - public void sphereBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("2") double radius, @Switch('h') boolean hollow) throws WorldEditException { + public void sphereBrush(Player player, LocalSession session, Pattern fill, @Optional("2") double radius, @Switch('h') boolean hollow) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); BrushTool tool = session.getBrushTool(player.getItemInHand()); @@ -228,7 +228,7 @@ public class BrushCommands { max = 3 ) @CommandPermissions("worldedit.brush.cylinder") - public void cylinderBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, + public void cylinderBrush(Player player, LocalSession session, Pattern fill, @Optional("2") double radius, @Optional("1") int height, @Switch('h') boolean hollow) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); worldEdit.checkMaxBrushRadius(height); @@ -257,7 +257,7 @@ public class BrushCommands { "stood relative to the copied area when you copied it." ) @CommandPermissions("worldedit.brush.clipboard") - public void clipboardBrush(Player player, LocalSession session, EditSession editSession, @Switch('a') boolean ignoreAir, @Switch('p') boolean usingOrigin) throws WorldEditException { + public void clipboardBrush(Player player, LocalSession session, @Switch('a') boolean ignoreAir, @Switch('p') boolean usingOrigin) throws WorldEditException { ClipboardHolder holder = session.getClipboard(); Clipboard clipboard = holder.getClipboard(); @@ -334,7 +334,7 @@ public class BrushCommands { max = 1 ) @CommandPermissions("worldedit.brush.gravity") - public void gravityBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius, @Switch('h') boolean fromMaxY) throws WorldEditException { + public void gravityBrush(Player player, LocalSession session, @Optional("5") double radius, @Switch('h') boolean fromMaxY) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); BrushTool tool = session.getBrushTool(player.getItemInHand()); @@ -354,7 +354,7 @@ public class BrushCommands { max = 4 ) @CommandPermissions("worldedit.brush.height") - public void heightBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale) throws WorldEditException { + public void heightBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); File file = new File(Fawe.imp().getDirectory(), "heightmap" + File.separator + (filename.endsWith(".png") ? filename : filename + ".png")); BrushTool tool = session.getBrushTool(player.getItemInHand()); @@ -378,7 +378,7 @@ public class BrushCommands { max = 1 ) @CommandPermissions("worldedit.brush.copy") - public void copy(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius) throws WorldEditException { + public void copy(Player player, LocalSession session, @Optional("5") double radius) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand()); tool.setSize(radius); @@ -396,7 +396,7 @@ public class BrushCommands { max = 99 ) @CommandPermissions("worldedit.brush.command") - public void command(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius, CommandContext args) throws WorldEditException { + public void command(Player player, LocalSession session, @Optional("5") double radius, CommandContext args) throws WorldEditException { BrushTool tool = session.getBrushTool(player.getItemInHand()); String cmd = args.getJoinedStrings(1); tool.setBrush(new CommandBrush(player, tool, cmd, radius), "worldedit.brush.copy"); @@ -423,7 +423,7 @@ public class BrushCommands { max = 1 ) @CommandPermissions("worldedit.brush.butcher") - public void butcherBrush(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void butcherBrush(Player player, LocalSession session, CommandContext args) throws WorldEditException { LocalConfiguration config = worldEdit.getConfiguration(); double radius = args.argsLength() > 0 ? args.getDouble(0) : 5; diff --git a/core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java new file mode 100644 index 00000000..ecd1d45c --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java @@ -0,0 +1,183 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command; + +import com.boydti.fawe.config.BBC; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.minecraft.util.commands.Logging; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.math.MathUtils; +import com.sk89q.worldedit.world.storage.LegacyChunkStore; +import com.sk89q.worldedit.world.storage.McRegionChunkStore; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION; + +/** + * Commands for working with chunks. + */ +public class ChunkCommands { + + private final WorldEdit worldEdit; + + public ChunkCommands(WorldEdit worldEdit) { + checkNotNull(worldEdit); + this.worldEdit = worldEdit; + } + + @Command( + aliases = { "chunkinfo" }, + usage = "", + desc = "Get information about the chunk that you are inside", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.chunkinfo") + public void chunkInfo(Player player, LocalSession session, CommandContext args) throws WorldEditException { + Vector pos = player.getBlockIn(); + int chunkX = (int) Math.floor(pos.getBlockX() / 16.0); + int chunkZ = (int) Math.floor(pos.getBlockZ() / 16.0); + + String folder1 = Integer.toString(MathUtils.divisorMod(chunkX, 64), 36); + String folder2 = Integer.toString(MathUtils.divisorMod(chunkZ, 64), 36); + String filename = "c." + Integer.toString(chunkX, 36) + + "." + Integer.toString(chunkZ, 36) + ".dat"; + + player.print(BBC.getPrefix() + "Chunk: " + chunkX + ", " + chunkZ); + player.print(BBC.getPrefix() + "Old format: " + folder1 + "/" + folder2 + "/" + filename); + player.print(BBC.getPrefix() + "McRegion: region/" + McRegionChunkStore.getFilename( + new Vector2D(chunkX, chunkZ))); + } + + @Command( + aliases = { "listchunks" }, + usage = "", + desc = "List chunks that your selection includes", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.listchunks") + public void listChunks(Player player, LocalSession session, CommandContext args) throws WorldEditException { + Set chunks = session.getSelection(player.getWorld()).getChunks(); + + for (Vector2D chunk : chunks) { + player.print(BBC.getPrefix() + LegacyChunkStore.getFilename(chunk)); + } + } + + @Command( + aliases = { "delchunks" }, + usage = "", + desc = "Delete chunks that your selection includes", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.delchunks") + @Logging(REGION) + public void deleteChunks(Player player, LocalSession session, CommandContext args) throws WorldEditException { + player.print(BBC.getPrefix() + "Note that this command does not yet support the mcregion format."); + LocalConfiguration config = worldEdit.getConfiguration(); + + Set chunks = session.getSelection(player.getWorld()).getChunks(); + FileOutputStream out = null; + + if (config.shellSaveType == null) { + player.printError("Shell script type must be configured: 'bat' or 'bash' expected."); + } else if (config.shellSaveType.equalsIgnoreCase("bat")) { + try { + out = new FileOutputStream("worldedit-delchunks.bat"); + OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8"); + writer.write("@ECHO off\r\n"); + writer.write("ECHO This batch file was generated by WorldEdit.\r\n"); + writer.write("ECHO It contains a list of chunks that were in the selected region\r\n"); + writer.write("ECHO at the time that the /delchunks command was used. Run this file\r\n"); + writer.write("ECHO in order to delete the chunk files listed in this file.\r\n"); + writer.write("ECHO.\r\n"); + writer.write("PAUSE\r\n"); + + for (Vector2D chunk : chunks) { + String filename = LegacyChunkStore.getFilename(chunk); + writer.write("ECHO " + filename + "\r\n"); + writer.write("DEL \"world/" + filename + "\"\r\n"); + } + + writer.write("ECHO Complete.\r\n"); + writer.write("PAUSE\r\n"); + writer.close(); + player.print(BBC.getPrefix() + "worldedit-delchunks.bat written. Run it when no one is near the region."); + } catch (IOException e) { + player.printError("Error occurred: " + e.getMessage()); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException ignored) { } + } + } + } else if (config.shellSaveType.equalsIgnoreCase("bash")) { + try { + out = new FileOutputStream("worldedit-delchunks.sh"); + OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8"); + writer.write("#!/bin/bash\n"); + writer.write("echo This shell file was generated by WorldEdit.\n"); + writer.write("echo It contains a list of chunks that were in the selected region\n"); + writer.write("echo at the time that the /delchunks command was used. Run this file\n"); + writer.write("echo in order to delete the chunk files listed in this file.\n"); + writer.write("echo\n"); + writer.write("read -p \"Press any key to continue...\"\n"); + + for (Vector2D chunk : chunks) { + String filename = LegacyChunkStore.getFilename(chunk); + writer.write("echo " + filename + "\n"); + writer.write("rm \"world/" + filename + "\"\n"); + } + + writer.write("echo Complete.\n"); + writer.write("read -p \"Press any key to continue...\"\n"); + writer.close(); + player.print(BBC.getPrefix() + "worldedit-delchunks.sh written. Run it when no one is near the region."); + player.print(BBC.getPrefix() + "You will have to chmod it to be executable."); + } catch (IOException e) { + player.printError("Error occurred: " + e.getMessage()); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException ignored) { + } + } + } + } else { + player.printError(BBC.getPrefix() + "Shell script type must be configured: 'bat' or 'bash' expected."); + } + } + + public static Class inject() { + return ChunkCommands.class; + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index 443c7a3f..e5a37fa1 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -103,7 +103,7 @@ public class ClipboardCommands { max = 0 ) @CommandPermissions("worldedit.clipboard.lazycopy") - public void lazyCopy(Player player, LocalSession session, final EditSession editSession, + public void lazyCopy(Player player, LocalSession session, EditSession editSession, @Selection final Region region, @Switch('e') boolean copyEntities, @Switch('m') Mask mask) throws WorldEditException { @@ -262,7 +262,7 @@ public class ClipboardCommands { ) @CommandPermissions("worldedit.clipboard.paste") @Logging(PLACEMENT) - public void paste(Player player, LocalSession session, final EditSession editSession, + public void paste(Player player, LocalSession session, EditSession editSession, @Switch('a') boolean ignoreAirBlocks, @Switch('o') boolean atOrigin, @Switch('s') boolean selectPasted) throws WorldEditException { ClipboardHolder holder = session.getClipboard(); @@ -415,7 +415,7 @@ public class ClipboardCommands { max = 1 ) @CommandPermissions("worldedit.clipboard.flip") - public void flip(Player player, LocalSession session, EditSession editSession, + public void flip(Player player, LocalSession session, @Optional(Direction.AIM) @Direction Vector direction) throws WorldEditException { ClipboardHolder holder = session.getClipboard(); Clipboard clipboard = holder.getClipboard(); diff --git a/core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java b/core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java index 47d31b36..78ebf048 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java @@ -48,7 +48,7 @@ public class GeneralCommands { max = 1 ) @CommandPermissions("worldedit.limit") - public void limit(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void limit(Player player, LocalSession session, CommandContext args) throws WorldEditException { LocalConfiguration config = worldEdit.getConfiguration(); boolean mayDisable = player.hasPermission("worldedit.limit.unrestricted"); @@ -78,7 +78,7 @@ public class GeneralCommands { max = 1 ) @CommandPermissions("worldedit.fast") - public void fast(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void fast(Player player, LocalSession session, CommandContext args) throws WorldEditException { String newState = args.getString(0, null); if (session.hasFastMode()) { @@ -156,7 +156,7 @@ public class GeneralCommands { max = -1 ) @CommandPermissions("worldedit.global-trasnform") - public void gtransform(Player player, LocalSession session, EditSession editSession, @Optional CommandContext context) throws WorldEditException { + public void gtransform(Player player, EditSession editSession, LocalSession session, @Optional CommandContext context) throws WorldEditException { if (context == null || context.argsLength() == 0) { session.setTransform(null); BBC.TRANSFORM_DISABLED.send(player); @@ -179,7 +179,7 @@ public class GeneralCommands { min = 0, max = 0 ) - public void togglePlace(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void togglePlace(Player player, LocalSession session, CommandContext args) throws WorldEditException { if (session.togglePlacementPosition()) { player.print(BBC.getPrefix() + "Now placing at pos #1."); @@ -213,7 +213,7 @@ public class GeneralCommands { ItemType type = ItemType.fromID(id); if (type != null) { - actor.print("#" + type.getID() + " (" + type.getName() + ")"); + actor.print(BBC.getPrefix() + "#" + type.getID() + " (" + type.getName() + ")"); } else { actor.printError("No item found by ID " + id); } @@ -228,21 +228,21 @@ public class GeneralCommands { } if (!blocksOnly && !itemsOnly) { - actor.print("Searching for: " + query); + actor.print(BBC.getPrefix() + "Searching for: " + query); } else if (blocksOnly && itemsOnly) { actor.printError("You cannot use both the 'b' and 'i' flags simultaneously."); return; } else if (blocksOnly) { - actor.print("Searching for blocks: " + query); + actor.print(BBC.getPrefix() + "Searching for blocks: " + query); } else { - actor.print("Searching for items: " + query); + actor.print(BBC.getPrefix() + "Searching for items: " + query); } int found = 0; for (ItemType type : ItemType.values()) { if (found >= 15) { - actor.print("Too many results!"); + actor.print(BBC.getPrefix() + "Too many results!"); break; } @@ -256,7 +256,7 @@ public class GeneralCommands { for (String alias : type.getAliases()) { if (alias.contains(query)) { - actor.print("#" + type.getID() + " (" + type.getName() + ")"); + actor.print(BBC.getPrefix() + "#" + type.getID() + " (" + type.getName() + ")"); ++found; break; } diff --git a/core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java new file mode 100644 index 00000000..27a13d37 --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -0,0 +1,386 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command; + +import com.boydti.fawe.config.BBC; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.minecraft.util.commands.Logging; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.function.pattern.Patterns; +import com.sk89q.worldedit.internal.annotation.Selection; +import com.sk89q.worldedit.internal.expression.ExpressionException; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.TreeGenerator; +import com.sk89q.worldedit.util.TreeGenerator.TreeType; +import com.sk89q.worldedit.util.command.binding.Range; +import com.sk89q.worldedit.util.command.binding.Switch; +import com.sk89q.worldedit.util.command.binding.Text; +import com.sk89q.worldedit.util.command.parametric.Optional; +import com.sk89q.worldedit.world.biome.BaseBiome; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.sk89q.minecraft.util.commands.Logging.LogMode.*; + +/** + * Commands for the generation of shapes and other objects. + */ +public class GenerationCommands { + + private final WorldEdit worldEdit; + + /** + * Create a new instance. + * + * @param worldEdit reference to WorldEdit + */ + public GenerationCommands(WorldEdit worldEdit) { + checkNotNull(worldEdit); + this.worldEdit = worldEdit; + } + + @Command( + aliases = { "/hcyl" }, + usage = " [,] [height]", + desc = "Generates a hollow cylinder.", + help = + "Generates a hollow cylinder.\n" + + "By specifying 2 radii, separated by a comma,\n" + + "you can generate elliptical cylinders.\n" + + "The 1st radius is north/south, the 2nd radius is east/west.", + min = 2, + max = 3 + ) + @CommandPermissions("worldedit.generation.cylinder") + @Logging(PLACEMENT) + public void hcyl(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("1") int height) throws WorldEditException { + cyl(player, session, editSession, pattern, radiusString, height, true); + } + + @Command( + aliases = { "/cyl" }, + usage = " [,] [height]", + flags = "h", + desc = "Generates a cylinder.", + help = + "Generates a cylinder.\n" + + "By specifying 2 radii, separated by a comma,\n" + + "you can generate elliptical cylinders.\n" + + "The 1st radius is north/south, the 2nd radius is east/west.", + min = 2, + max = 3 + ) + @CommandPermissions("worldedit.generation.cylinder") + @Logging(PLACEMENT) + public void cyl(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("1") int height, @Switch('h') boolean hollow) throws WorldEditException { + String[] radii = radiusString.split(","); + final double radiusX, radiusZ; + switch (radii.length) { + case 1: + radiusX = radiusZ = Math.max(1, Double.parseDouble(radii[0])); + break; + + case 2: + radiusX = Math.max(1, Double.parseDouble(radii[0])); + radiusZ = Math.max(1, Double.parseDouble(radii[1])); + break; + + default: + player.printError("You must either specify 1 or 2 radius values."); + return; + } + + worldEdit.checkMaxRadius(radiusX); + worldEdit.checkMaxRadius(radiusZ); + worldEdit.checkMaxRadius(height); + + Vector pos = session.getPlacementPosition(player); + int affected = editSession.makeCylinder(pos, Patterns.wrap(pattern), radiusX, radiusZ, height, !hollow); + player.print(BBC.getPrefix() + affected + " block(s) have been created."); + } + + @Command( + aliases = { "/hsphere" }, + usage = " [,,] [raised?]", + desc = "Generates a hollow sphere.", + help = + "Generates a hollow sphere.\n" + + "By specifying 3 radii, separated by commas,\n" + + "you can generate an ellipsoid. The order of the ellipsoid radii\n" + + "is north/south, up/down, east/west.", + min = 2, + max = 3 + ) + @CommandPermissions("worldedit.generation.sphere") + @Logging(PLACEMENT) + public void hsphere(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("false") boolean raised) throws WorldEditException { + sphere(player, session, editSession, pattern, radiusString, raised, true); + } + + @Command( + aliases = { "/sphere" }, + usage = " [,,] [raised?]", + flags = "h", + desc = "Generates a filled sphere.", + help = + "Generates a filled sphere.\n" + + "By specifying 3 radii, separated by commas,\n" + + "you can generate an ellipsoid. The order of the ellipsoid radii\n" + + "is north/south, up/down, east/west.", + min = 2, + max = 3 + ) + @CommandPermissions("worldedit.generation.sphere") + @Logging(PLACEMENT) + public void sphere(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("false") boolean raised, @Switch('h') boolean hollow) throws WorldEditException { + String[] radii = radiusString.split(","); + final double radiusX, radiusY, radiusZ; + switch (radii.length) { + case 1: + radiusX = radiusY = radiusZ = Math.max(1, Double.parseDouble(radii[0])); + break; + + case 3: + radiusX = Math.max(1, Double.parseDouble(radii[0])); + radiusY = Math.max(1, Double.parseDouble(radii[1])); + radiusZ = Math.max(1, Double.parseDouble(radii[2])); + break; + + default: + player.printError("You must either specify 1 or 3 radius values."); + return; + } + + worldEdit.checkMaxRadius(radiusX); + worldEdit.checkMaxRadius(radiusY); + worldEdit.checkMaxRadius(radiusZ); + + Vector pos = session.getPlacementPosition(player); + if (raised) { + pos = pos.add(0, radiusY, 0); + } + + int affected = editSession.makeSphere(pos, Patterns.wrap(pattern), radiusX, radiusY, radiusZ, !hollow); + player.findFreePosition(); + player.print(BBC.getPrefix() + affected + " block(s) have been created."); + } + + @Command( + aliases = { "forestgen" }, + usage = "[size] [type] [density]", + desc = "Generate a forest", + min = 0, + max = 3 + ) + @CommandPermissions("worldedit.generation.forest") + @Logging(POSITION) + @SuppressWarnings("deprecation") + public void forestGen(Player player, LocalSession session, EditSession editSession, @Optional("10") int size, @Optional("tree") TreeType type, @Optional("5") double density) throws WorldEditException { + density = density / 100; + int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, new TreeGenerator(type)); + player.print(BBC.getPrefix() + affected + " trees created."); + } + + @Command( + aliases = { "pumpkins" }, + usage = "[size]", + desc = "Generate pumpkin patches", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.generation.pumpkins") + @Logging(POSITION) + public void pumpkins(Player player, LocalSession session, EditSession editSession, @Optional("10") int apothem) throws WorldEditException { + int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), apothem); + player.print(BBC.getPrefix() + affected + " pumpkin patches created."); + } + + @Command( + aliases = { "/hpyramid" }, + usage = " ", + desc = "Generate a hollow pyramid", + min = 2, + max = 2 + ) + @CommandPermissions("worldedit.generation.pyramid") + @Logging(PLACEMENT) + public void hollowPyramid(Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size) throws WorldEditException { + pyramid(player, session, editSession, pattern, size, true); + } + + @Command( + aliases = { "/pyramid" }, + usage = " ", + flags = "h", + desc = "Generate a filled pyramid", + min = 2, + max = 2 + ) + @CommandPermissions("worldedit.generation.pyramid") + @Logging(PLACEMENT) + public void pyramid(Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size, @Switch('h') boolean hollow) throws WorldEditException { + Vector pos = session.getPlacementPosition(player); + worldEdit.checkMaxRadius(size); + int affected = editSession.makePyramid(pos, Patterns.wrap(pattern), size, !hollow); + player.findFreePosition(); + player.print(BBC.getPrefix() + affected + " block(s) have been created."); + } + + @Command( + aliases = { "/generate", "/gen", "/g" }, + usage = " ", + desc = "Generates a shape according to a formula.", + help = + "Generates a shape according to a formula that is expected to\n" + + "return positive numbers (true) if the point is inside the shape\n" + + "Optionally set type/data to the desired block.\n" + + "Flags:\n" + + " -h to generate a hollow shape\n" + + " -r to use raw minecraft coordinates\n" + + " -o is like -r, except offset from placement.\n" + + " -c is like -r, except offset selection center.\n" + + "If neither -r nor -o is given, the selection is mapped to -1..1\n" + + "See also tinyurl.com/wesyntax.", + flags = "hroc", + min = 2, + max = -1 + ) + @CommandPermissions("worldedit.generation.shape") + @Logging(ALL) + public void generate(Player player, LocalSession session, EditSession editSession, + @Selection Region region, + Pattern pattern, + @Text String expression, + @Switch('h') boolean hollow, + @Switch('r') boolean useRawCoords, + @Switch('o') boolean offset, + @Switch('c') boolean offsetCenter) throws WorldEditException { + + final Vector zero; + Vector unit; + + if (useRawCoords) { + zero = Vector.ZERO; + unit = Vector.ONE; + } else if (offset) { + zero = session.getPlacementPosition(player); + unit = Vector.ONE; + } else if (offsetCenter) { + final Vector min = region.getMinimumPoint(); + final Vector max = region.getMaximumPoint(); + + zero = max.add(min).multiply(0.5); + unit = Vector.ONE; + } else { + final Vector min = region.getMinimumPoint(); + final Vector max = region.getMaximumPoint(); + + zero = max.add(min).multiply(0.5); + unit = max.subtract(zero); + + if (unit.getX() == 0) unit = unit.setX(1.0); + if (unit.getY() == 0) unit = unit.setY(1.0); + if (unit.getZ() == 0) unit = unit.setZ(1.0); + } + + try { + final int affected = editSession.makeShape(region, zero, unit, Patterns.wrap(pattern), expression, hollow); + player.findFreePosition(); + player.print(BBC.getPrefix() + affected + " block(s) have been created."); + } catch (ExpressionException e) { + player.printError(e.getMessage()); + } + } + + @Command( + aliases = { "/generatebiome", "/genbiome", "/gb" }, + usage = " ", + desc = "Sets biome according to a formula.", + help = + "Generates a shape according to a formula that is expected to\n" + + "return positive numbers (true) if the point is inside the shape\n" + + "Sets the biome of blocks in that shape.\n" + + "Flags:\n" + + " -h to generate a hollow shape\n" + + " -r to use raw minecraft coordinates\n" + + " -o is like -r, except offset from placement.\n" + + " -c is like -r, except offset selection center.\n" + + "If neither -r nor -o is given, the selection is mapped to -1..1\n" + + "See also tinyurl.com/wesyntax.", + flags = "hroc", + min = 2, + max = -1 + ) + @CommandPermissions({"worldedit.generation.shape", "worldedit.biome.set"}) + @Logging(ALL) + public void generateBiome(Player player, LocalSession session, EditSession editSession, + @Selection Region region, + BaseBiome target, + @Text String expression, + @Switch('h') boolean hollow, + @Switch('r') boolean useRawCoords, + @Switch('o') boolean offset, + @Switch('c') boolean offsetCenter) throws WorldEditException { + final Vector zero; + Vector unit; + + if (useRawCoords) { + zero = Vector.ZERO; + unit = Vector.ONE; + } else if (offset) { + zero = session.getPlacementPosition(player); + unit = Vector.ONE; + } else if (offsetCenter) { + final Vector min = region.getMinimumPoint(); + final Vector max = region.getMaximumPoint(); + + zero = max.add(min).multiply(0.5); + unit = Vector.ONE; + } else { + final Vector min = region.getMinimumPoint(); + final Vector max = region.getMaximumPoint(); + + zero = max.add(min).multiply(0.5); + unit = max.subtract(zero); + + if (unit.getX() == 0) unit = unit.setX(1.0); + if (unit.getY() == 0) unit = unit.setY(1.0); + if (unit.getZ() == 0) unit = unit.setZ(1.0); + } + + try { + final int affected = editSession.makeBiomeShape(region, zero, unit, target, expression, hollow); + player.findFreePosition(); + player.print(BBC.getPrefix() + "" + affected + " columns affected."); + } catch (ExpressionException e) { + player.printError(e.getMessage()); + } + } + + public static Class inject() { + return GenerationCommands.class; + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java b/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java index 9a4871cd..043872ed 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java @@ -194,7 +194,7 @@ public class HistoryCommands { max = 2 ) @CommandPermissions("worldedit.history.undo") - public void undo(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void undo(Player player, LocalSession session, CommandContext args) throws WorldEditException { int times = Math.max(1, args.getInteger(0, 1)); for (int i = 0; i < times; ++i) { EditSession undone; @@ -227,7 +227,7 @@ public class HistoryCommands { max = 2 ) @CommandPermissions("worldedit.history.redo") - public void redo(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void redo(Player player, LocalSession session, CommandContext args) throws WorldEditException { int times = Math.max(1, args.getInteger(0, 1)); @@ -261,7 +261,7 @@ public class HistoryCommands { max = 0 ) @CommandPermissions("worldedit.history.clear") - public void clearHistory(Player player, LocalSession session, EditSession editSession) throws WorldEditException { + public void clearHistory(Player player, LocalSession session) throws WorldEditException { session.clearHistory(); BBC.COMMAND_HISTORY_CLEAR.send(player); } diff --git a/core/src/main/java/com/sk89q/worldedit/command/NavigationCommands.java b/core/src/main/java/com/sk89q/worldedit/command/NavigationCommands.java index 30071fc2..1811fdd6 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/NavigationCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/NavigationCommands.java @@ -26,7 +26,6 @@ import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.Logging; -import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld; @@ -130,7 +129,7 @@ public class NavigationCommands { ) @CommandPermissions("worldedit.navigation.ceiling") @Logging(POSITION) - public void ceiling(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void ceiling(Player player, LocalSession session, CommandContext args) throws WorldEditException { final int clearance = args.argsLength() > 0 ? Math.max(0, args.getInteger(0)) : 0; @@ -151,7 +150,7 @@ public class NavigationCommands { max = 0 ) @CommandPermissions("worldedit.navigation.thru.command") - public void thru(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void thru(Player player, LocalSession session, CommandContext args) throws WorldEditException { if (player.passThroughForwardWall(6)) { BBC.WHOOSH.send(player); } else { @@ -168,7 +167,7 @@ public class NavigationCommands { max = 1 ) @CommandPermissions("worldedit.navigation.jumpto.command") - public void jumpTo(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void jumpTo(Player player, LocalSession session, CommandContext args) throws WorldEditException { WorldVector pos; if (args.argsLength() == 1) { String arg = args.getString(0); @@ -201,7 +200,7 @@ public class NavigationCommands { ) @CommandPermissions("worldedit.navigation.up") @Logging(POSITION) - public void up(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void up(Player player, LocalSession session, CommandContext args) throws WorldEditException { final int distance = args.getInteger(0); final boolean alwaysGlass = getAlwaysGlass(args); diff --git a/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java index a3e3cdce..bd472987 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -29,8 +29,10 @@ import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.util.MainUtil; +import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.SetQueue; import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.Logging; import com.sk89q.worldedit.EditSession; @@ -69,6 +71,9 @@ import com.sk89q.worldedit.util.command.binding.Range; import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.util.command.binding.Text; import com.sk89q.worldedit.util.command.parametric.Optional; +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.Biomes; +import com.sk89q.worldedit.world.registry.BiomeRegistry; import java.util.ArrayList; import java.util.List; @@ -105,7 +110,7 @@ public class RegionCommands { max = 0 ) @CommandPermissions("worldedit.light.fix") - public void fixlighting(Player player, EditSession editSession) throws WorldEditException { + public void fixlighting(Player player) throws WorldEditException { FawePlayer fp = FawePlayer.wrap(player); final FaweLocation loc = fp.getLocation(); Region selection = fp.getSelection(); @@ -125,7 +130,7 @@ public class RegionCommands { max = 0 ) @CommandPermissions("worldedit.light.fix") - public void getlighting(Player player, EditSession editSession) throws WorldEditException { + public void getlighting(Player player) throws WorldEditException { FawePlayer fp = FawePlayer.wrap(player); final FaweLocation loc = fp.getLocation(); FaweQueue queue = SetQueue.IMP.getNewQueue(loc.world, true, false); @@ -139,7 +144,7 @@ public class RegionCommands { max = 0 ) @CommandPermissions("worldedit.light.remove") - public void removelighting(Player player, EditSession editSession) { + public void removelighting(Player player) { FawePlayer fp = FawePlayer.wrap(player); final FaweLocation loc = fp.getLocation(); Region selection = fp.getSelection(); @@ -159,7 +164,7 @@ public class RegionCommands { max = 1 ) @CommandPermissions("worldedit.light.set") - public void setlighting(Player player, EditSession editSession, @Selection Region region, int value) { + public void setlighting(Player player, @Selection Region region, int value) { FawePlayer fp = FawePlayer.wrap(player); final FaweLocation loc = fp.getLocation(); final int cx = loc.x >> 4; @@ -183,7 +188,7 @@ public class RegionCommands { max = 1 ) @CommandPermissions("worldedit.light.set") - public void setskylighting(Player player, EditSession editSession, @Selection Region region, int value) { + public void setskylighting(Player player, @Selection Region region, int value) { FawePlayer fp = FawePlayer.wrap(player); final FaweLocation loc = fp.getLocation(); final int cx = loc.x >> 4; @@ -312,7 +317,7 @@ public class RegionCommands { ) @CommandPermissions("worldedit.region.set") @Logging(REGION) - public void set(Player player, EditSession editSession, LocalSession session, @Selection Region selection, Pattern to) throws WorldEditException { + public void set(Player player, LocalSession session, EditSession editSession, @Selection Region selection, Pattern to) throws WorldEditException { if (selection instanceof CuboidRegion && editSession.hasFastMode() && to instanceof BlockPattern) { try { CuboidRegion cuboid = (CuboidRegion) selection; @@ -477,7 +482,7 @@ public class RegionCommands { ) @CommandPermissions("worldedit.region.move") @Logging(ORIENTATION_REGION) - public void move(Player player, EditSession editSession, LocalSession session, + public void move(Player player, LocalSession session, EditSession editSession, @Selection Region region, @Optional("1") @Range(min = 1) int count, @Optional(Direction.AIM) @Direction Vector direction, @@ -537,7 +542,7 @@ public class RegionCommands { ) @CommandPermissions("worldedit.region.stack") @Logging(ORIENTATION_REGION) - public void stack(Player player, EditSession editSession, LocalSession session, + public void stack(Player player, LocalSession session, EditSession editSession, @Selection Region region, @Optional("1") @Range(min = 1) int count, @Optional(Direction.AIM) @Direction Vector direction, @@ -564,24 +569,31 @@ public class RegionCommands { @Command( aliases = { "/regen" }, - usage = "", + usage = "[biome] [seed]", desc = "Regenerates the contents of the selection", help = "Regenerates the contents of the current selection.\n" + "This command might affect things outside the selection,\n" + "if they are within the same chunk.", min = 0, - max = 0 + max = 2 ) @CommandPermissions("worldedit.regen") @Logging(REGION) - public void regenerateChunk(Player player, LocalSession session, EditSession editSession, @Selection Region region) throws WorldEditException { + public void regenerateChunk(Player player, LocalSession session, EditSession editSession, @Selection Region region, CommandContext args) throws WorldEditException { Mask mask = session.getMask(); Mask sourceMask = session.getSourceMask(); try { session.setMask((Mask) null); session.setSourceMask((Mask) null); - player.getWorld().regenerate(region, editSession); + BaseBiome biome = null; + if (args.argsLength() >= 1) { + BiomeRegistry biomeRegistry = player.getWorld().getWorldData().getBiomeRegistry(); + List knownBiomes = biomeRegistry.getBiomes(); + biome = Biomes.findBiomeByName(knownBiomes, args.getString(0), biomeRegistry); + } + Long seed = args.argsLength() != 2 || !MathMan.isInteger(args.getString(1)) ? null : Long.parseLong(args.getString(1)); + editSession.regenerate(region, biome, seed); } finally { session.setMask(mask); session.setSourceMask(mask); diff --git a/core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index dce5f286..4a252f91 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -27,7 +27,6 @@ import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandPermissions; -import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; @@ -215,7 +214,7 @@ public class SchematicCommands { @Command(aliases = { "delete", "d" }, usage = "", desc = "Delete a saved schematic", help = "Delete a schematic from the schematic list", min = 1, max = 1) @CommandPermissions("worldedit.schematic.delete") - public void delete(final Player player, final LocalSession session, final EditSession editSession, final CommandContext args) throws WorldEditException { + public void delete(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException { final LocalConfiguration config = this.worldEdit.getConfiguration(); final String filename = args.getString(0); diff --git a/core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java index d490ba3b..666199b6 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java @@ -24,7 +24,6 @@ import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.Logging; -import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; @@ -55,7 +54,7 @@ public class ScriptingCommands { @Command(aliases = { "cs" }, usage = " [args...]", desc = "Execute a CraftScript", min = 1, max = -1) @CommandPermissions("worldedit.scripting.execute") @Logging(ALL) - public void execute(final Player player, final LocalSession session, final EditSession editSession, final CommandContext args) throws WorldEditException { + public void execute(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException { final String[] scriptArgs = args.getSlice(1); final String name = args.getString(0); @@ -78,7 +77,7 @@ public class ScriptingCommands { @Command(aliases = { ".s" }, usage = "[args...]", desc = "Execute last CraftScript", min = 0, max = -1) @CommandPermissions("worldedit.scripting.execute") @Logging(ALL) - public void executeLast(final Player player, final LocalSession session, final EditSession editSession, final CommandContext args) throws WorldEditException { + public void executeLast(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException { final String lastScript = session.getLastScript(); if (!player.hasPermission("worldedit.scripting.execute." + lastScript)) { diff --git a/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index 3f5ae95d..7dd11301 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -88,7 +88,7 @@ public class SelectionCommands { ) @Logging(POSITION) @CommandPermissions("worldedit.selection.pos") - public void pos1(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void pos1(Player player, LocalSession session, CommandContext args) throws WorldEditException { Vector pos; @@ -103,7 +103,7 @@ public class SelectionCommands { } else { pos = player.getBlockIn(); } - pos = pos.clampY(0, editSession.getMaximumPoint().getBlockY()); + pos = pos.clampY(0, player.getWorld().getMaximumPoint().getBlockY()); if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos, ActorSelectorLimits.forActor(player))) { BBC.SELECTOR_ALREADY_SET.send(player); return; @@ -121,7 +121,7 @@ public class SelectionCommands { ) @Logging(POSITION) @CommandPermissions("worldedit.selection.pos") - public void pos2(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void pos2(Player player, LocalSession session, CommandContext args) throws WorldEditException { Vector pos; if (args.argsLength() == 1) { @@ -137,7 +137,7 @@ public class SelectionCommands { } else { pos = player.getBlockIn(); } - pos = pos.clampY(0, editSession.getMaximumPoint().getBlockY()); + pos = pos.clampY(0, player.getWorld().getMaximumPoint().getBlockY()); if (!session.getRegionSelector(player.getWorld()).selectSecondary(pos, ActorSelectorLimits.forActor(player))) { BBC.SELECTOR_ALREADY_SET.send(player); return; @@ -155,7 +155,7 @@ public class SelectionCommands { max = 0 ) @CommandPermissions("worldedit.selection.hpos") - public void hpos1(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void hpos1(Player player, LocalSession session, CommandContext args) throws WorldEditException { Vector pos = player.getBlockTrace(300); @@ -180,7 +180,7 @@ public class SelectionCommands { max = 0 ) @CommandPermissions("worldedit.selection.hpos") - public void hpos2(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void hpos2(Player player, LocalSession session, CommandContext args) throws WorldEditException { Vector pos = player.getBlockTrace(300); @@ -215,7 +215,7 @@ public class SelectionCommands { ) @Logging(POSITION) @CommandPermissions("worldedit.selection.chunk") - public void chunk(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void chunk(Player player, LocalSession session, CommandContext args) throws WorldEditException { final Vector min; final Vector max; final World world = player.getWorld(); @@ -274,7 +274,7 @@ public class SelectionCommands { max = 0 ) @CommandPermissions("worldedit.wand") - public void wand(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void wand(Player player, LocalSession session, CommandContext args) throws WorldEditException { player.giveItem(we.getConfiguration().wandItem, 1); BBC.SELECTION_WAND.send(player); @@ -288,7 +288,7 @@ public class SelectionCommands { max = 0 ) @CommandPermissions("worldedit.wand.toggle") - public void toggleWand(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void toggleWand(Player player, LocalSession session, CommandContext args) throws WorldEditException { session.setToolControl(!session.isToolControlEnabled()); @@ -308,7 +308,7 @@ public class SelectionCommands { ) @Logging(REGION) @CommandPermissions("worldedit.selection.expand") - public void expand(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void expand(Player player, LocalSession session, CommandContext args) throws WorldEditException { // Special syntax (//expand vert) to expand the selection between // sky and bedrock. @@ -400,7 +400,7 @@ public class SelectionCommands { ) @Logging(REGION) @CommandPermissions("worldedit.selection.contract") - public void contract(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void contract(Player player, LocalSession session, CommandContext args) throws WorldEditException { List dirs = new ArrayList(); int change = args.getInteger(0); @@ -474,7 +474,7 @@ public class SelectionCommands { ) @Logging(REGION) @CommandPermissions("worldedit.selection.shift") - public void shift(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void shift(Player player, LocalSession session, CommandContext args) throws WorldEditException { List dirs = new ArrayList(); int change = args.getInteger(0); @@ -521,7 +521,7 @@ public class SelectionCommands { ) @Logging(REGION) @CommandPermissions("worldedit.selection.outset") - public void outset(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void outset(Player player, LocalSession session, CommandContext args) throws WorldEditException { Region region = session.getSelection(player.getWorld()); region.expand(getChangesForEachDir(args)); session.getRegionSelector(player.getWorld()).learnChanges(); @@ -544,7 +544,7 @@ public class SelectionCommands { ) @Logging(REGION) @CommandPermissions("worldedit.selection.inset") - public void inset(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void inset(Player player, LocalSession session, CommandContext args) throws WorldEditException { Region region = session.getSelection(player.getWorld()); region.contract(getChangesForEachDir(args)); session.getRegionSelector(player.getWorld()).learnChanges(); @@ -580,7 +580,7 @@ public class SelectionCommands { max = 0 ) @CommandPermissions("worldedit.selection.size") - public void size(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void size(Player player, LocalSession session, CommandContext args) throws WorldEditException { if (args.hasFlag('c')) { ClipboardHolder holder = session.getClipboard(); diff --git a/core/src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java b/core/src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java new file mode 100644 index 00000000..0375209d --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java @@ -0,0 +1,276 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +// $Id$ + +package com.sk89q.worldedit.command; + +import com.boydti.fawe.config.BBC; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.world.snapshot.InvalidSnapshotException; +import com.sk89q.worldedit.world.snapshot.Snapshot; +import com.sk89q.worldedit.world.storage.MissingWorldException; + +import java.io.File; +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.List; +import java.util.logging.Logger; + +/** + * Snapshot commands. + */ +public class SnapshotCommands { + + private static final Logger logger = Logger.getLogger("Minecraft.WorldEdit"); + private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); + + private final WorldEdit we; + + public SnapshotCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "list" }, + usage = "[num]", + desc = "List snapshots", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.snapshots.list") + public void list(Player player, LocalSession session, CommandContext args) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + + if (config.snapshotRepo == null) { + player.printError("Snapshot/backup restore is not configured."); + return; + } + + try { + List snapshots = config.snapshotRepo.getSnapshots(true, player.getWorld().getName()); + + if (!snapshots.isEmpty()) { + + int num = args.argsLength() > 0 ? Math.min(40, Math.max(5, args.getInteger(0))) : 5; + + player.print(BBC.getPrefix() + "Snapshots for world: '" + player.getWorld().getName() + "'"); + for (byte i = 0; i < Math.min(num, snapshots.size()); i++) { + player.print(BBC.getPrefix() + (i + 1) + ". " + snapshots.get(i).getName()); + } + + player.print(BBC.getPrefix() + "Use /snap use [snapshot] or /snap use latest."); + } else { + player.printError("No snapshots are available. See console for details."); + + // Okay, let's toss some debugging information! + File dir = config.snapshotRepo.getDirectory(); + + try { + logger.info("WorldEdit found no snapshots: looked in: " + + dir.getCanonicalPath()); + } catch (IOException e) { + logger.info("WorldEdit found no snapshots: looked in " + + "(NON-RESOLVABLE PATH - does it exist?): " + + dir.getPath()); + } + } + } catch (MissingWorldException ex) { + player.printError("No snapshots were found for this world."); + } + } + + @Command( + aliases = { "use" }, + usage = "", + desc = "Choose a snapshot to use", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.snapshots.restore") + public void use(Player player, LocalSession session, CommandContext args) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + + if (config.snapshotRepo == null) { + player.printError("Snapshot/backup restore is not configured."); + return; + } + + String name = args.getString(0); + + // Want the latest snapshot? + if (name.equalsIgnoreCase("latest")) { + try { + Snapshot snapshot = config.snapshotRepo.getDefaultSnapshot(player.getWorld().getName()); + + if (snapshot != null) { + session.setSnapshot(null); + player.print(BBC.getPrefix() + "Now using newest snapshot."); + } else { + player.printError("No snapshots were found."); + } + } catch (MissingWorldException ex) { + player.printError("No snapshots were found for this world."); + } + } else { + try { + session.setSnapshot(config.snapshotRepo.getSnapshot(name)); + player.print(BBC.getPrefix() + "Snapshot set to: " + name); + } catch (InvalidSnapshotException e) { + player.printError("That snapshot does not exist or is not available."); + } + } + } + + @Command( + aliases = { "sel" }, + usage = "", + desc = "Choose the snapshot based on the list id", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.snapshots.restore") + public void sel(Player player, LocalSession session, CommandContext args) throws WorldEditException { + LocalConfiguration config = we.getConfiguration(); + + if (config.snapshotRepo == null) { + player.printError("Snapshot/backup restore is not configured."); + return; + } + + int index = -1; + try { + index = Integer.parseInt(args.getString(0)); + } catch (NumberFormatException e) { + player.printError("Invalid index, " + args.getString(0) + " is not a valid integer."); + return; + } + + if (index < 1) { + player.printError("Invalid index, must be equal or higher then 1."); + return; + } + + try { + List snapshots = config.snapshotRepo.getSnapshots(true, player.getWorld().getName()); + if (snapshots.size() < index) { + player.printError("Invalid index, must be between 1 and " + snapshots.size() + "."); + return; + } + Snapshot snapshot = snapshots.get(index - 1); + if (snapshot == null) { + player.printError("That snapshot does not exist or is not available."); + return; + } + session.setSnapshot(snapshot); + player.print(BBC.getPrefix() + "Snapshot set to: " + snapshot.getName()); + } catch (MissingWorldException e) { + player.printError("No snapshots were found for this world."); + } + } + + @Command( + aliases = { "before" }, + usage = "", + desc = "Choose the nearest snapshot before a date", + min = 1, + max = -1 + ) + @CommandPermissions("worldedit.snapshots.restore") + public void before(Player player, LocalSession session, CommandContext args) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + + if (config.snapshotRepo == null) { + player.printError("Snapshot/backup restore is not configured."); + return; + } + + Calendar date = session.detectDate(args.getJoinedStrings(0)); + + if (date == null) { + player.printError("Could not detect the date inputted."); + } else { + try { + Snapshot snapshot = config.snapshotRepo.getSnapshotBefore(date, player.getWorld().getName()); + + if (snapshot == null) { + dateFormat.setTimeZone(session.getTimeZone()); + player.printError("Couldn't find a snapshot before " + + dateFormat.format(date.getTime()) + "."); + } else { + session.setSnapshot(snapshot); + player.print(BBC.getPrefix() + "Snapshot set to: " + snapshot.getName()); + } + } catch (MissingWorldException ex) { + player.printError("No snapshots were found for this world."); + } + } + } + + @Command( + aliases = { "after" }, + usage = "", + desc = "Choose the nearest snapshot after a date", + min = 1, + max = -1 + ) + @CommandPermissions("worldedit.snapshots.restore") + public void after(Player player, LocalSession session, CommandContext args) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + + if (config.snapshotRepo == null) { + player.printError("Snapshot/backup restore is not configured."); + return; + } + + Calendar date = session.detectDate(args.getJoinedStrings(0)); + + if (date == null) { + player.printError("Could not detect the date inputted."); + } else { + try { + Snapshot snapshot = config.snapshotRepo.getSnapshotAfter(date, player.getWorld().getName()); + if (snapshot == null) { + dateFormat.setTimeZone(session.getTimeZone()); + player.printError("Couldn't find a snapshot after " + + dateFormat.format(date.getTime()) + "."); + } else { + session.setSnapshot(snapshot); + player.print(BBC.getPrefix() + "Snapshot set to: " + snapshot.getName()); + } + } catch (MissingWorldException ex) { + player.printError("No snapshots were found for this world."); + } + } + } + + public static Class inject() { + return SnapshotCommands.class; + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java b/core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java new file mode 100644 index 00000000..8c50f246 --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java @@ -0,0 +1,159 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command; + +import com.boydti.fawe.config.BBC; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.minecraft.util.commands.Logging; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.DataException; +import com.sk89q.worldedit.world.snapshot.InvalidSnapshotException; +import com.sk89q.worldedit.world.snapshot.Snapshot; +import com.sk89q.worldedit.world.snapshot.SnapshotRestore; +import com.sk89q.worldedit.world.storage.ChunkStore; +import com.sk89q.worldedit.world.storage.MissingWorldException; + +import java.io.File; +import java.io.IOException; +import java.util.logging.Logger; + +import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION; + +public class SnapshotUtilCommands { + + private static final Logger logger = Logger.getLogger("Minecraft.WorldEdit"); + + private final WorldEdit we; + + public SnapshotUtilCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "restore", "/restore" }, + usage = "[snapshot]", + desc = "Restore the selection from a snapshot", + min = 0, + max = 1 + ) + @Logging(REGION) + @CommandPermissions("worldedit.snapshots.restore") + public void restore(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + + if (config.snapshotRepo == null) { + player.printError("Snapshot/backup restore is not configured."); + return; + } + + Region region = session.getSelection(player.getWorld()); + Snapshot snapshot; + + if (args.argsLength() > 0) { + try { + snapshot = config.snapshotRepo.getSnapshot(args.getString(0)); + } catch (InvalidSnapshotException e) { + player.printError("That snapshot does not exist or is not available."); + return; + } + } else { + snapshot = session.getSnapshot(); + } + + // No snapshot set? + if (snapshot == null) { + try { + snapshot = config.snapshotRepo.getDefaultSnapshot(player.getWorld().getName()); + + if (snapshot == null) { + player.printError("No snapshots were found. See console for details."); + + // Okay, let's toss some debugging information! + File dir = config.snapshotRepo.getDirectory(); + + try { + logger.info("WorldEdit found no snapshots: looked in: " + + dir.getCanonicalPath()); + } catch (IOException e) { + logger.info("WorldEdit found no snapshots: looked in " + + "(NON-RESOLVABLE PATH - does it exist?): " + + dir.getPath()); + } + + return; + } + } catch (MissingWorldException ex) { + player.printError("No snapshots were found for this world."); + return; + } + } + + ChunkStore chunkStore = null; + + // Load chunk store + try { + chunkStore = snapshot.getChunkStore(); + player.print(BBC.getPrefix() + "Snapshot '" + snapshot.getName() + "' loaded; now restoring..."); + } catch (DataException e) { + player.printError("Failed to load snapshot: " + e.getMessage()); + return; + } catch (IOException e) { + player.printError("Failed to load snapshot: " + e.getMessage()); + return; + } + + try { + // Restore snapshot + SnapshotRestore restore = new SnapshotRestore(chunkStore, editSession, region); + //player.print(restore.getChunksAffected() + " chunk(s) will be loaded."); + + restore.restore(); + + if (restore.hadTotalFailure()) { + String error = restore.getLastErrorMessage(); + if (error != null) { + player.printError("Errors prevented any blocks from being restored."); + player.printError("Last error: " + error); + } else { + player.printError("No chunks could be loaded. (Bad archive?)"); + } + } else { + player.print(BBC.getPrefix() + String.format("Restored; %d " + + "missing chunks and %d other errors.", + restore.getMissingChunks().size(), + restore.getErrorChunks().size())); + } + } finally { + try { + chunkStore.close(); + } catch (IOException ignored) { + } + } + } + + public static Class inject() { + return SnapshotUtilCommands.class; + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java b/core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java new file mode 100644 index 00000000..1a95eeef --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java @@ -0,0 +1,103 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command; + +import com.boydti.fawe.config.BBC; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.command.tool.AreaPickaxe; +import com.sk89q.worldedit.command.tool.RecursivePickaxe; +import com.sk89q.worldedit.command.tool.SinglePickaxe; +import com.sk89q.worldedit.entity.Player; + +public class SuperPickaxeCommands { + private final WorldEdit we; + + public SuperPickaxeCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "single" }, + usage = "", + desc = "Enable the single block super pickaxe mode", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.superpickaxe") + public void single(Player player, LocalSession session, CommandContext args) throws WorldEditException { + + session.setSuperPickaxe(new SinglePickaxe()); + session.enableSuperPickAxe(); + player.print(BBC.getPrefix() + "Mode changed. Left click with a pickaxe. // to disable."); + } + + @Command( + aliases = { "area" }, + usage = "", + desc = "Enable the area super pickaxe pickaxe mode", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.superpickaxe.area") + public void area(Player player, LocalSession session, CommandContext args) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + int range = args.getInteger(0); + + if (range > config.maxSuperPickaxeSize) { + player.printError("Maximum range: " + config.maxSuperPickaxeSize); + return; + } + + session.setSuperPickaxe(new AreaPickaxe(range)); + session.enableSuperPickAxe(); + player.print(BBC.getPrefix() + "Mode changed. Left click with a pickaxe. // to disable."); + } + + @Command( + aliases = { "recur", "recursive" }, + usage = "", + desc = "Enable the recursive super pickaxe pickaxe mode", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.superpickaxe.recursive") + public void recursive(Player player, LocalSession session, CommandContext args) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + double range = args.getDouble(0); + + if (range > config.maxSuperPickaxeSize) { + player.printError("Maximum range: " + config.maxSuperPickaxeSize); + return; + } + + session.setSuperPickaxe(new RecursivePickaxe(range)); + session.enableSuperPickAxe(); + player.print(BBC.getPrefix() + "Mode changed. Left click with a pickaxe. // to disable."); + } + + public static Class inject() { + return SuperPickaxeCommands.class; + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java index d9f1507c..1d435d09 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java @@ -24,7 +24,6 @@ import com.boydti.fawe.object.brush.InspectBrush; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; -import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; @@ -35,7 +34,7 @@ import com.sk89q.worldedit.command.tool.BlockDataCyler; import com.sk89q.worldedit.command.tool.BlockReplacer; import com.sk89q.worldedit.command.tool.DistanceWand; import com.sk89q.worldedit.command.tool.FloatingTreeRemover; - import com.sk89q.worldedit.command.tool.FloodFillTool; +import com.sk89q.worldedit.command.tool.FloodFillTool; import com.sk89q.worldedit.command.tool.LongRangeBuildTool; import com.sk89q.worldedit.command.tool.QueryTool; import com.sk89q.worldedit.command.tool.TreePlanter; @@ -61,7 +60,7 @@ public class ToolCommands { max = 0 ) @CommandPermissions("worldedit.tool.inspect") - public void inspectBrush(Player player, LocalSession session, EditSession editSession, @Optional("1") double radius) throws WorldEditException { + public void inspectBrush(Player player, LocalSession session, @Optional("1") double radius) throws WorldEditException { session.setTool(player.getItemInHand(), new InspectBrush()); BBC.TOOL_INSPECT.send(player, ItemType.toHeldName(player.getItemInHand())); } @@ -73,7 +72,7 @@ public class ToolCommands { min = 0, max = 0 ) - public void none(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void none(Player player, LocalSession session, CommandContext args) throws WorldEditException { session.setTool(player.getItemInHand(), null); BBC.TOOL_NONE.send(player); } @@ -86,7 +85,7 @@ public class ToolCommands { max = 0 ) @CommandPermissions("worldedit.tool.info") - public void info(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void info(Player player, LocalSession session, CommandContext args) throws WorldEditException { session.setTool(player.getItemInHand(), new QueryTool()); BBC.TOOL_INFO.send(player, ItemType.toHeldName(player.getItemInHand())); } @@ -100,7 +99,7 @@ public class ToolCommands { ) @CommandPermissions("worldedit.tool.tree") @SuppressWarnings("deprecation") - public void tree(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void tree(Player player, LocalSession session, CommandContext args) throws WorldEditException { TreeGenerator.TreeType type = args.argsLength() > 0 ? type = TreeGenerator.lookup(args.getString(0)) @@ -123,7 +122,7 @@ public class ToolCommands { max = 1 ) @CommandPermissions("worldedit.tool.replacer") - public void repl(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void repl(Player player, LocalSession session, CommandContext args) throws WorldEditException { BaseBlock targetBlock = we.getBlock(player, args.getString(0)); session.setTool(player.getItemInHand(), new BlockReplacer(targetBlock)); BBC.TOOL_REPL.send(player, ItemType.toHeldName(player.getItemInHand())); @@ -137,7 +136,7 @@ public class ToolCommands { max = 0 ) @CommandPermissions("worldedit.tool.data-cycler") - public void cycler(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void cycler(Player player, LocalSession session, CommandContext args) throws WorldEditException { session.setTool(player.getItemInHand(), new BlockDataCyler()); BBC.TOOL_CYCLER.send(player, ItemType.toHeldName(player.getItemInHand())); @@ -151,7 +150,7 @@ public class ToolCommands { max = 2 ) @CommandPermissions("worldedit.tool.flood-fill") - public void floodFill(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void floodFill(Player player, LocalSession session, CommandContext args) throws WorldEditException { LocalConfiguration config = we.getConfiguration(); int range = args.getInteger(1); @@ -173,7 +172,7 @@ public class ToolCommands { max = 0 ) @CommandPermissions("worldedit.tool.deltree") - public void deltree(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void deltree(Player player, LocalSession session, CommandContext args) throws WorldEditException { session.setTool(player.getItemInHand(), new FloatingTreeRemover()); BBC.TOOL_DELTREE.send(player, ItemType.toHeldName(player.getItemInHand())); } @@ -186,7 +185,7 @@ public class ToolCommands { max = 0 ) @CommandPermissions("worldedit.tool.farwand") - public void farwand(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void farwand(Player player, LocalSession session, CommandContext args) throws WorldEditException { session.setTool(player.getItemInHand(), new DistanceWand()); BBC.TOOL_FARWAND.send(player, ItemType.toHeldName(player.getItemInHand())); } @@ -199,7 +198,7 @@ public class ToolCommands { max = 2 ) @CommandPermissions("worldedit.tool.lrbuild") - public void longrangebuildtool(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void longrangebuildtool(Player player, LocalSession session, CommandContext args) throws WorldEditException { BaseBlock secondary = we.getBlock(player, args.getString(0)); BaseBlock primary = we.getBlock(player, args.getString(1)); diff --git a/core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java index 752b8c6c..af392378 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java @@ -39,7 +39,7 @@ public class ToolUtilCommands { max = 1 ) @CommandPermissions("worldedit.superpickaxe") - public void togglePickaxe(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void togglePickaxe(Player player, LocalSession session, CommandContext args) throws WorldEditException { String newState = args.getString(0, null); if (session.hasSuperPickAxe()) { if ("on".equals(newState)) { @@ -178,7 +178,7 @@ public class ToolUtilCommands { max = 1 ) @CommandPermissions("worldedit.brush.options.material") - public void material(Player player, LocalSession session, EditSession editSession, Pattern pattern) throws WorldEditException { + public void material(Player player, LocalSession session, Pattern pattern) throws WorldEditException { Tool tool = session.getTool(player.getItemInHand()); if (tool instanceof BrushTool) { ((BrushTool) tool).setMask(null); @@ -196,7 +196,7 @@ public class ToolUtilCommands { max = 1 ) @CommandPermissions("worldedit.brush.options.range") - public void range(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void range(Player player, LocalSession session, CommandContext args) throws WorldEditException { int range = args.getInteger(0); Tool tool = session.getTool(player.getItemInHand()); if (tool instanceof BrushTool) { @@ -215,7 +215,7 @@ public class ToolUtilCommands { max = 1 ) @CommandPermissions("worldedit.brush.options.size") - public void size(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + public void size(Player player, LocalSession session, CommandContext args) throws WorldEditException { int radius = args.getInteger(0); we.checkMaxBrushRadius(radius); diff --git a/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java new file mode 100644 index 00000000..2983d3c1 --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -0,0 +1,681 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command; + +import com.boydti.fawe.config.BBC; +import com.google.common.base.Joiner; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandException; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.minecraft.util.commands.Logging; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.command.util.CreatureButcher; +import com.sk89q.worldedit.command.util.EntityRemover; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.CommandManager; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.function.visitor.EntityVisitor; +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.ExpressionException; +import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; +import com.sk89q.worldedit.patterns.Pattern; +import com.sk89q.worldedit.patterns.SingleBlockPattern; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.CylinderRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.command.CommandCallable; +import com.sk89q.worldedit.util.command.CommandMapping; +import com.sk89q.worldedit.util.command.Dispatcher; +import com.sk89q.worldedit.util.command.PrimaryAliasComparator; +import com.sk89q.worldedit.util.command.binding.Text; +import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; +import com.sk89q.worldedit.util.formatting.Style; +import com.sk89q.worldedit.util.formatting.StyledFragment; +import com.sk89q.worldedit.util.formatting.component.Code; +import com.sk89q.worldedit.util.formatting.component.CommandListBox; +import com.sk89q.worldedit.util.formatting.component.CommandUsageBox; +import com.sk89q.worldedit.world.World; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + + +import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT; + +/** + * Utility commands. + */ +public class UtilityCommands { + + private final WorldEdit we; + + public UtilityCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "/fill" }, + usage = " [depth]", + desc = "Fill a hole", + min = 2, + max = 3 + ) + @CommandPermissions("worldedit.fill") + @Logging(PLACEMENT) + public void fill(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + Pattern pattern = we.getBlockPattern(player, args.getString(0)); + double radius = Math.max(1, args.getDouble(1)); + we.checkMaxRadius(radius); + int depth = args.argsLength() > 2 ? Math.max(1, args.getInteger(2)) : 1; + + Vector pos = session.getPlacementPosition(player); + int affected = 0; + if (pattern instanceof SingleBlockPattern) { + affected = editSession.fillXZ(pos, + ((SingleBlockPattern) pattern).getBlock(), + radius, depth, false); + } else { + affected = editSession.fillXZ(pos, pattern, radius, depth, false); + } + player.print(BBC.getPrefix() + affected + " block(s) have been created."); + } + + @Command( + aliases = { "/fillr" }, + usage = " [depth]", + desc = "Fill a hole recursively", + min = 2, + max = 3 + ) + @CommandPermissions("worldedit.fill.recursive") + @Logging(PLACEMENT) + public void fillr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + Pattern pattern = we.getBlockPattern(player, args.getString(0)); + double radius = Math.max(1, args.getDouble(1)); + we.checkMaxRadius(radius); + int depth = args.argsLength() > 2 ? Math.max(1, args.getInteger(2)) : Integer.MAX_VALUE; + + Vector pos = session.getPlacementPosition(player); + int affected = 0; + if (pattern instanceof SingleBlockPattern) { + affected = editSession.fillXZ(pos, + ((SingleBlockPattern) pattern).getBlock(), + radius, depth, true); + } else { + affected = editSession.fillXZ(pos, pattern, radius, depth, true); + } + player.print(BBC.getPrefix() + affected + " block(s) have been created."); + } + + @Command( + aliases = { "/drain" }, + usage = "", + desc = "Drain a pool", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.drain") + @Logging(PLACEMENT) + public void drain(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + double radius = Math.max(0, args.getDouble(0)); + we.checkMaxRadius(radius); + int affected = editSession.drainArea( + session.getPlacementPosition(player), radius); + player.print(BBC.getPrefix() + affected + " block(s) have been changed."); + } + + @Command( + aliases = { "/fixlava", "fixlava" }, + usage = "", + desc = "Fix lava to be stationary", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.fixlava") + @Logging(PLACEMENT) + public void fixLava(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + double radius = Math.max(0, args.getDouble(0)); + we.checkMaxRadius(radius); + int affected = editSession.fixLiquid( + session.getPlacementPosition(player), radius, 10, 11); + player.print(BBC.getPrefix() + affected + " block(s) have been changed."); + } + + @Command( + aliases = { "/fixwater", "fixwater" }, + usage = "", + desc = "Fix water to be stationary", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.fixwater") + @Logging(PLACEMENT) + public void fixWater(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + double radius = Math.max(0, args.getDouble(0)); + we.checkMaxRadius(radius); + int affected = editSession.fixLiquid( + session.getPlacementPosition(player), radius, 8, 9); + player.print(BBC.getPrefix() + affected + " block(s) have been changed."); + } + + @Command( + aliases = { "/removeabove", "removeabove" }, + usage = "[size] [height]", + desc = "Remove blocks above your head.", + min = 0, + max = 2 + ) + @CommandPermissions("worldedit.removeabove") + @Logging(PLACEMENT) + public void removeAbove(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1; + we.checkMaxRadius(size); + World world = player.getWorld(); + int height = args.argsLength() > 1 ? Math.min((world.getMaxY() + 1), args.getInteger(1) + 2) : (world.getMaxY() + 1); + + int affected = editSession.removeAbove( + session.getPlacementPosition(player), size, height); + player.print(BBC.getPrefix() + affected + " block(s) have been removed."); + } + + @Command( + aliases = { "/removebelow", "removebelow" }, + usage = "[size] [height]", + desc = "Remove blocks below you.", + min = 0, + max = 2 + ) + @CommandPermissions("worldedit.removebelow") + @Logging(PLACEMENT) + public void removeBelow(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1; + we.checkMaxRadius(size); + World world = player.getWorld(); + int height = args.argsLength() > 1 ? Math.min((world.getMaxY() + 1), args.getInteger(1) + 2) : (world.getMaxY() + 1); + + int affected = editSession.removeBelow(session.getPlacementPosition(player), size, height); + player.print(BBC.getPrefix() + affected + " block(s) have been removed."); + } + + @Command( + aliases = { "/removenear", "removenear" }, + usage = " [size]", + desc = "Remove blocks near you.", + min = 1, + max = 2 + ) + @CommandPermissions("worldedit.removenear") + @Logging(PLACEMENT) + public void removeNear(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + BaseBlock block = we.getBlock(player, args.getString(0), true); + int size = Math.max(1, args.getInteger(1, 50)); + we.checkMaxRadius(size); + + int affected = editSession.removeNear(session.getPlacementPosition(player), block.getType(), size); + player.print(BBC.getPrefix() + affected + " block(s) have been removed."); + } + + @Command( + aliases = { "/replacenear", "replacenear" }, + usage = " ", + desc = "Replace nearby blocks", + flags = "f", + min = 3, + max = 3 + ) + @CommandPermissions("worldedit.replacenear") + @Logging(PLACEMENT) + public void replaceNear(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + int size = Math.max(1, args.getInteger(0)); + int affected; + Set from; + Pattern to; + if (args.argsLength() == 2) { + from = null; + to = we.getBlockPattern(player, args.getString(1)); + } else { + from = we.getBlocks(player, args.getString(1), true, !args.hasFlag('f')); + to = we.getBlockPattern(player, args.getString(2)); + } + + Vector base = session.getPlacementPosition(player); + Vector min = base.subtract(size, size, size); + Vector max = base.add(size, size, size); + Region region = new CuboidRegion(player.getWorld(), min, max); + + if (to instanceof SingleBlockPattern) { + affected = editSession.replaceBlocks(region, from, ((SingleBlockPattern) to).getBlock()); + } else { + affected = editSession.replaceBlocks(region, from, to); + } + player.print(BBC.getPrefix() + affected + " block(s) have been replaced."); + } + + @Command( + aliases = { "/snow", "snow" }, + usage = "[radius]", + desc = "Simulates snow", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.snow") + @Logging(PLACEMENT) + public void snow(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10; + + int affected = editSession.simulateSnow(session.getPlacementPosition(player), size); + player.print(BBC.getPrefix() + affected + " surfaces covered. Let it snow~"); + } + + @Command( + aliases = {"/thaw", "thaw"}, + usage = "[radius]", + desc = "Thaws the area", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.thaw") + @Logging(PLACEMENT) + public void thaw(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10; + + int affected = editSession.thaw(session.getPlacementPosition(player), size); + player.print(BBC.getPrefix() + affected + " surfaces thawed."); + } + + @Command( + aliases = { "/green", "green" }, + usage = "[radius]", + desc = "Greens the area", + flags = "f", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.green") + @Logging(PLACEMENT) + public void green(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + final double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10; + final boolean onlyNormalDirt = !args.hasFlag('f'); + + final int affected = editSession.green(session.getPlacementPosition(player), size, onlyNormalDirt); + player.print(BBC.getPrefix() + affected + " surfaces greened."); + } + + @Command( + aliases = { "/ex", "/ext", "/extinguish", "ex", "ext", "extinguish" }, + usage = "[radius]", + desc = "Extinguish nearby fire", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.extinguish") + @Logging(PLACEMENT) + public void extinguish(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + + int defaultRadius = config.maxRadius != -1 ? Math.min(40, config.maxRadius) : 40; + int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) + : defaultRadius; + we.checkMaxRadius(size); + + int affected = editSession.removeNear(session.getPlacementPosition(player), 51, size); + player.print(BBC.getPrefix() + affected + " block(s) have been removed."); + } + + @Command( + aliases = { "butcher" }, + usage = "[radius]", + flags = "plangbtfr", + desc = "Kill all or nearby mobs", + help = + "Kills nearby mobs, based on radius, if none is given uses default in configuration.\n" + + "Flags:\n" + + " -p also kills pets.\n" + + " -n also kills NPCs.\n" + + " -g also kills Golems.\n" + + " -a also kills animals.\n" + + " -b also kills ambient mobs.\n" + + " -t also kills mobs with name tags.\n" + + " -f compounds all previous flags.\n" + + " -r also destroys armor stands.\n" + + " -l currently does nothing.", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.butcher") + @Logging(PLACEMENT) + public void butcher(Actor actor, CommandContext args) throws WorldEditException { + LocalConfiguration config = we.getConfiguration(); + Player player = actor instanceof Player ? (Player) actor : null; + + // technically the default can be larger than the max, but that's not my problem + int radius = config.butcherDefaultRadius; + + // there might be a better way to do this but my brain is fried right now + if (args.argsLength() > 0) { // user inputted radius, override the default + radius = args.getInteger(0); + if (radius < -1) { + actor.printError("Use -1 to remove all mobs in loaded chunks"); + return; + } + if (config.butcherMaxRadius != -1) { // clamp if there is a max + if (radius == -1) { + radius = config.butcherMaxRadius; + } else { // Math.min does not work if radius is -1 (actually highest possible value) + radius = Math.min(radius, config.butcherMaxRadius); + } + } + } + + CreatureButcher flags = new CreatureButcher(actor); + flags.fromCommand(args); + + List visitors = new ArrayList(); + LocalSession session = null; + EditSession editSession = null; + + if (player != null) { + session = we.getSessionManager().get(player); + Vector center = session.getPlacementPosition(player); + editSession = session.createEditSession(player); + List entities; + if (radius >= 0) { + CylinderRegion region = CylinderRegion.createRadius(editSession, center, radius); + entities = editSession.getEntities(region); + } else { + entities = editSession.getEntities(); + } + visitors.add(new EntityVisitor(entities.iterator(), flags.createFunction(editSession.getWorld().getWorldData().getEntityRegistry()))); + } else { + Platform platform = we.getPlatformManager().queryCapability(Capability.WORLD_EDITING); + for (World world : platform.getWorlds()) { + List entities = world.getEntities(); + visitors.add(new EntityVisitor(entities.iterator(), flags.createFunction(world.getWorldData().getEntityRegistry()))); + } + } + + int killed = 0; + for (EntityVisitor visitor : visitors) { + Operations.completeLegacy(visitor); + killed += visitor.getAffected(); + } + + actor.print(BBC.getPrefix() + "Killed " + killed + (killed != 1 ? " mobs" : " mob") + (radius < 0 ? "" : " in a radius of " + radius) + "."); + + if (editSession != null) { + session.remember(editSession); + editSession.flushQueue(); + } + } + + @Command( + aliases = { "remove", "rem", "rement" }, + usage = " ", + desc = "Remove all entities of a type", + min = 2, + max = 2 + ) + @CommandPermissions("worldedit.remove") + @Logging(PLACEMENT) + public void remove(Actor actor, CommandContext args) throws WorldEditException, CommandException { + String typeStr = args.getString(0); + int radius = args.getInteger(1); + Player player = actor instanceof Player ? (Player) actor : null; + + if (radius < -1) { + actor.printError("Use -1 to remove all entities in loaded chunks"); + return; + } + + EntityRemover remover = new EntityRemover(); + remover.fromString(typeStr); + + List visitors = new ArrayList(); + LocalSession session = null; + EditSession editSession = null; + + if (player != null) { + session = we.getSessionManager().get(player); + Vector center = session.getPlacementPosition(player); + editSession = session.createEditSession(player); + List entities; + if (radius >= 0) { + CylinderRegion region = CylinderRegion.createRadius(editSession, center, radius); + entities = editSession.getEntities(region); + } else { + entities = editSession.getEntities(); + } + visitors.add(new EntityVisitor(entities.iterator(), remover.createFunction(editSession.getWorld().getWorldData().getEntityRegistry()))); + } else { + Platform platform = we.getPlatformManager().queryCapability(Capability.WORLD_EDITING); + for (World world : platform.getWorlds()) { + List entities = world.getEntities(); + visitors.add(new EntityVisitor(entities.iterator(), remover.createFunction(world.getWorldData().getEntityRegistry()))); + } + } + + int removed = 0; + for (EntityVisitor visitor : visitors) { + Operations.completeLegacy(visitor); + removed += visitor.getAffected(); + } + + actor.print(BBC.getPrefix() + "Marked " + removed + (removed != 1 ? " entities" : " entity") + " for removal."); + + if (editSession != null) { + session.remember(editSession); + editSession.flushQueue(); + } + } + + @Command( + aliases = { "/calc", "/calculate", "/eval", "/evaluate", "/solve" }, + usage = "", + desc = "Evaluate a mathematical expression" + ) + @CommandPermissions("worldedit.calc") + public void calc(Actor actor, @Text String input) throws CommandException { + try { + Expression expression = Expression.compile(input); + actor.print(BBC.getPrefix() + "= " + expression.evaluate()); + } catch (EvaluationException e) { + actor.printError(String.format( + "'%s' could not be parsed as a valid expression", input)); + } catch (ExpressionException e) { + actor.printError(String.format( + "'%s' could not be evaluated (error: %s)", input, e.getMessage())); + } + } + + @Command( + aliases = { "/help" }, + usage = "[]", + desc = "Displays help for WorldEdit commands", + min = 0, + max = -1 + ) + @CommandPermissions("worldedit.help") + public void help(Actor actor, CommandContext args) throws WorldEditException { + help(args, we, actor); + } + + private static CommandMapping detectCommand(Dispatcher dispatcher, String command, boolean isRootLevel) { + CommandMapping mapping; + + // First try the command as entered + mapping = dispatcher.get(command); + if (mapping != null) { + return mapping; + } + + // Then if we're looking at root commands and the user didn't use + // any slashes, let's try double slashes and then single slashes. + // However, be aware that there exists different single slash + // and double slash commands in WorldEdit + if (isRootLevel && !command.contains("/")) { + mapping = dispatcher.get("//" + command); + if (mapping != null) { + return mapping; + } + + mapping = dispatcher.get("/" + command); + if (mapping != null) { + return mapping; + } + } + + return null; + } + + public static void help(CommandContext args, WorldEdit we, Actor actor) { + CommandCallable callable = we.getPlatformManager().getCommandManager().getDispatcher(); + + int page = 0; + final int perPage = actor instanceof Player ? 8 : 20; // More pages for console + int effectiveLength = args.argsLength(); + + // Detect page from args + try { + if (args.argsLength() > 0) { + page = args.getInteger(args.argsLength() - 1); + if (page <= 0) { + page = 1; + } else { + page--; + } + + effectiveLength--; + } + } catch (NumberFormatException ignored) { + } + + boolean isRootLevel = true; + List visited = new ArrayList(); + + // Drill down to the command + for (int i = 0; i < effectiveLength; i++) { + String command = args.getString(i); + + if (callable instanceof Dispatcher) { + // Chop off the beginning / if we're are the root level + if (isRootLevel && command.length() > 1 && command.charAt(0) == '/') { + command = command.substring(1); + } + + CommandMapping mapping = detectCommand((Dispatcher) callable, command, isRootLevel); + if (mapping != null) { + callable = mapping.getCallable(); + } else { + if (isRootLevel) { + actor.printError(String.format("The command '%s' could not be found.", args.getString(i))); + return; + } else { + actor.printError(String.format("The sub-command '%s' under '%s' could not be found.", + command, Joiner.on(" ").join(visited))); + return; + } + } + + visited.add(args.getString(i)); + isRootLevel = false; + } else { + actor.printError(String.format("'%s' has no sub-commands. (Maybe '%s' is for a parameter?)", + Joiner.on(" ").join(visited), command)); + return; + } + } + + // Create the message + if (callable instanceof Dispatcher) { + Dispatcher dispatcher = (Dispatcher) callable; + + // Get a list of aliases + List aliases = new ArrayList(dispatcher.getCommands()); + Collections.sort(aliases, new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN)); + + // Calculate pagination + int offset = perPage * page; + int pageTotal = (int) Math.ceil(aliases.size() / (double) perPage); + + // Box + CommandListBox box = new CommandListBox(String.format("Help: page %d/%d ", page + 1, pageTotal)); + StyledFragment contents = box.getContents(); + StyledFragment tip = contents.createFragment(Style.GRAY); + + if (offset >= aliases.size()) { + tip.createFragment(Style.RED).append(String.format("There is no page %d (total number of pages is %d).", page + 1, pageTotal)).newLine(); + } else { + List list = aliases.subList(offset, Math.min(offset + perPage, aliases.size())); + + tip.append("Type "); + tip.append(new Code().append("//help ").append(" []")); + tip.append(" for more information.").newLine(); + + // Add each command + for (CommandMapping mapping : list) { + StringBuilder builder = new StringBuilder(); + if (isRootLevel) { + builder.append("/"); + } + if (!visited.isEmpty()) { + builder.append(Joiner.on(" ").join(visited)); + builder.append(" "); + } + builder.append(mapping.getPrimaryAlias()); + box.appendCommand(builder.toString(), mapping.getDescription().getDescription()); + } + } + + actor.printRaw(ColorCodeBuilder.asColorCodes(box)); + } else { + CommandUsageBox box = new CommandUsageBox(callable, Joiner.on(" ").join(visited)); + actor.printRaw(ColorCodeBuilder.asColorCodes(box)); + } + } + + public static Class inject() { + return UtilityCommands.class; + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java b/core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java new file mode 100644 index 00000000..258adace --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java @@ -0,0 +1,130 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command; + +import com.boydti.fawe.config.BBC; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.event.platform.ConfigurationLoadEvent; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.extension.platform.PlatformManager; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.TimeZone; + +public class WorldEditCommands { + private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); + + private final WorldEdit we; + + public WorldEditCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "version", "ver" }, + usage = "", + desc = "Get WorldEdit version", + min = 0, + max = 0 + ) + public void version(Actor actor) throws WorldEditException { + actor.print(BBC.getPrefix() + "WorldEdit version " + WorldEdit.getVersion()); + actor.print(BBC.getPrefix() + "https://github.com/sk89q/worldedit/"); + + PlatformManager pm = we.getPlatformManager(); + + actor.printDebug("----------- Platforms -----------"); + for (Platform platform : pm.getPlatforms()) { + actor.printDebug(String.format("* %s (%s)", platform.getPlatformName(), platform.getPlatformVersion())); + } + + actor.printDebug("----------- Capabilities -----------"); + for (Capability capability : Capability.values()) { + Platform platform = pm.queryCapability(capability); + actor.printDebug(String.format("%s: %s", capability.name(), platform != null ? platform.getPlatformName() : "NONE")); + } + } + + @Command( + aliases = { "reload" }, + usage = "", + desc = "Reload configuration", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.reload") + public void reload(Actor actor) throws WorldEditException { + we.getServer().reload(); + we.getEventBus().post(new ConfigurationLoadEvent(we.getPlatformManager().queryCapability(Capability.CONFIGURATION).getConfiguration())); + actor.print(BBC.getPrefix() + "Configuration reloaded!"); + } + + @Command( + aliases = { "cui" }, + usage = "", + desc = "Complete CUI handshake (internal usage)", + min = 0, + max = 0 + ) + public void cui(Player player, LocalSession session, CommandContext args) throws WorldEditException { + session.setCUISupport(true); + session.dispatchCUISetup(player); + } + + @Command( + aliases = { "tz" }, + usage = "[timezone]", + desc = "Set your timezone for snapshots", + min = 1, + max = 1 + ) + public void tz(Player player, LocalSession session, CommandContext args) throws WorldEditException { + TimeZone tz = TimeZone.getTimeZone(args.getString(0)); + session.setTimezone(tz); + player.print(BBC.getPrefix() + "Timezone set for this session to: " + tz.getDisplayName()); + player.print(BBC.getPrefix() + "The current time in that timezone is: " + + dateFormat.format(Calendar.getInstance(tz).getTime())); + } + + @Command( + aliases = { "help" }, + usage = "[]", + desc = "Displays help for WorldEdit commands", + min = 0, + max = -1 + ) + @CommandPermissions("worldedit.help") + public void help(Actor actor, CommandContext args) throws WorldEditException { + UtilityCommands.help(args, we, actor); + } + + public static Class inject() { + return WorldEditCommands.class; + } +} diff --git a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlatform.java b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlatform.java index db383928..a2f5ce12 100644 --- a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlatform.java +++ b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlatform.java @@ -67,7 +67,6 @@ public class NukkitPlatform extends AbstractPlatform implements MultiUserPlatfor @Override public boolean isValidMobType(String type) { - System.out.print("Not implemented: isValidMobType"); return true; }