diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java index 1397e5654..1ef75c30e 100644 --- a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -10,8 +10,8 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; -import com.sk89q.worldedit.bags.BlockBag; -import com.sk89q.worldedit.cui.CUIEvent; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.internal.cui.CUIEvent; public class ForgePlayer extends LocalPlayer { private EntityPlayerMP player; diff --git a/src/main/java/com/sk89q/jnbt/NBTUtils.java b/src/main/java/com/sk89q/jnbt/NBTUtils.java index 21057a1ec..da1a944c4 100644 --- a/src/main/java/com/sk89q/jnbt/NBTUtils.java +++ b/src/main/java/com/sk89q/jnbt/NBTUtils.java @@ -2,20 +2,7 @@ package com.sk89q.jnbt; import java.util.Map; -import com.sk89q.jnbt.ByteArrayTag; -import com.sk89q.jnbt.ByteTag; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.DoubleTag; -import com.sk89q.jnbt.EndTag; -import com.sk89q.jnbt.FloatTag; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.LongTag; -import com.sk89q.jnbt.NBTConstants; -import com.sk89q.jnbt.ShortTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.data.InvalidFormatException; +import com.sk89q.worldedit.world.storage.InvalidFormatException; /* * JNBT License diff --git a/src/main/java/com/sk89q/worldedit/CuboidClipboard.java b/src/main/java/com/sk89q/worldedit/CuboidClipboard.java index 6f3bddc23..66d2acce4 100644 --- a/src/main/java/com/sk89q/worldedit/CuboidClipboard.java +++ b/src/main/java/com/sk89q/worldedit/CuboidClipboard.java @@ -30,9 +30,10 @@ import java.util.Map; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.schematic.SchematicFormat; +import com.sk89q.worldedit.util.Countable; /** * The clipboard remembers the state of a cuboid region. diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java index 37382775d..16a0ac93c 100644 --- a/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/src/main/java/com/sk89q/worldedit/EditSession.java @@ -19,16 +19,24 @@ package com.sk89q.worldedit; -import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.extent.buffer.ForgetfulExtentBuffer; +import com.sk89q.worldedit.extent.cache.LastAccessExtentCache; +import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.event.extent.EditSessionEvent; -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.ExpressionException; -import com.sk89q.worldedit.expression.runtime.RValue; +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.ExpressionException; +import com.sk89q.worldedit.internal.expression.runtime.RValue; import com.sk89q.worldedit.extent.*; +import com.sk89q.worldedit.extent.inventory.BlockBagExtent; import com.sk89q.worldedit.extent.reorder.MultiStageReorder; +import com.sk89q.worldedit.extent.validation.BlockChangeLimiter; +import com.sk89q.worldedit.extent.validation.DataValidatorExtent; +import com.sk89q.worldedit.extent.world.BlockQuirkExtent; +import com.sk89q.worldedit.extent.world.ChunkLoadingExtent; +import com.sk89q.worldedit.extent.world.FastModeExtent; import com.sk89q.worldedit.function.GroundFunction; import com.sk89q.worldedit.function.RegionMaskingFilter; import com.sk89q.worldedit.function.block.Counter; @@ -54,10 +62,11 @@ import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.patterns.Pattern; import com.sk89q.worldedit.patterns.SingleBlockPattern; import com.sk89q.worldedit.regions.*; -import com.sk89q.worldedit.shape.ArbitraryBiomeShape; -import com.sk89q.worldedit.shape.ArbitraryShape; -import com.sk89q.worldedit.shape.RegionShape; -import com.sk89q.worldedit.shape.WorldEditExpressionEnvironment; +import com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape; +import com.sk89q.worldedit.regions.shape.ArbitraryShape; +import com.sk89q.worldedit.regions.shape.RegionShape; +import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment; +import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.collection.DoubleArrayList; import com.sk89q.worldedit.util.eventbus.EventBus; diff --git a/src/main/java/com/sk89q/worldedit/EditSessionFactory.java b/src/main/java/com/sk89q/worldedit/EditSessionFactory.java index 07b946de5..cf3eb79b2 100644 --- a/src/main/java/com/sk89q/worldedit/EditSessionFactory.java +++ b/src/main/java/com/sk89q/worldedit/EditSessionFactory.java @@ -19,7 +19,7 @@ package com.sk89q.worldedit; -import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.event.extent.EditSessionEvent; import com.sk89q.worldedit.util.eventbus.EventBus; diff --git a/src/main/java/com/sk89q/worldedit/LocalConfiguration.java b/src/main/java/com/sk89q/worldedit/LocalConfiguration.java index 5a3cd72a3..49d3bdb7f 100644 --- a/src/main/java/com/sk89q/worldedit/LocalConfiguration.java +++ b/src/main/java/com/sk89q/worldedit/LocalConfiguration.java @@ -25,7 +25,7 @@ import java.util.Set; import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.ItemID; -import com.sk89q.worldedit.snapshots.SnapshotRepository; +import com.sk89q.worldedit.world.snapshot.SnapshotRepository; /** * Represents WorldEdit's configuration. diff --git a/src/main/java/com/sk89q/worldedit/LocalPlayer.java b/src/main/java/com/sk89q/worldedit/LocalPlayer.java index 4fa98c7aa..b0121e28e 100644 --- a/src/main/java/com/sk89q/worldedit/LocalPlayer.java +++ b/src/main/java/com/sk89q/worldedit/LocalPlayer.java @@ -21,12 +21,12 @@ package com.sk89q.worldedit; import java.io.File; -import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.ItemID; -import com.sk89q.worldedit.cui.CUIEvent; +import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.util.TargetBlock; /** diff --git a/src/main/java/com/sk89q/worldedit/LocalSession.java b/src/main/java/com/sk89q/worldedit/LocalSession.java index 7e73d222d..fc1801522 100644 --- a/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -28,15 +28,15 @@ import com.sk89q.jchronic.Chronic; import com.sk89q.jchronic.Options; import com.sk89q.jchronic.utils.Span; import com.sk89q.jchronic.utils.Time; -import com.sk89q.worldedit.snapshots.Snapshot; -import com.sk89q.worldedit.tools.BrushTool; -import com.sk89q.worldedit.tools.SinglePickaxe; -import com.sk89q.worldedit.tools.BlockTool; -import com.sk89q.worldedit.tools.Tool; -import com.sk89q.worldedit.bags.BlockBag; -import com.sk89q.worldedit.cui.CUIRegion; -import com.sk89q.worldedit.cui.CUIEvent; -import com.sk89q.worldedit.cui.SelectionShapeEvent; +import com.sk89q.worldedit.world.snapshot.Snapshot; +import com.sk89q.worldedit.command.tool.BrushTool; +import com.sk89q.worldedit.command.tool.SinglePickaxe; +import com.sk89q.worldedit.command.tool.BlockTool; +import com.sk89q.worldedit.command.tool.Tool; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.internal.cui.CUIRegion; +import com.sk89q.worldedit.internal.cui.CUIEvent; +import com.sk89q.worldedit.internal.cui.SelectionShapeEvent; import com.sk89q.worldedit.masks.Mask; import com.sk89q.worldedit.regions.CuboidRegionSelector; import com.sk89q.worldedit.regions.Region; diff --git a/src/main/java/com/sk89q/worldedit/WorldEdit.java b/src/main/java/com/sk89q/worldedit/WorldEdit.java index c00a76613..e3d50a9c1 100644 --- a/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -23,9 +23,9 @@ import com.sk89q.minecraft.util.commands.*; import com.sk89q.minecraft.util.commands.Console; import com.sk89q.util.StringUtil; import com.sk89q.worldedit.CuboidClipboard.FlipDirection; -import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.blocks.*; -import com.sk89q.worldedit.commands.*; +import com.sk89q.worldedit.command.*; import com.sk89q.worldedit.event.extent.EditSessionEvent; import com.sk89q.worldedit.masks.*; import com.sk89q.worldedit.patterns.*; @@ -33,7 +33,8 @@ import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.scripting.CraftScriptContext; import com.sk89q.worldedit.scripting.CraftScriptEngine; import com.sk89q.worldedit.scripting.RhinoCraftScriptEngine; -import com.sk89q.worldedit.tools.*; +import com.sk89q.worldedit.command.tool.*; +import com.sk89q.worldedit.util.LogFormat; import com.sk89q.worldedit.util.eventbus.EventBus; import javax.script.ScriptException; diff --git a/src/main/java/com/sk89q/worldedit/blocks/ChestBlock.java b/src/main/java/com/sk89q/worldedit/blocks/ChestBlock.java index 1b66e4304..db161e1c8 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/ChestBlock.java +++ b/src/main/java/com/sk89q/worldedit/blocks/ChestBlock.java @@ -29,7 +29,7 @@ import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.NBTUtils; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * Represents a chest block. diff --git a/src/main/java/com/sk89q/worldedit/blocks/ContainerBlock.java b/src/main/java/com/sk89q/worldedit/blocks/ContainerBlock.java index 60be36134..1796e66dd 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/ContainerBlock.java +++ b/src/main/java/com/sk89q/worldedit/blocks/ContainerBlock.java @@ -30,7 +30,7 @@ import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.NBTUtils; import com.sk89q.jnbt.ShortTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * Represents a block that stores items. diff --git a/src/main/java/com/sk89q/worldedit/blocks/DispenserBlock.java b/src/main/java/com/sk89q/worldedit/blocks/DispenserBlock.java index 81c8e9c9b..169448656 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/DispenserBlock.java +++ b/src/main/java/com/sk89q/worldedit/blocks/DispenserBlock.java @@ -29,7 +29,7 @@ import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.NBTUtils; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * Represents dispensers. diff --git a/src/main/java/com/sk89q/worldedit/blocks/FurnaceBlock.java b/src/main/java/com/sk89q/worldedit/blocks/FurnaceBlock.java index b0187a262..5fc017eb1 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/FurnaceBlock.java +++ b/src/main/java/com/sk89q/worldedit/blocks/FurnaceBlock.java @@ -30,7 +30,7 @@ import com.sk89q.jnbt.NBTUtils; import com.sk89q.jnbt.ShortTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * Represents a furnace block. diff --git a/src/main/java/com/sk89q/worldedit/blocks/LazyBlock.java b/src/main/java/com/sk89q/worldedit/blocks/LazyBlock.java index 551592923..54325671f 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/LazyBlock.java +++ b/src/main/java/com/sk89q/worldedit/blocks/LazyBlock.java @@ -21,7 +21,7 @@ package com.sk89q.worldedit.blocks; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.extent.Extent; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/src/main/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java b/src/main/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java index 746b1ba67..590c71d1b 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java +++ b/src/main/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java @@ -29,8 +29,8 @@ import com.sk89q.jnbt.ShortTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.MobType; -import com.sk89q.worldedit.data.DataException; -import com.sk89q.worldedit.data.InvalidFormatException; +import com.sk89q.worldedit.world.DataException; +import com.sk89q.worldedit.world.storage.InvalidFormatException; /** * A mob spawner block. diff --git a/src/main/java/com/sk89q/worldedit/blocks/NoteBlock.java b/src/main/java/com/sk89q/worldedit/blocks/NoteBlock.java index 283ca4c37..ca4be9a6e 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/NoteBlock.java +++ b/src/main/java/com/sk89q/worldedit/blocks/NoteBlock.java @@ -26,7 +26,7 @@ import com.sk89q.jnbt.ByteTag; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * A note block. diff --git a/src/main/java/com/sk89q/worldedit/blocks/SignBlock.java b/src/main/java/com/sk89q/worldedit/blocks/SignBlock.java index f593b0d05..5b78fa417 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/SignBlock.java +++ b/src/main/java/com/sk89q/worldedit/blocks/SignBlock.java @@ -25,7 +25,7 @@ import java.util.Map; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * Represents a sign block. diff --git a/src/main/java/com/sk89q/worldedit/blocks/SkullBlock.java b/src/main/java/com/sk89q/worldedit/blocks/SkullBlock.java index 66179b495..3bb2bc483 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/SkullBlock.java +++ b/src/main/java/com/sk89q/worldedit/blocks/SkullBlock.java @@ -26,7 +26,7 @@ import com.sk89q.jnbt.ByteTag; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * A skull block. diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java index 5747a4607..b7ad8fe88 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java @@ -28,7 +28,7 @@ import com.sk89q.worldedit.PlayerNeededException; import com.sk89q.worldedit.ServerInterface; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; -import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.extent.inventory.BlockBag; public class BukkitCommandSender extends LocalPlayer { private CommandSender sender; diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 7374105e7..ae8fb2e49 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -32,8 +32,8 @@ import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.ServerInterface; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; -import com.sk89q.worldedit.bags.BlockBag; -import com.sk89q.worldedit.cui.CUIEvent; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.internal.cui.CUIEvent; public class BukkitPlayer extends LocalPlayer { private Player player; diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java index ab66726b3..80c47678d 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java @@ -22,7 +22,7 @@ package com.sk89q.worldedit.bukkit; import com.sk89q.worldedit.WorldVector; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import com.sk89q.worldedit.bags.*; +import com.sk89q.worldedit.extent.inventory.*; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BlockID; diff --git a/src/main/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java b/src/main/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java index 23fd20561..66bf9c996 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/DefaultNmsBlock.java @@ -22,7 +22,7 @@ import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.TileEntityBlock; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.foundation.Block; import net.minecraft.server.v1_7_R2.*; import org.bukkit.World; diff --git a/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index eaba0e2af..40640be9f 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -45,7 +45,7 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.ServerInterface; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditOperation; -import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.bukkit.selections.CuboidSelection; import com.sk89q.worldedit.bukkit.selections.Polygonal2DSelection; import com.sk89q.worldedit.bukkit.selections.Selection; diff --git a/src/main/java/com/sk89q/worldedit/commands/BiomeCommands.java b/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java similarity index 99% rename from src/main/java/com/sk89q/worldedit/commands/BiomeCommands.java rename to src/main/java/com/sk89q/worldedit/command/BiomeCommands.java index f25c25cd8..63fa1a12d 100644 --- a/src/main/java/com/sk89q/worldedit/commands/BiomeCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java @@ -1,4 +1,4 @@ -package com.sk89q.worldedit.commands; +package com.sk89q.worldedit.command; import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION; diff --git a/src/main/java/com/sk89q/worldedit/commands/BrushCommands.java b/src/main/java/com/sk89q/worldedit/command/BrushCommands.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/commands/BrushCommands.java rename to src/main/java/com/sk89q/worldedit/command/BrushCommands.java index cffe67220..a8dbd6ce5 100644 --- a/src/main/java/com/sk89q/worldedit/commands/BrushCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -1,293 +1,293 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -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.CuboidClipboard; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.LocalConfiguration; -import com.sk89q.worldedit.LocalPlayer; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.LocalWorld.KillFlags; -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.blocks.BlockID; -import com.sk89q.worldedit.commands.UtilityCommands.FlagContainer; -import com.sk89q.worldedit.masks.BlockMask; -import com.sk89q.worldedit.patterns.Pattern; -import com.sk89q.worldedit.patterns.SingleBlockPattern; -import com.sk89q.worldedit.tools.BrushTool; -import com.sk89q.worldedit.tools.brushes.ButcherBrush; -import com.sk89q.worldedit.tools.brushes.ClipboardBrush; -import com.sk89q.worldedit.tools.brushes.CylinderBrush; -import com.sk89q.worldedit.tools.brushes.GravityBrush; -import com.sk89q.worldedit.tools.brushes.HollowCylinderBrush; -import com.sk89q.worldedit.tools.brushes.HollowSphereBrush; -import com.sk89q.worldedit.tools.brushes.SmoothBrush; -import com.sk89q.worldedit.tools.brushes.SphereBrush; - -/** - * Brush shape commands. - * - * @author sk89q - */ -public class BrushCommands { - private final WorldEdit we; - - public BrushCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "sphere", "s" }, - usage = " [radius]", - flags = "h", - desc = "Choose the sphere brush", - help = - "Chooses the sphere brush.\n" + - "The -h flag creates hollow spheres instead.", - min = 1, - max = 2 - ) - @CommandPermissions("worldedit.brush.sphere") - public void sphereBrush(CommandContext args, LocalSession session, - LocalPlayer player, EditSession editSession) throws WorldEditException { - - double radius = args.argsLength() > 1 ? args.getDouble(1) : 2; - we.checkMaxBrushRadius(radius); - - BrushTool tool = session.getBrushTool(player.getItemInHand()); - Pattern fill = we.getBlockPattern(player, args.getString(0)); - tool.setFill(fill); - tool.setSize(radius); - - if (args.hasFlag('h')) { - tool.setBrush(new HollowSphereBrush(), "worldedit.brush.sphere"); - } else { - tool.setBrush(new SphereBrush(), "worldedit.brush.sphere"); - } - - player.print(String.format("Sphere brush shape equipped (%.0f).", - radius)); - } - - @Command( - aliases = { "cylinder", "cyl", "c" }, - usage = " [radius] [height]", - flags = "h", - desc = "Choose the cylinder brush", - help = - "Chooses the cylinder brush.\n" + - "The -h flag creates hollow cylinders instead.", - min = 1, - max = 3 - ) - @CommandPermissions("worldedit.brush.cylinder") - public void cylinderBrush(CommandContext args, LocalSession session, - LocalPlayer player, EditSession editSession) throws WorldEditException { - - double radius = args.argsLength() > 1 ? args.getDouble(1) : 2; - we.checkMaxBrushRadius(radius); - - int height = args.argsLength() > 2 ? args.getInteger(2) : 1; - we.checkMaxBrushRadius(height); - - BrushTool tool = session.getBrushTool(player.getItemInHand()); - Pattern fill = we.getBlockPattern(player, args.getString(0)); - tool.setFill(fill); - tool.setSize(radius); - - if (args.hasFlag('h')) { - tool.setBrush(new HollowCylinderBrush(height), "worldedit.brush.cylinder"); - } else { - tool.setBrush(new CylinderBrush(height), "worldedit.brush.cylinder"); - } - - player.print(String.format("Cylinder brush shape equipped (%.0f by %d).", - radius, height)); - } - - @Command( - aliases = { "clipboard", "copy" }, - usage = "", - flags = "a", - desc = "Choose the clipboard brush", - help = - "Chooses the clipboard brush.\n" + - "The -a flag makes it not paste air.", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.brush.clipboard") - public void clipboardBrush(CommandContext args, LocalSession session, - LocalPlayer player, EditSession editSession) throws WorldEditException { - - CuboidClipboard clipboard = session.getClipboard(); - - if (clipboard == null) { - player.printError("Copy something first."); - return; - } - - Vector size = clipboard.getSize(); - - we.checkMaxBrushRadius(size.getBlockX()); - we.checkMaxBrushRadius(size.getBlockY()); - we.checkMaxBrushRadius(size.getBlockZ()); - - BrushTool tool = session.getBrushTool(player.getItemInHand()); - tool.setBrush(new ClipboardBrush(clipboard, args.hasFlag('a')), "worldedit.brush.clipboard"); - - player.print("Clipboard brush shape equipped."); - } - - @Command( - aliases = { "smooth" }, - usage = "[size] [iterations]", - flags = "n", - desc = "Choose the terrain softener brush", - help = - "Chooses the terrain softener brush.\n" + - "The -n flag makes it only consider naturally occuring blocks.", - min = 0, - max = 2 - ) - @CommandPermissions("worldedit.brush.smooth") - public void smoothBrush(CommandContext args, LocalSession session, - LocalPlayer player, EditSession editSession) throws WorldEditException { - - double radius = args.argsLength() > 0 ? args.getDouble(0) : 2; - we.checkMaxBrushRadius(radius); - - int iterations = args.argsLength() > 1 ? args.getInteger(1) : 4; - - BrushTool tool = session.getBrushTool(player.getItemInHand()); - tool.setSize(radius); - tool.setBrush(new SmoothBrush(iterations, args.hasFlag('n')), "worldedit.brush.smooth"); - - player.print(String.format("Smooth brush equipped (%.0f x %dx, using " + (args.hasFlag('n') ? "natural blocks only" : "any block") + ").", - radius, iterations)); - } - - @Command( - aliases = { "ex", "extinguish" }, - usage = "[radius]", - desc = "Shortcut fire extinguisher brush", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.brush.ex") - public void extinguishBrush(CommandContext args, LocalSession session, - LocalPlayer player, EditSession editSession) throws WorldEditException { - - double radius = args.argsLength() > 1 ? args.getDouble(1) : 5; - we.checkMaxBrushRadius(radius); - - BrushTool tool = session.getBrushTool(player.getItemInHand()); - Pattern fill = new SingleBlockPattern(new BaseBlock(0)); - tool.setFill(fill); - tool.setSize(radius); - tool.setMask(new BlockMask(new BaseBlock(BlockID.FIRE))); - tool.setBrush(new SphereBrush(), "worldedit.brush.ex"); - - player.print(String.format("Extinguisher equipped (%.0f).", - radius)); - } - - @Command( - aliases = { "gravity", "grav" }, - usage = "[radius]", - flags = "h", - desc = "Gravity brush", - help = - "This brush simulates the affect of gravity.\n" + - "The -h flag makes it affect blocks starting at the world's max y, " + - "instead of the clicked block's y + radius.", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.brush.gravity") - public void gravityBrush(CommandContext args, LocalSession session, - LocalPlayer player, EditSession editSession) throws WorldEditException { - - double radius = args.argsLength() > 0 ? args.getDouble(0) : 5; - we.checkMaxBrushRadius(radius); - - BrushTool tool = session.getBrushTool(player.getItemInHand()); - tool.setSize(radius); - tool.setBrush(new GravityBrush(args.hasFlag('h')), "worldedit.brush.gravity"); - - player.print(String.format("Gravity brush equipped (%.0f).", - radius)); - } - - @Command( - aliases = { "butcher", "kill" }, - usage = "[radius] [command flags]", - desc = "Butcher brush", - help = "Kills nearby mobs within the specified radius.\n" + - "Any number of 'flags' that the //butcher command uses\n" + - "may be specified as an argument", - min = 0, - max = 2 - ) - @CommandPermissions("worldedit.brush.butcher") - public void butcherBrush(CommandContext args, LocalSession session, - LocalPlayer player, EditSession editSession) throws WorldEditException { - - LocalConfiguration config = we.getConfiguration(); - - double radius = args.argsLength() > 0 ? args.getDouble(0) : 5; - double maxRadius = config.maxBrushRadius; - // hmmmm not horribly worried about this because -1 is still rather efficient, - // the problem arises when butcherMaxRadius is some really high number but not infinite - // - original idea taken from https://github.com/sk89q/worldedit/pull/198#issuecomment-6463108 - if (player.hasPermission("worldedit.butcher")) { - maxRadius = Math.max(config.maxBrushRadius, config.butcherMaxRadius); - } - if (radius > maxRadius) { - player.printError("Maximum allowed brush radius: " + maxRadius); - return; - } - - FlagContainer flags = new FlagContainer(player); - if (args.argsLength() == 2) { - String flagString = args.getString(1); - // straight from the command, using contains instead of hasflag - flags.or(KillFlags.FRIENDLY , flagString.contains("f")); // No permission check here. Flags will instead be filtered by the subsequent calls. - flags.or(KillFlags.PETS , flagString.contains("p"), "worldedit.butcher.pets"); - flags.or(KillFlags.NPCS , flagString.contains("n"), "worldedit.butcher.npcs"); - flags.or(KillFlags.GOLEMS , flagString.contains("g"), "worldedit.butcher.golems"); - flags.or(KillFlags.ANIMALS , flagString.contains("a"), "worldedit.butcher.animals"); - flags.or(KillFlags.AMBIENT , flagString.contains("b"), "worldedit.butcher.ambient"); - flags.or(KillFlags.WITH_LIGHTNING, flagString.contains("l"), "worldedit.butcher.lightning"); - } - BrushTool tool = session.getBrushTool(player.getItemInHand()); - tool.setSize(radius); - tool.setBrush(new ButcherBrush(flags.flags), "worldedit.brush.butcher"); - - player.print(String.format("Butcher brush equipped (%.0f).", - radius)); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +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.CuboidClipboard; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.LocalWorld.KillFlags; +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.blocks.BlockID; +import com.sk89q.worldedit.command.UtilityCommands.FlagContainer; +import com.sk89q.worldedit.masks.BlockMask; +import com.sk89q.worldedit.patterns.Pattern; +import com.sk89q.worldedit.patterns.SingleBlockPattern; +import com.sk89q.worldedit.command.tool.BrushTool; +import com.sk89q.worldedit.command.tool.brush.ButcherBrush; +import com.sk89q.worldedit.command.tool.brush.ClipboardBrush; +import com.sk89q.worldedit.command.tool.brush.CylinderBrush; +import com.sk89q.worldedit.command.tool.brush.GravityBrush; +import com.sk89q.worldedit.command.tool.brush.HollowCylinderBrush; +import com.sk89q.worldedit.command.tool.brush.HollowSphereBrush; +import com.sk89q.worldedit.command.tool.brush.SmoothBrush; +import com.sk89q.worldedit.command.tool.brush.SphereBrush; + +/** + * Brush shape commands. + * + * @author sk89q + */ +public class BrushCommands { + private final WorldEdit we; + + public BrushCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "sphere", "s" }, + usage = " [radius]", + flags = "h", + desc = "Choose the sphere brush", + help = + "Chooses the sphere brush.\n" + + "The -h flag creates hollow spheres instead.", + min = 1, + max = 2 + ) + @CommandPermissions("worldedit.brush.sphere") + public void sphereBrush(CommandContext args, LocalSession session, + LocalPlayer player, EditSession editSession) throws WorldEditException { + + double radius = args.argsLength() > 1 ? args.getDouble(1) : 2; + we.checkMaxBrushRadius(radius); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + Pattern fill = we.getBlockPattern(player, args.getString(0)); + tool.setFill(fill); + tool.setSize(radius); + + if (args.hasFlag('h')) { + tool.setBrush(new HollowSphereBrush(), "worldedit.brush.sphere"); + } else { + tool.setBrush(new SphereBrush(), "worldedit.brush.sphere"); + } + + player.print(String.format("Sphere brush shape equipped (%.0f).", + radius)); + } + + @Command( + aliases = { "cylinder", "cyl", "c" }, + usage = " [radius] [height]", + flags = "h", + desc = "Choose the cylinder brush", + help = + "Chooses the cylinder brush.\n" + + "The -h flag creates hollow cylinders instead.", + min = 1, + max = 3 + ) + @CommandPermissions("worldedit.brush.cylinder") + public void cylinderBrush(CommandContext args, LocalSession session, + LocalPlayer player, EditSession editSession) throws WorldEditException { + + double radius = args.argsLength() > 1 ? args.getDouble(1) : 2; + we.checkMaxBrushRadius(radius); + + int height = args.argsLength() > 2 ? args.getInteger(2) : 1; + we.checkMaxBrushRadius(height); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + Pattern fill = we.getBlockPattern(player, args.getString(0)); + tool.setFill(fill); + tool.setSize(radius); + + if (args.hasFlag('h')) { + tool.setBrush(new HollowCylinderBrush(height), "worldedit.brush.cylinder"); + } else { + tool.setBrush(new CylinderBrush(height), "worldedit.brush.cylinder"); + } + + player.print(String.format("Cylinder brush shape equipped (%.0f by %d).", + radius, height)); + } + + @Command( + aliases = { "clipboard", "copy" }, + usage = "", + flags = "a", + desc = "Choose the clipboard brush", + help = + "Chooses the clipboard brush.\n" + + "The -a flag makes it not paste air.", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.brush.clipboard") + public void clipboardBrush(CommandContext args, LocalSession session, + LocalPlayer player, EditSession editSession) throws WorldEditException { + + CuboidClipboard clipboard = session.getClipboard(); + + if (clipboard == null) { + player.printError("Copy something first."); + return; + } + + Vector size = clipboard.getSize(); + + we.checkMaxBrushRadius(size.getBlockX()); + we.checkMaxBrushRadius(size.getBlockY()); + we.checkMaxBrushRadius(size.getBlockZ()); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + tool.setBrush(new ClipboardBrush(clipboard, args.hasFlag('a')), "worldedit.brush.clipboard"); + + player.print("Clipboard brush shape equipped."); + } + + @Command( + aliases = { "smooth" }, + usage = "[size] [iterations]", + flags = "n", + desc = "Choose the terrain softener brush", + help = + "Chooses the terrain softener brush.\n" + + "The -n flag makes it only consider naturally occuring blocks.", + min = 0, + max = 2 + ) + @CommandPermissions("worldedit.brush.smooth") + public void smoothBrush(CommandContext args, LocalSession session, + LocalPlayer player, EditSession editSession) throws WorldEditException { + + double radius = args.argsLength() > 0 ? args.getDouble(0) : 2; + we.checkMaxBrushRadius(radius); + + int iterations = args.argsLength() > 1 ? args.getInteger(1) : 4; + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + tool.setSize(radius); + tool.setBrush(new SmoothBrush(iterations, args.hasFlag('n')), "worldedit.brush.smooth"); + + player.print(String.format("Smooth brush equipped (%.0f x %dx, using " + (args.hasFlag('n') ? "natural blocks only" : "any block") + ").", + radius, iterations)); + } + + @Command( + aliases = { "ex", "extinguish" }, + usage = "[radius]", + desc = "Shortcut fire extinguisher brush", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.brush.ex") + public void extinguishBrush(CommandContext args, LocalSession session, + LocalPlayer player, EditSession editSession) throws WorldEditException { + + double radius = args.argsLength() > 1 ? args.getDouble(1) : 5; + we.checkMaxBrushRadius(radius); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + Pattern fill = new SingleBlockPattern(new BaseBlock(0)); + tool.setFill(fill); + tool.setSize(radius); + tool.setMask(new BlockMask(new BaseBlock(BlockID.FIRE))); + tool.setBrush(new SphereBrush(), "worldedit.brush.ex"); + + player.print(String.format("Extinguisher equipped (%.0f).", + radius)); + } + + @Command( + aliases = { "gravity", "grav" }, + usage = "[radius]", + flags = "h", + desc = "Gravity brush", + help = + "This brush simulates the affect of gravity.\n" + + "The -h flag makes it affect blocks starting at the world's max y, " + + "instead of the clicked block's y + radius.", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.brush.gravity") + public void gravityBrush(CommandContext args, LocalSession session, + LocalPlayer player, EditSession editSession) throws WorldEditException { + + double radius = args.argsLength() > 0 ? args.getDouble(0) : 5; + we.checkMaxBrushRadius(radius); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + tool.setSize(radius); + tool.setBrush(new GravityBrush(args.hasFlag('h')), "worldedit.brush.gravity"); + + player.print(String.format("Gravity brush equipped (%.0f).", + radius)); + } + + @Command( + aliases = { "butcher", "kill" }, + usage = "[radius] [command flags]", + desc = "Butcher brush", + help = "Kills nearby mobs within the specified radius.\n" + + "Any number of 'flags' that the //butcher command uses\n" + + "may be specified as an argument", + min = 0, + max = 2 + ) + @CommandPermissions("worldedit.brush.butcher") + public void butcherBrush(CommandContext args, LocalSession session, + LocalPlayer player, EditSession editSession) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + + double radius = args.argsLength() > 0 ? args.getDouble(0) : 5; + double maxRadius = config.maxBrushRadius; + // hmmmm not horribly worried about this because -1 is still rather efficient, + // the problem arises when butcherMaxRadius is some really high number but not infinite + // - original idea taken from https://github.com/sk89q/worldedit/pull/198#issuecomment-6463108 + if (player.hasPermission("worldedit.butcher")) { + maxRadius = Math.max(config.maxBrushRadius, config.butcherMaxRadius); + } + if (radius > maxRadius) { + player.printError("Maximum allowed brush radius: " + maxRadius); + return; + } + + FlagContainer flags = new FlagContainer(player); + if (args.argsLength() == 2) { + String flagString = args.getString(1); + // straight from the command, using contains instead of hasflag + flags.or(KillFlags.FRIENDLY , flagString.contains("f")); // No permission check here. Flags will instead be filtered by the subsequent calls. + flags.or(KillFlags.PETS , flagString.contains("p"), "worldedit.butcher.pets"); + flags.or(KillFlags.NPCS , flagString.contains("n"), "worldedit.butcher.npcs"); + flags.or(KillFlags.GOLEMS , flagString.contains("g"), "worldedit.butcher.golems"); + flags.or(KillFlags.ANIMALS , flagString.contains("a"), "worldedit.butcher.animals"); + flags.or(KillFlags.AMBIENT , flagString.contains("b"), "worldedit.butcher.ambient"); + flags.or(KillFlags.WITH_LIGHTNING, flagString.contains("l"), "worldedit.butcher.lightning"); + } + BrushTool tool = session.getBrushTool(player.getItemInHand()); + tool.setSize(radius); + tool.setBrush(new ButcherBrush(flags.flags), "worldedit.brush.butcher"); + + player.print(String.format("Butcher brush equipped (%.0f).", + radius)); + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/ChunkCommands.java b/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/commands/ChunkCommands.java rename to src/main/java/com/sk89q/worldedit/command/ChunkCommands.java index 887404ef6..583174e06 100644 --- a/src/main/java/com/sk89q/worldedit/commands/ChunkCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java @@ -1,179 +1,179 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.util.Set; -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 static com.sk89q.minecraft.util.commands.Logging.LogMode.*; -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.data.LegacyChunkStore; -import com.sk89q.worldedit.data.McRegionChunkStore; - -/** - * Chunk tools. - * - * @author sk89q - */ -public class ChunkCommands { - private final WorldEdit we; - - public ChunkCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "chunkinfo" }, - usage = "", - desc = "Get information about the chunk that you are inside", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.chunkinfo") - public void chunkInfo(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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(WorldEdit.divisorMod(chunkX, 64), 36); - String folder2 = Integer.toString(WorldEdit.divisorMod(chunkZ, 64), 36); - String filename = "c." + Integer.toString(chunkX, 36) - + "." + Integer.toString(chunkZ, 36) + ".dat"; - - player.print("Chunk: " + chunkX + ", " + chunkZ); - player.print("Old format: " + folder1 + "/" + folder2 + "/" + filename); - player.print("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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Set chunks = session.getSelection(player.getWorld()).getChunks(); - - for (Vector2D chunk : chunks) { - player.print(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - player.print("Note that this command does not yet support the mcregion format."); - LocalConfiguration config = we.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("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 ie) { } - } - } - } 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("worldedit-delchunks.sh written. Run it when no one is near the region."); - player.print("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 ie) { - } - } - } - } else { - player.printError("Shell script type must be configured: 'bat' or 'bash' expected."); - } - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.Set; +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 static com.sk89q.minecraft.util.commands.Logging.LogMode.*; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.world.storage.LegacyChunkStore; +import com.sk89q.worldedit.world.storage.McRegionChunkStore; + +/** + * Chunk tools. + * + * @author sk89q + */ +public class ChunkCommands { + private final WorldEdit we; + + public ChunkCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "chunkinfo" }, + usage = "", + desc = "Get information about the chunk that you are inside", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.chunkinfo") + public void chunkInfo(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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(WorldEdit.divisorMod(chunkX, 64), 36); + String folder2 = Integer.toString(WorldEdit.divisorMod(chunkZ, 64), 36); + String filename = "c." + Integer.toString(chunkX, 36) + + "." + Integer.toString(chunkZ, 36) + ".dat"; + + player.print("Chunk: " + chunkX + ", " + chunkZ); + player.print("Old format: " + folder1 + "/" + folder2 + "/" + filename); + player.print("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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Set chunks = session.getSelection(player.getWorld()).getChunks(); + + for (Vector2D chunk : chunks) { + player.print(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + player.print("Note that this command does not yet support the mcregion format."); + LocalConfiguration config = we.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("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 ie) { } + } + } + } 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("worldedit-delchunks.sh written. Run it when no one is near the region."); + player.print("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 ie) { + } + } + } + } else { + player.printError("Shell script type must be configured: 'bat' or 'bash' expected."); + } + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/ClipboardCommands.java b/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/commands/ClipboardCommands.java rename to src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index a38530f3f..48c97f4b0 100644 --- a/src/main/java/com/sk89q/worldedit/commands/ClipboardCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -1,286 +1,286 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -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 static com.sk89q.minecraft.util.commands.Logging.LogMode.*; - -import com.sk89q.minecraft.util.commands.NestedCommand; -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockID; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.regions.CuboidRegionSelector; -import com.sk89q.worldedit.regions.Region; - -/** - * Clipboard commands. - * - * @author sk89q - */ -public class ClipboardCommands { - private final WorldEdit we; - - public ClipboardCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "/copy" }, - flags = "e", - desc = "Copy the selection to the clipboard", - help = "Copy the selection to the clipboard\n" + - "Flags:\n" + - " -e controls whether entities are copied\n" + - "WARNING: Pasting entities cannot yet be undone!", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.clipboard.copy") - public void copy(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Region region = session.getSelection(player.getWorld()); - Vector min = region.getMinimumPoint(); - Vector max = region.getMaximumPoint(); - Vector pos = session.getPlacementPosition(player); - - CuboidClipboard clipboard = new CuboidClipboard( - max.subtract(min).add(Vector.ONE), - min, min.subtract(pos)); - - if (region instanceof CuboidRegion) { - clipboard.copy(editSession); - } else { - clipboard.copy(editSession, region); - } - - if (args.hasFlag('e')) { - for (LocalEntity entity : player.getWorld().getEntities(region)) { - clipboard.storeEntity(entity); - } - } - session.setClipboard(clipboard); - - player.print("Block(s) copied."); - } - - @Command( - aliases = { "/cut" }, - usage = "[leave-id]", - desc = "Cut the selection to the clipboard", - help = "Copy the selection to the clipboard\n" + - "Flags:\n" + - " -e controls whether entities are copied\n" + - "WARNING: Cutting and pasting entities cannot yet be undone!", - flags = "e", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.clipboard.cut") - @Logging(REGION) - public void cut(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - BaseBlock block = new BaseBlock(BlockID.AIR); - LocalWorld world = player.getWorld(); - - if (args.argsLength() > 0) { - block = we.getBlock(player, args.getString(0)); - } - - Region region = session.getSelection(world); - Vector min = region.getMinimumPoint(); - Vector max = region.getMaximumPoint(); - Vector pos = session.getPlacementPosition(player); - - CuboidClipboard clipboard = new CuboidClipboard( - max.subtract(min).add(Vector.ONE), - min, min.subtract(pos)); - - if (region instanceof CuboidRegion) { - clipboard.copy(editSession); - } else { - clipboard.copy(editSession, region); - } - - if (args.hasFlag('e')) { - LocalEntity[] entities = world.getEntities(region); - for (LocalEntity entity : entities) { - clipboard.storeEntity(entity); - } - world.killEntities(entities); - } - session.setClipboard(clipboard); - - editSession.setBlocks(region, block); - player.print("Block(s) cut."); - } - - @Command( - aliases = { "/paste" }, - usage = "", - flags = "sao", - desc = "Paste the clipboard's contents", - help = - "Pastes the clipboard's contents.\n" + - "Flags:\n" + - " -a skips air blocks\n" + - " -o pastes at the original position\n" + - " -s selects the region after pasting", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.clipboard.paste") - @Logging(PLACEMENT) - public void paste(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - boolean atOrigin = args.hasFlag('o'); - boolean pasteNoAir = args.hasFlag('a'); - - CuboidClipboard clipboard = session.getClipboard(); - - Vector pos = atOrigin ? session.getClipboard().getOrigin() - : session.getPlacementPosition(player); - - if (atOrigin) { - clipboard.place(editSession, pos, pasteNoAir); - clipboard.pasteEntities(pos); - player.findFreePosition(); - player.print("Pasted to copy origin. Undo with //undo"); - } else { - clipboard.paste(editSession, pos, pasteNoAir, true); - player.findFreePosition(); - player.print("Pasted relative to you. Undo with //undo"); - } - - if (args.hasFlag('s')) { - LocalWorld world = player.getWorld(); - Vector pos2 = pos.add(clipboard.getSize().subtract(1, 1, 1)); - if (!atOrigin) { - pos2 = pos2.add(clipboard.getOffset()); - pos = pos.add(clipboard.getOffset()); - } - session.setRegionSelector(world, new CuboidRegionSelector(world, pos, pos2)); - session.getRegionSelector(world).learnChanges(); - session.getRegionSelector(world).explainRegionAdjust(player, session); - } - } - - @Command( - aliases = { "/rotate" }, - usage = "", - desc = "Rotate the contents of the clipboard", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.clipboard.rotate") - public void rotate(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int angle = args.getInteger(0); - - if (angle % 90 == 0) { - CuboidClipboard clipboard = session.getClipboard(); - clipboard.rotate2D(angle); - player.print("Clipboard rotated by " + angle + " degrees."); - } else { - player.printError("Angles must be divisible by 90 degrees."); - } - } - - @Command( - aliases = { "/flip" }, - usage = "[dir]", - flags = "p", - desc = "Flip the contents of the clipboard.", - help = - "Flips the contents of the clipboard.\n" + - "The -p flag flips the selection around the player,\n" + - "instead of the selections center.", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.clipboard.flip") - public void flip(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - CuboidClipboard.FlipDirection dir = we.getFlipDirection(player, - args.argsLength() > 0 ? args.getString(0).toLowerCase() : "me"); - - CuboidClipboard clipboard = session.getClipboard(); - clipboard.flip(dir, args.hasFlag('p')); - player.print("Clipboard flipped."); - } - - @Command( - aliases = { "/load" }, - usage = "", - desc = "Load a schematic into your clipboard", - min = 0, - max = 1 - ) - @Deprecated - @CommandPermissions("worldedit.clipboard.load") - public void load(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - player.printError("This command is no longer used. See //schematic load."); - } - - @Command( - aliases = { "/save" }, - usage = "", - desc = "Save a schematic into your clipboard", - min = 0, - max = 1 - ) - @Deprecated - @CommandPermissions("worldedit.clipboard.save") - public void save(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - player.printError("This command is no longer used. See //schematic save."); - } - - @Command( - aliases = { "/schematic", "/schem"}, - desc = "Schematic-related commands" - ) - @NestedCommand(SchematicCommands.class) - public void schematic() {} - - @Command( - aliases = { "clearclipboard" }, - usage = "", - desc = "Clear your clipboard", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.clipboard.clear") - public void clearClipboard(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - session.setClipboard(null); - player.print("Clipboard cleared."); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +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 static com.sk89q.minecraft.util.commands.Logging.LogMode.*; + +import com.sk89q.minecraft.util.commands.NestedCommand; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.CuboidRegionSelector; +import com.sk89q.worldedit.regions.Region; + +/** + * Clipboard commands. + * + * @author sk89q + */ +public class ClipboardCommands { + private final WorldEdit we; + + public ClipboardCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "/copy" }, + flags = "e", + desc = "Copy the selection to the clipboard", + help = "Copy the selection to the clipboard\n" + + "Flags:\n" + + " -e controls whether entities are copied\n" + + "WARNING: Pasting entities cannot yet be undone!", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.clipboard.copy") + public void copy(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Region region = session.getSelection(player.getWorld()); + Vector min = region.getMinimumPoint(); + Vector max = region.getMaximumPoint(); + Vector pos = session.getPlacementPosition(player); + + CuboidClipboard clipboard = new CuboidClipboard( + max.subtract(min).add(Vector.ONE), + min, min.subtract(pos)); + + if (region instanceof CuboidRegion) { + clipboard.copy(editSession); + } else { + clipboard.copy(editSession, region); + } + + if (args.hasFlag('e')) { + for (LocalEntity entity : player.getWorld().getEntities(region)) { + clipboard.storeEntity(entity); + } + } + session.setClipboard(clipboard); + + player.print("Block(s) copied."); + } + + @Command( + aliases = { "/cut" }, + usage = "[leave-id]", + desc = "Cut the selection to the clipboard", + help = "Copy the selection to the clipboard\n" + + "Flags:\n" + + " -e controls whether entities are copied\n" + + "WARNING: Cutting and pasting entities cannot yet be undone!", + flags = "e", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.clipboard.cut") + @Logging(REGION) + public void cut(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + BaseBlock block = new BaseBlock(BlockID.AIR); + LocalWorld world = player.getWorld(); + + if (args.argsLength() > 0) { + block = we.getBlock(player, args.getString(0)); + } + + Region region = session.getSelection(world); + Vector min = region.getMinimumPoint(); + Vector max = region.getMaximumPoint(); + Vector pos = session.getPlacementPosition(player); + + CuboidClipboard clipboard = new CuboidClipboard( + max.subtract(min).add(Vector.ONE), + min, min.subtract(pos)); + + if (region instanceof CuboidRegion) { + clipboard.copy(editSession); + } else { + clipboard.copy(editSession, region); + } + + if (args.hasFlag('e')) { + LocalEntity[] entities = world.getEntities(region); + for (LocalEntity entity : entities) { + clipboard.storeEntity(entity); + } + world.killEntities(entities); + } + session.setClipboard(clipboard); + + editSession.setBlocks(region, block); + player.print("Block(s) cut."); + } + + @Command( + aliases = { "/paste" }, + usage = "", + flags = "sao", + desc = "Paste the clipboard's contents", + help = + "Pastes the clipboard's contents.\n" + + "Flags:\n" + + " -a skips air blocks\n" + + " -o pastes at the original position\n" + + " -s selects the region after pasting", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.clipboard.paste") + @Logging(PLACEMENT) + public void paste(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + boolean atOrigin = args.hasFlag('o'); + boolean pasteNoAir = args.hasFlag('a'); + + CuboidClipboard clipboard = session.getClipboard(); + + Vector pos = atOrigin ? session.getClipboard().getOrigin() + : session.getPlacementPosition(player); + + if (atOrigin) { + clipboard.place(editSession, pos, pasteNoAir); + clipboard.pasteEntities(pos); + player.findFreePosition(); + player.print("Pasted to copy origin. Undo with //undo"); + } else { + clipboard.paste(editSession, pos, pasteNoAir, true); + player.findFreePosition(); + player.print("Pasted relative to you. Undo with //undo"); + } + + if (args.hasFlag('s')) { + LocalWorld world = player.getWorld(); + Vector pos2 = pos.add(clipboard.getSize().subtract(1, 1, 1)); + if (!atOrigin) { + pos2 = pos2.add(clipboard.getOffset()); + pos = pos.add(clipboard.getOffset()); + } + session.setRegionSelector(world, new CuboidRegionSelector(world, pos, pos2)); + session.getRegionSelector(world).learnChanges(); + session.getRegionSelector(world).explainRegionAdjust(player, session); + } + } + + @Command( + aliases = { "/rotate" }, + usage = "", + desc = "Rotate the contents of the clipboard", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.clipboard.rotate") + public void rotate(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int angle = args.getInteger(0); + + if (angle % 90 == 0) { + CuboidClipboard clipboard = session.getClipboard(); + clipboard.rotate2D(angle); + player.print("Clipboard rotated by " + angle + " degrees."); + } else { + player.printError("Angles must be divisible by 90 degrees."); + } + } + + @Command( + aliases = { "/flip" }, + usage = "[dir]", + flags = "p", + desc = "Flip the contents of the clipboard.", + help = + "Flips the contents of the clipboard.\n" + + "The -p flag flips the selection around the player,\n" + + "instead of the selections center.", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.clipboard.flip") + public void flip(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + CuboidClipboard.FlipDirection dir = we.getFlipDirection(player, + args.argsLength() > 0 ? args.getString(0).toLowerCase() : "me"); + + CuboidClipboard clipboard = session.getClipboard(); + clipboard.flip(dir, args.hasFlag('p')); + player.print("Clipboard flipped."); + } + + @Command( + aliases = { "/load" }, + usage = "", + desc = "Load a schematic into your clipboard", + min = 0, + max = 1 + ) + @Deprecated + @CommandPermissions("worldedit.clipboard.load") + public void load(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + player.printError("This command is no longer used. See //schematic load."); + } + + @Command( + aliases = { "/save" }, + usage = "", + desc = "Save a schematic into your clipboard", + min = 0, + max = 1 + ) + @Deprecated + @CommandPermissions("worldedit.clipboard.save") + public void save(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + player.printError("This command is no longer used. See //schematic save."); + } + + @Command( + aliases = { "/schematic", "/schem"}, + desc = "Schematic-related commands" + ) + @NestedCommand(SchematicCommands.class) + public void schematic() {} + + @Command( + aliases = { "clearclipboard" }, + usage = "", + desc = "Clear your clipboard", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.clipboard.clear") + public void clearClipboard(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + session.setClipboard(null); + player.print("Clipboard cleared."); + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/GeneralCommands.java b/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/commands/GeneralCommands.java rename to src/main/java/com/sk89q/worldedit/command/GeneralCommands.java index 2fc8fd4f3..3ca64194f 100644 --- a/src/main/java/com/sk89q/worldedit/commands/GeneralCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java @@ -1,234 +1,234 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -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.Console; -import com.sk89q.minecraft.util.commands.NestedCommand; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.LocalConfiguration; -import com.sk89q.worldedit.LocalPlayer; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.blocks.ItemType; -import com.sk89q.worldedit.masks.Mask; - -/** - * General WorldEdit commands. - * - * @author sk89q - */ -public class GeneralCommands { - private final WorldEdit we; - - public GeneralCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "/limit" }, - usage = "", - desc = "Modify block change limit", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.limit") - public void limit(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - LocalConfiguration config = we.getConfiguration(); - - int limit = Math.max(-1, args.getInteger(0)); - if (!player.hasPermission("worldedit.limit.unrestricted") - && config.maxChangeLimit > -1) { - if (limit > config.maxChangeLimit) { - player.printError("Your maximum allowable limit is " - + config.maxChangeLimit + "."); - return; - } - } - - session.setBlockChangeLimit(limit); - player.print("Block change limit set to " + limit + "."); - } - - @Command( - aliases = { "/fast" }, - usage = "[on|off]", - desc = "Toggle fast mode", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.fast") - public void fast(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - String newState = args.getString(0, null); - if (session.hasFastMode()) { - if ("on".equals(newState)) { - player.printError("Fast mode already enabled."); - return; - } - - session.setFastMode(false); - player.print("Fast mode disabled."); - } else { - if ("off".equals(newState)) { - player.printError("Fast mode already disabled."); - return; - } - - session.setFastMode(true); - player.print("Fast mode enabled. Lighting in the affected chunks may be wrong and/or you may need to rejoin to see changes."); - } - } - - @Command( - aliases = { "/gmask", "gmask" }, - usage = "[mask]", - desc = "Set the global mask", - min = 0, - max = -1 - ) - @CommandPermissions("worldedit.global-mask") - public void gmask(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - if (args.argsLength() == 0) { - session.setMask(null); - player.print("Global mask disabled."); - } else { - Mask mask = we.getBlockMask(player, session, args.getJoinedStrings(0)); - session.setMask(mask); - player.print("Global mask set."); - } - } - - @Command( - aliases = { "/toggleplace", "toggleplace" }, - usage = "", - desc = "Switch between your position and pos1 for placement", - min = 0, - max = 0 - ) - public void togglePlace(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - if (session.togglePlacementPosition()) { - player.print("Now placing at pos #1."); - } else { - player.print("Now placing at the block you stand in."); - } - } - - @Command( - aliases = { "/searchitem", "/l", "/search", "searchitem" }, - usage = "", - flags = "bi", - desc = "Search for an item", - help = - "Searches for an item.\n" + - "Flags:\n" + - " -b only search for blocks\n" + - " -i only search for items", - min = 1, - max = 1 - ) - @Console - public void searchItem(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - String query = args.getString(0).trim().toLowerCase(); - boolean blocksOnly = args.hasFlag('b'); - boolean itemsOnly = args.hasFlag('i'); - - try { - int id = Integer.parseInt(query); - - ItemType type = ItemType.fromID(id); - - if (type != null) { - player.print("#" + type.getID() + " (" + type.getName() + ")"); - } else { - player.printError("No item found by ID " + id); - } - - return; - } catch (NumberFormatException e) { - } - - if (query.length() <= 2) { - player.printError("Enter a longer search string (len > 2)."); - return; - } - - if (!blocksOnly && !itemsOnly) { - player.print("Searching for: " + query); - } else if (blocksOnly && itemsOnly) { - player.printError("You cannot use both the 'b' and 'i' flags simultaneously."); - return; - } else if (blocksOnly) { - player.print("Searching for blocks: " + query); - } else { - player.print("Searching for items: " + query); - } - - int found = 0; - - for (ItemType type : ItemType.values()) { - if (found >= 15) { - player.print("Too many results!"); - break; - } - - if (blocksOnly && type.getID() > 255) { - continue; - } - - if (itemsOnly && type.getID() <= 255) { - continue; - } - - for (String alias : type.getAliases()) { - if (alias.contains(query)) { - player.print("#" + type.getID() + " (" + type.getName() + ")"); - ++found; - break; - } - } - } - - if (found == 0) { - player.printError("No items found."); - } - } - - @Command( - aliases = { "we", "worldedit" }, - desc = "WorldEdit commands" - ) - @NestedCommand(WorldEditCommands.class) - @Console - public void we(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +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.Console; +import com.sk89q.minecraft.util.commands.NestedCommand; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.ItemType; +import com.sk89q.worldedit.masks.Mask; + +/** + * General WorldEdit commands. + * + * @author sk89q + */ +public class GeneralCommands { + private final WorldEdit we; + + public GeneralCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "/limit" }, + usage = "", + desc = "Modify block change limit", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.limit") + public void limit(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + + int limit = Math.max(-1, args.getInteger(0)); + if (!player.hasPermission("worldedit.limit.unrestricted") + && config.maxChangeLimit > -1) { + if (limit > config.maxChangeLimit) { + player.printError("Your maximum allowable limit is " + + config.maxChangeLimit + "."); + return; + } + } + + session.setBlockChangeLimit(limit); + player.print("Block change limit set to " + limit + "."); + } + + @Command( + aliases = { "/fast" }, + usage = "[on|off]", + desc = "Toggle fast mode", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.fast") + public void fast(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + String newState = args.getString(0, null); + if (session.hasFastMode()) { + if ("on".equals(newState)) { + player.printError("Fast mode already enabled."); + return; + } + + session.setFastMode(false); + player.print("Fast mode disabled."); + } else { + if ("off".equals(newState)) { + player.printError("Fast mode already disabled."); + return; + } + + session.setFastMode(true); + player.print("Fast mode enabled. Lighting in the affected chunks may be wrong and/or you may need to rejoin to see changes."); + } + } + + @Command( + aliases = { "/gmask", "gmask" }, + usage = "[mask]", + desc = "Set the global mask", + min = 0, + max = -1 + ) + @CommandPermissions("worldedit.global-mask") + public void gmask(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + if (args.argsLength() == 0) { + session.setMask(null); + player.print("Global mask disabled."); + } else { + Mask mask = we.getBlockMask(player, session, args.getJoinedStrings(0)); + session.setMask(mask); + player.print("Global mask set."); + } + } + + @Command( + aliases = { "/toggleplace", "toggleplace" }, + usage = "", + desc = "Switch between your position and pos1 for placement", + min = 0, + max = 0 + ) + public void togglePlace(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + if (session.togglePlacementPosition()) { + player.print("Now placing at pos #1."); + } else { + player.print("Now placing at the block you stand in."); + } + } + + @Command( + aliases = { "/searchitem", "/l", "/search", "searchitem" }, + usage = "", + flags = "bi", + desc = "Search for an item", + help = + "Searches for an item.\n" + + "Flags:\n" + + " -b only search for blocks\n" + + " -i only search for items", + min = 1, + max = 1 + ) + @Console + public void searchItem(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + String query = args.getString(0).trim().toLowerCase(); + boolean blocksOnly = args.hasFlag('b'); + boolean itemsOnly = args.hasFlag('i'); + + try { + int id = Integer.parseInt(query); + + ItemType type = ItemType.fromID(id); + + if (type != null) { + player.print("#" + type.getID() + " (" + type.getName() + ")"); + } else { + player.printError("No item found by ID " + id); + } + + return; + } catch (NumberFormatException e) { + } + + if (query.length() <= 2) { + player.printError("Enter a longer search string (len > 2)."); + return; + } + + if (!blocksOnly && !itemsOnly) { + player.print("Searching for: " + query); + } else if (blocksOnly && itemsOnly) { + player.printError("You cannot use both the 'b' and 'i' flags simultaneously."); + return; + } else if (blocksOnly) { + player.print("Searching for blocks: " + query); + } else { + player.print("Searching for items: " + query); + } + + int found = 0; + + for (ItemType type : ItemType.values()) { + if (found >= 15) { + player.print("Too many results!"); + break; + } + + if (blocksOnly && type.getID() > 255) { + continue; + } + + if (itemsOnly && type.getID() <= 255) { + continue; + } + + for (String alias : type.getAliases()) { + if (alias.contains(query)) { + player.print("#" + type.getID() + " (" + type.getName() + ")"); + ++found; + break; + } + } + } + + if (found == 0) { + player.printError("No items found."); + } + } + + @Command( + aliases = { "we", "worldedit" }, + desc = "WorldEdit commands" + ) + @NestedCommand(WorldEditCommands.class) + @Console + public void we(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/GenerationCommands.java b/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/commands/GenerationCommands.java rename to src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index d904e5f1b..cb5dc2ea0 100644 --- a/src/main/java/com/sk89q/worldedit/commands/GenerationCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -1,487 +1,486 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -import static com.sk89q.minecraft.util.commands.Logging.LogMode.ALL; -import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT; -import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION; - -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.BiomeType; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.LocalPlayer; -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.expression.ExpressionException; -import com.sk89q.worldedit.patterns.Pattern; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.TreeGenerator; - -/** - * Generation commands. - * - * @author sk89q - */ -public class GenerationCommands { - private final WorldEdit we; - - public GenerationCommands(WorldEdit we) { - this.we = we; - } - - @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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Pattern block = we.getBlockPattern(player, args.getString(0)); - String[] radiuses = args.getString(1).split(","); - final double radiusX, radiusZ; - switch (radiuses.length) { - case 1: - radiusX = radiusZ = Math.max(1, Double.parseDouble(radiuses[0])); - break; - - case 2: - radiusX = Math.max(1, Double.parseDouble(radiuses[0])); - radiusZ = Math.max(1, Double.parseDouble(radiuses[1])); - break; - - default: - player.printError("You must either specify 1 or 2 radius values."); - return; - } - int height = args.argsLength() > 2 ? args.getInteger(2) : 1; - - we.checkMaxRadius(radiusX); - we.checkMaxRadius(radiusZ); - we.checkMaxRadius(height); - - Vector pos = session.getPlacementPosition(player); - int affected = editSession.makeCylinder(pos, block, radiusX, radiusZ, height, false); - player.print(affected + " block(s) have been created."); - } - - @Command( - aliases = { "/cyl" }, - usage = " [,] [height]", - 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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Pattern block = we.getBlockPattern(player, args.getString(0)); - String[] radiuses = args.getString(1).split(","); - final double radiusX, radiusZ; - switch (radiuses.length) { - case 1: - radiusX = radiusZ = Math.max(1, Double.parseDouble(radiuses[0])); - break; - - case 2: - radiusX = Math.max(1, Double.parseDouble(radiuses[0])); - radiusZ = Math.max(1, Double.parseDouble(radiuses[1])); - break; - - default: - player.printError("You must either specify 1 or 2 radius values."); - return; - } - int height = args.argsLength() > 2 ? args.getInteger(2) : 1; - - we.checkMaxRadius(radiusX); - we.checkMaxRadius(radiusZ); - we.checkMaxRadius(height); - - Vector pos = session.getPlacementPosition(player); - int affected = editSession.makeCylinder(pos, block, radiusX, radiusZ, height, true); - player.print(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final Pattern block = we.getBlockPattern(player, args.getString(0)); - String[] radiuses = args.getString(1).split(","); - final double radiusX, radiusY, radiusZ; - switch (radiuses.length) { - case 1: - radiusX = radiusY = radiusZ = Math.max(1, Double.parseDouble(radiuses[0])); - break; - - case 3: - radiusX = Math.max(1, Double.parseDouble(radiuses[0])); - radiusY = Math.max(1, Double.parseDouble(radiuses[1])); - radiusZ = Math.max(1, Double.parseDouble(radiuses[2])); - break; - - default: - player.printError("You must either specify 1 or 3 radius values."); - return; - } - - we.checkMaxRadius(radiusX); - we.checkMaxRadius(radiusY); - we.checkMaxRadius(radiusZ); - - final boolean raised; - if (args.argsLength() > 2) { - raised = args.getString(2).equalsIgnoreCase("true") || args.getString(2).equalsIgnoreCase("yes"); - } else { - raised = false; - } - - Vector pos = session.getPlacementPosition(player); - if (raised) { - pos = pos.add(0, radiusY, 0); - } - - int affected = editSession.makeSphere(pos, block, radiusX, radiusY, radiusZ, false); - player.findFreePosition(); - player.print(affected + " block(s) have been created."); - } - - @Command( - aliases = { "/sphere" }, - usage = " [,,] [raised?]", - 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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Pattern block = we.getBlockPattern(player, args.getString(0)); - String[] radiuses = args.getString(1).split(","); - final double radiusX, radiusY, radiusZ; - switch (radiuses.length) { - case 1: - radiusX = radiusY = radiusZ = Math.max(1, Double.parseDouble(radiuses[0])); - break; - - case 3: - radiusX = Math.max(1, Double.parseDouble(radiuses[0])); - radiusY = Math.max(1, Double.parseDouble(radiuses[1])); - radiusZ = Math.max(1, Double.parseDouble(radiuses[2])); - break; - - default: - player.printError("You must either specify 1 or 3 radius values."); - return; - } - - we.checkMaxRadius(radiusX); - we.checkMaxRadius(radiusY); - we.checkMaxRadius(radiusZ); - - final boolean raised; - if (args.argsLength() > 2) { - raised = args.getString(2).equalsIgnoreCase("true") || args.getString(2).equalsIgnoreCase("yes"); - } else { - raised = false; - } - - Vector pos = session.getPlacementPosition(player); - if (raised) { - pos = pos.add(0, radiusY, 0); - } - - int affected = editSession.makeSphere(pos, block, radiusX, radiusY, radiusZ, true); - player.findFreePosition(); - player.print(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 10; - TreeGenerator.TreeType type = args.argsLength() > 1 ? - TreeGenerator.lookup(args.getString(1)) - : TreeGenerator.TreeType.TREE; - double density = args.argsLength() > 2 ? args.getDouble(2) / 100 : 0.05; - - if (type == null) { - player.printError("Tree type '" + args.getString(1) + "' is unknown."); - return; - } - - int affected = editSession.makeForest(session.getPlacementPosition(player), - size, density, new TreeGenerator(type)); - player.print(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 10; - - int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), size); - player.print(affected + " pumpkin patches created."); - } - - @Command( - aliases = { "/pyramid" }, - usage = " ", - desc = "Generate a filled pyramid", - min = 2, - max = 2 - ) - @CommandPermissions("worldedit.generation.pyramid") - @Logging(PLACEMENT) - public void pyramid(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Pattern block = we.getBlockPattern(player, args.getString(0)); - int size = Math.max(1, args.getInteger(1)); - Vector pos = session.getPlacementPosition(player); - - we.checkMaxRadius(size); - - int affected = editSession.makePyramid(pos, block, size, true); - - player.findFreePosition(); - player.print(affected + " block(s) have been created."); - } - - @Command( - aliases = { "/hpyramid" }, - usage = " ", - desc = "Generate a hollow pyramid", - min = 2, - max = 2 - ) - @CommandPermissions("worldedit.generation.pyramid") - @Logging(PLACEMENT) - public void hpyramid(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Pattern block = we.getBlockPattern(player, args.getString(0)); - int size = Math.max(1, args.getInteger(1)); - Vector pos = session.getPlacementPosition(player); - - we.checkMaxRadius(size); - - int affected = editSession.makePyramid(pos, block, size, false); - - player.findFreePosition(); - player.print(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final Pattern pattern = we.getBlockPattern(player, args.getString(0)); - final Region region = session.getSelection(player.getWorld()); - - final boolean hollow = args.hasFlag('h'); - - final String expression = args.getJoinedStrings(1); - - final Vector zero; - Vector unit; - - if (args.hasFlag('r')) { - zero = Vector.ZERO; - unit = Vector.ONE; - } else if (args.hasFlag('o')) { - zero = session.getPlacementPosition(player); - unit = Vector.ONE; - } else if (args.hasFlag('c')) { - 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, pattern, expression, hollow); - player.findFreePosition(); - player.print(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" + - "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", "worldedit.biome.set"}) - @Logging(ALL) - public void generateBiome(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final BiomeType target = we.getServer().getBiomes().get(args.getString(0)); - final Region region = session.getSelection(player.getWorld()); - - final boolean hollow = args.hasFlag('h'); - - final String expression = args.getJoinedStrings(1); - - final Vector zero; - Vector unit; - - if (args.hasFlag('r')) { - zero = Vector.ZERO; - unit = Vector.ONE; - } else if (args.hasFlag('o')) { - zero = session.getPlacementPosition(player); - unit = Vector.ONE; - } else if (args.hasFlag('c')) { - 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("Biome changed to " + target.getName() + ". " + affected + " columns affected."); - } catch (ExpressionException e) { - player.printError(e.getMessage()); - } - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +import static com.sk89q.minecraft.util.commands.Logging.LogMode.ALL; +import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT; +import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION; + +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.BiomeType; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.internal.expression.ExpressionException; +import com.sk89q.worldedit.patterns.Pattern; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.TreeGenerator; + +/** + * Generation commands. + * + * @author sk89q + */ +public class GenerationCommands { + private final WorldEdit we; + + public GenerationCommands(WorldEdit we) { + this.we = we; + } + + @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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Pattern block = we.getBlockPattern(player, args.getString(0)); + String[] radiuses = args.getString(1).split(","); + final double radiusX, radiusZ; + switch (radiuses.length) { + case 1: + radiusX = radiusZ = Math.max(1, Double.parseDouble(radiuses[0])); + break; + + case 2: + radiusX = Math.max(1, Double.parseDouble(radiuses[0])); + radiusZ = Math.max(1, Double.parseDouble(radiuses[1])); + break; + + default: + player.printError("You must either specify 1 or 2 radius values."); + return; + } + int height = args.argsLength() > 2 ? args.getInteger(2) : 1; + + we.checkMaxRadius(radiusX); + we.checkMaxRadius(radiusZ); + we.checkMaxRadius(height); + + Vector pos = session.getPlacementPosition(player); + int affected = editSession.makeCylinder(pos, block, radiusX, radiusZ, height, false); + player.print(affected + " block(s) have been created."); + } + + @Command( + aliases = { "/cyl" }, + usage = " [,] [height]", + 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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Pattern block = we.getBlockPattern(player, args.getString(0)); + String[] radiuses = args.getString(1).split(","); + final double radiusX, radiusZ; + switch (radiuses.length) { + case 1: + radiusX = radiusZ = Math.max(1, Double.parseDouble(radiuses[0])); + break; + + case 2: + radiusX = Math.max(1, Double.parseDouble(radiuses[0])); + radiusZ = Math.max(1, Double.parseDouble(radiuses[1])); + break; + + default: + player.printError("You must either specify 1 or 2 radius values."); + return; + } + int height = args.argsLength() > 2 ? args.getInteger(2) : 1; + + we.checkMaxRadius(radiusX); + we.checkMaxRadius(radiusZ); + we.checkMaxRadius(height); + + Vector pos = session.getPlacementPosition(player); + int affected = editSession.makeCylinder(pos, block, radiusX, radiusZ, height, true); + player.print(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final Pattern block = we.getBlockPattern(player, args.getString(0)); + String[] radiuses = args.getString(1).split(","); + final double radiusX, radiusY, radiusZ; + switch (radiuses.length) { + case 1: + radiusX = radiusY = radiusZ = Math.max(1, Double.parseDouble(radiuses[0])); + break; + + case 3: + radiusX = Math.max(1, Double.parseDouble(radiuses[0])); + radiusY = Math.max(1, Double.parseDouble(radiuses[1])); + radiusZ = Math.max(1, Double.parseDouble(radiuses[2])); + break; + + default: + player.printError("You must either specify 1 or 3 radius values."); + return; + } + + we.checkMaxRadius(radiusX); + we.checkMaxRadius(radiusY); + we.checkMaxRadius(radiusZ); + + final boolean raised; + if (args.argsLength() > 2) { + raised = args.getString(2).equalsIgnoreCase("true") || args.getString(2).equalsIgnoreCase("yes"); + } else { + raised = false; + } + + Vector pos = session.getPlacementPosition(player); + if (raised) { + pos = pos.add(0, radiusY, 0); + } + + int affected = editSession.makeSphere(pos, block, radiusX, radiusY, radiusZ, false); + player.findFreePosition(); + player.print(affected + " block(s) have been created."); + } + + @Command( + aliases = { "/sphere" }, + usage = " [,,] [raised?]", + 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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Pattern block = we.getBlockPattern(player, args.getString(0)); + String[] radiuses = args.getString(1).split(","); + final double radiusX, radiusY, radiusZ; + switch (radiuses.length) { + case 1: + radiusX = radiusY = radiusZ = Math.max(1, Double.parseDouble(radiuses[0])); + break; + + case 3: + radiusX = Math.max(1, Double.parseDouble(radiuses[0])); + radiusY = Math.max(1, Double.parseDouble(radiuses[1])); + radiusZ = Math.max(1, Double.parseDouble(radiuses[2])); + break; + + default: + player.printError("You must either specify 1 or 3 radius values."); + return; + } + + we.checkMaxRadius(radiusX); + we.checkMaxRadius(radiusY); + we.checkMaxRadius(radiusZ); + + final boolean raised; + if (args.argsLength() > 2) { + raised = args.getString(2).equalsIgnoreCase("true") || args.getString(2).equalsIgnoreCase("yes"); + } else { + raised = false; + } + + Vector pos = session.getPlacementPosition(player); + if (raised) { + pos = pos.add(0, radiusY, 0); + } + + int affected = editSession.makeSphere(pos, block, radiusX, radiusY, radiusZ, true); + player.findFreePosition(); + player.print(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 10; + TreeGenerator.TreeType type = args.argsLength() > 1 ? + TreeGenerator.lookup(args.getString(1)) + : TreeGenerator.TreeType.TREE; + double density = args.argsLength() > 2 ? args.getDouble(2) / 100 : 0.05; + + if (type == null) { + player.printError("Tree type '" + args.getString(1) + "' is unknown."); + return; + } + + int affected = editSession.makeForest(session.getPlacementPosition(player), + size, density, new TreeGenerator(type)); + player.print(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 10; + + int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), size); + player.print(affected + " pumpkin patches created."); + } + + @Command( + aliases = { "/pyramid" }, + usage = " ", + desc = "Generate a filled pyramid", + min = 2, + max = 2 + ) + @CommandPermissions("worldedit.generation.pyramid") + @Logging(PLACEMENT) + public void pyramid(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Pattern block = we.getBlockPattern(player, args.getString(0)); + int size = Math.max(1, args.getInteger(1)); + Vector pos = session.getPlacementPosition(player); + + we.checkMaxRadius(size); + + int affected = editSession.makePyramid(pos, block, size, true); + + player.findFreePosition(); + player.print(affected + " block(s) have been created."); + } + + @Command( + aliases = { "/hpyramid" }, + usage = " ", + desc = "Generate a hollow pyramid", + min = 2, + max = 2 + ) + @CommandPermissions("worldedit.generation.pyramid") + @Logging(PLACEMENT) + public void hpyramid(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Pattern block = we.getBlockPattern(player, args.getString(0)); + int size = Math.max(1, args.getInteger(1)); + Vector pos = session.getPlacementPosition(player); + + we.checkMaxRadius(size); + + int affected = editSession.makePyramid(pos, block, size, false); + + player.findFreePosition(); + player.print(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final Pattern pattern = we.getBlockPattern(player, args.getString(0)); + final Region region = session.getSelection(player.getWorld()); + + final boolean hollow = args.hasFlag('h'); + + final String expression = args.getJoinedStrings(1); + + final Vector zero; + Vector unit; + + if (args.hasFlag('r')) { + zero = Vector.ZERO; + unit = Vector.ONE; + } else if (args.hasFlag('o')) { + zero = session.getPlacementPosition(player); + unit = Vector.ONE; + } else if (args.hasFlag('c')) { + 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, pattern, expression, hollow); + player.findFreePosition(); + player.print(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" + + "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", "worldedit.biome.set"}) + @Logging(ALL) + public void generateBiome(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final BiomeType target = we.getServer().getBiomes().get(args.getString(0)); + final Region region = session.getSelection(player.getWorld()); + + final boolean hollow = args.hasFlag('h'); + + final String expression = args.getJoinedStrings(1); + + final Vector zero; + Vector unit; + + if (args.hasFlag('r')) { + zero = Vector.ZERO; + unit = Vector.ONE; + } else if (args.hasFlag('o')) { + zero = session.getPlacementPosition(player); + unit = Vector.ONE; + } else if (args.hasFlag('c')) { + 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("Biome changed to " + target.getName() + ". " + affected + " columns affected."); + } catch (ExpressionException e) { + player.printError(e.getMessage()); + } + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/HistoryCommands.java b/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/commands/HistoryCommands.java rename to src/main/java/com/sk89q/worldedit/command/HistoryCommands.java index 03346ac93..930925ae5 100644 --- a/src/main/java/com/sk89q/worldedit/commands/HistoryCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java @@ -1,123 +1,123 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -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.*; - -/** - * History little commands. - * - * @author sk89q - */ -public class HistoryCommands { - private final WorldEdit we; - - public HistoryCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "/undo", "undo" }, - usage = "[times] [player]", - desc = "Undoes the last action", - min = 0, - max = 2 - ) - @CommandPermissions("worldedit.history.undo") - public void undo(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int times = Math.max(1, args.getInteger(0, 1)); - for (int i = 0; i < times; ++i) { - EditSession undone; - if (args.argsLength() < 2) { - undone = session.undo(session.getBlockBag(player), player); - } else { - player.checkPermission("worldedit.history.undo.other"); - LocalSession sess = we.getSession(args.getString(1)); - if (sess == null) { - player.printError("Unable to find session for " + args.getString(1)); - break; - } - undone = sess.undo(session.getBlockBag(player), player); - } - if (undone != null) { - player.print("Undo successful."); - we.flushBlockBag(player, undone); - } else { - player.printError("Nothing left to undo."); - break; - } - } - } - - @Command( - aliases = { "/redo", "redo" }, - usage = "[times] [player]", - desc = "Redoes the last action (from history)", - min = 0, - max = 2 - ) - @CommandPermissions("worldedit.history.redo") - public void redo(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int times = Math.max(1, args.getInteger(0, 1)); - - for (int i = 0; i < times; ++i) { - EditSession redone; - if (args.argsLength() < 2) { - redone = session.redo(session.getBlockBag(player), player); - } else { - player.checkPermission("worldedit.history.redo.other"); - LocalSession sess = we.getSession(args.getString(1)); - if (sess == null) { - player.printError("Unable to find session for " + args.getString(1)); - break; - } - redone = sess.redo(session.getBlockBag(player), player); - } - if (redone != null) { - player.print("Redo successful."); - we.flushBlockBag(player, redone); - } else { - player.printError("Nothing left to redo."); - } - } - } - - @Command( - aliases = { "/clearhistory", "clearhistory" }, - usage = "", - desc = "Clear your history", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.history.clear") - public void clearHistory(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - session.clearHistory(); - player.print("History cleared."); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +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.*; + +/** + * History little commands. + * + * @author sk89q + */ +public class HistoryCommands { + private final WorldEdit we; + + public HistoryCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "/undo", "undo" }, + usage = "[times] [player]", + desc = "Undoes the last action", + min = 0, + max = 2 + ) + @CommandPermissions("worldedit.history.undo") + public void undo(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int times = Math.max(1, args.getInteger(0, 1)); + for (int i = 0; i < times; ++i) { + EditSession undone; + if (args.argsLength() < 2) { + undone = session.undo(session.getBlockBag(player), player); + } else { + player.checkPermission("worldedit.history.undo.other"); + LocalSession sess = we.getSession(args.getString(1)); + if (sess == null) { + player.printError("Unable to find session for " + args.getString(1)); + break; + } + undone = sess.undo(session.getBlockBag(player), player); + } + if (undone != null) { + player.print("Undo successful."); + we.flushBlockBag(player, undone); + } else { + player.printError("Nothing left to undo."); + break; + } + } + } + + @Command( + aliases = { "/redo", "redo" }, + usage = "[times] [player]", + desc = "Redoes the last action (from history)", + min = 0, + max = 2 + ) + @CommandPermissions("worldedit.history.redo") + public void redo(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int times = Math.max(1, args.getInteger(0, 1)); + + for (int i = 0; i < times; ++i) { + EditSession redone; + if (args.argsLength() < 2) { + redone = session.redo(session.getBlockBag(player), player); + } else { + player.checkPermission("worldedit.history.redo.other"); + LocalSession sess = we.getSession(args.getString(1)); + if (sess == null) { + player.printError("Unable to find session for " + args.getString(1)); + break; + } + redone = sess.redo(session.getBlockBag(player), player); + } + if (redone != null) { + player.print("Redo successful."); + we.flushBlockBag(player, redone); + } else { + player.printError("Nothing left to redo."); + } + } + } + + @Command( + aliases = { "/clearhistory", "clearhistory" }, + usage = "", + desc = "Clear your history", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.history.clear") + public void clearHistory(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + session.clearHistory(); + player.print("History cleared."); + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/InsufficientArgumentsException.java b/src/main/java/com/sk89q/worldedit/command/InsufficientArgumentsException.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/commands/InsufficientArgumentsException.java rename to src/main/java/com/sk89q/worldedit/command/InsufficientArgumentsException.java index 488f99023..2ebd93790 100644 --- a/src/main/java/com/sk89q/worldedit/commands/InsufficientArgumentsException.java +++ b/src/main/java/com/sk89q/worldedit/command/InsufficientArgumentsException.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.commands; +package com.sk89q.worldedit.command; import com.sk89q.worldedit.WorldEditException; diff --git a/src/main/java/com/sk89q/worldedit/commands/NavigationCommands.java b/src/main/java/com/sk89q/worldedit/command/NavigationCommands.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/commands/NavigationCommands.java rename to src/main/java/com/sk89q/worldedit/command/NavigationCommands.java index 17b1df07a..440ba8ef3 100644 --- a/src/main/java/com/sk89q/worldedit/commands/NavigationCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/NavigationCommands.java @@ -1,216 +1,216 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION; - -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.LocalPlayer; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.WorldVector; - -/** - * Navigation commands. - * - * @author sk89q - */ -public class NavigationCommands { - @SuppressWarnings("unused") - private final WorldEdit we; - - public NavigationCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "unstuck", "!" }, - usage = "", - desc = "Escape from being stuck inside a block", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.navigation.unstuck") - public void unstuck(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - player.print("There you go!"); - player.findFreePosition(); - } - - @Command( - aliases = { "ascend", "asc" }, - usage = "[# of levels]", - desc = "Go up a floor", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.navigation.ascend") - public void ascend(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - int levelsToAscend = 0; - if (args.argsLength() == 0) { - levelsToAscend = 1; - } else { - levelsToAscend = args.getInteger(0); - } - int ascentLevels = 1; - while (player.ascendLevel() && levelsToAscend != ascentLevels) { - ++ascentLevels; - } - if (ascentLevels == 0) { - player.printError("No free spot above you found."); - } else { - player.print((ascentLevels != 1) ? "Ascended " + Integer.toString(ascentLevels) + " levels." : "Ascended a level."); - } - } - - @Command( - aliases = { "descend", "desc" }, - usage = "[# of floors]", - desc = "Go down a floor", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.navigation.descend") - public void descend(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - int levelsToDescend = 0; - if (args.argsLength() == 0) { - levelsToDescend = 1; - } else { - levelsToDescend = args.getInteger(0); - } - int descentLevels = 1; - while (player.descendLevel() && levelsToDescend != descentLevels) { - ++descentLevels; - } - if (descentLevels == 0) { - player.printError("No free spot above you found."); - } else { - player.print((descentLevels != 1) ? "Descended " + Integer.toString(descentLevels) + " levels." : "Descended a level."); - } - } - - @Command( - aliases = { "ceil" }, - usage = "[clearance]", - desc = "Go to the celing", - flags = "fg", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.navigation.ceiling") - @Logging(POSITION) - public void ceiling(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final int clearance = args.argsLength() > 0 ? - Math.max(0, args.getInteger(0)) : 0; - - final boolean alwaysGlass = getAlwaysGlass(args); - if (player.ascendToCeiling(clearance, alwaysGlass)) { - player.print("Whoosh!"); - } else { - player.printError("No free spot above you found."); - } - } - - @Command( - aliases = { "thru" }, - usage = "", - desc = "Passthrough walls", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.navigation.thru.command") - public void thru(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - if (player.passThroughForwardWall(6)) { - player.print("Whoosh!"); - } else { - player.printError("No free spot ahead of you found."); - } - } - - @Command( - aliases = { "jumpto", "j" }, - usage = "", - desc = "Teleport to a location", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.navigation.jumpto.command") - public void jumpTo(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - WorldVector pos = player.getSolidBlockTrace(300); - if (pos != null) { - player.findFreePosition(pos); - player.print("Poof!"); - } else { - player.printError("No block in sight!"); - } - } - - @Command( - aliases = { "up" }, - usage = "", - desc = "Go upwards some distance", - flags = "fg", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.navigation.up") - @Logging(POSITION) - public void up(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final int distance = args.getInteger(0); - - final boolean alwaysGlass = getAlwaysGlass(args); - if (player.ascendUpwards(distance, alwaysGlass)) { - player.print("Whoosh!"); - } else { - player.printError("You would hit something above you."); - } - } - - /** - * Helper function for /up and /ceil. - * - * @param args The {@link CommandContext} to extract the flags from. - * @return true, if glass should always be put under the player - */ - private boolean getAlwaysGlass(CommandContext args) { - final LocalConfiguration config = we.getConfiguration(); - - final boolean forceFlight = args.hasFlag('f'); - final boolean forceGlass = args.hasFlag('g'); - - return forceGlass || (config.navigationUseGlass && !forceFlight); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION; + +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.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.WorldVector; + +/** + * Navigation commands. + * + * @author sk89q + */ +public class NavigationCommands { + @SuppressWarnings("unused") + private final WorldEdit we; + + public NavigationCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "unstuck", "!" }, + usage = "", + desc = "Escape from being stuck inside a block", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.navigation.unstuck") + public void unstuck(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + player.print("There you go!"); + player.findFreePosition(); + } + + @Command( + aliases = { "ascend", "asc" }, + usage = "[# of levels]", + desc = "Go up a floor", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.navigation.ascend") + public void ascend(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + int levelsToAscend = 0; + if (args.argsLength() == 0) { + levelsToAscend = 1; + } else { + levelsToAscend = args.getInteger(0); + } + int ascentLevels = 1; + while (player.ascendLevel() && levelsToAscend != ascentLevels) { + ++ascentLevels; + } + if (ascentLevels == 0) { + player.printError("No free spot above you found."); + } else { + player.print((ascentLevels != 1) ? "Ascended " + Integer.toString(ascentLevels) + " levels." : "Ascended a level."); + } + } + + @Command( + aliases = { "descend", "desc" }, + usage = "[# of floors]", + desc = "Go down a floor", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.navigation.descend") + public void descend(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + int levelsToDescend = 0; + if (args.argsLength() == 0) { + levelsToDescend = 1; + } else { + levelsToDescend = args.getInteger(0); + } + int descentLevels = 1; + while (player.descendLevel() && levelsToDescend != descentLevels) { + ++descentLevels; + } + if (descentLevels == 0) { + player.printError("No free spot above you found."); + } else { + player.print((descentLevels != 1) ? "Descended " + Integer.toString(descentLevels) + " levels." : "Descended a level."); + } + } + + @Command( + aliases = { "ceil" }, + usage = "[clearance]", + desc = "Go to the celing", + flags = "fg", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.navigation.ceiling") + @Logging(POSITION) + public void ceiling(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final int clearance = args.argsLength() > 0 ? + Math.max(0, args.getInteger(0)) : 0; + + final boolean alwaysGlass = getAlwaysGlass(args); + if (player.ascendToCeiling(clearance, alwaysGlass)) { + player.print("Whoosh!"); + } else { + player.printError("No free spot above you found."); + } + } + + @Command( + aliases = { "thru" }, + usage = "", + desc = "Passthrough walls", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.navigation.thru.command") + public void thru(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + if (player.passThroughForwardWall(6)) { + player.print("Whoosh!"); + } else { + player.printError("No free spot ahead of you found."); + } + } + + @Command( + aliases = { "jumpto", "j" }, + usage = "", + desc = "Teleport to a location", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.navigation.jumpto.command") + public void jumpTo(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + WorldVector pos = player.getSolidBlockTrace(300); + if (pos != null) { + player.findFreePosition(pos); + player.print("Poof!"); + } else { + player.printError("No block in sight!"); + } + } + + @Command( + aliases = { "up" }, + usage = "", + desc = "Go upwards some distance", + flags = "fg", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.navigation.up") + @Logging(POSITION) + public void up(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final int distance = args.getInteger(0); + + final boolean alwaysGlass = getAlwaysGlass(args); + if (player.ascendUpwards(distance, alwaysGlass)) { + player.print("Whoosh!"); + } else { + player.printError("You would hit something above you."); + } + } + + /** + * Helper function for /up and /ceil. + * + * @param args The {@link CommandContext} to extract the flags from. + * @return true, if glass should always be put under the player + */ + private boolean getAlwaysGlass(CommandContext args) { + final LocalConfiguration config = we.getConfiguration(); + + final boolean forceFlight = args.hasFlag('f'); + final boolean forceGlass = args.hasFlag('g'); + + return forceGlass || (config.navigationUseGlass && !forceFlight); + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/command/RegionCommands.java similarity index 97% rename from src/main/java/com/sk89q/worldedit/commands/RegionCommands.java rename to src/main/java/com/sk89q/worldedit/command/RegionCommands.java index b0e2f7442..ccaa0bf60 100644 --- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -1,585 +1,585 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -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.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockID; -import com.sk89q.worldedit.expression.ExpressionException; -import com.sk89q.worldedit.function.mask.ExistingBlockMask; -import com.sk89q.worldedit.function.operation.Operations; -import com.sk89q.worldedit.math.convolution.GaussianKernel; -import com.sk89q.worldedit.math.convolution.HeightMap; -import com.sk89q.worldedit.math.convolution.HeightMapFilter; -import com.sk89q.worldedit.function.GroundFunction; -import com.sk89q.worldedit.function.generator.FloraGenerator; -import com.sk89q.worldedit.function.generator.ForestGenerator; -import com.sk89q.worldedit.function.visitor.LayerVisitor; -import com.sk89q.worldedit.masks.Mask; -import com.sk89q.worldedit.function.mask.NoiseFilter2D; -import com.sk89q.worldedit.patterns.Pattern; -import com.sk89q.worldedit.patterns.SingleBlockPattern; -import com.sk89q.worldedit.regions.ConvexPolyhedralRegion; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.regions.RegionOperationException; -import com.sk89q.worldedit.util.TreeGenerator; -import com.sk89q.worldedit.math.noise.RandomNoise; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import static com.sk89q.minecraft.util.commands.Logging.LogMode.*; -import static com.sk89q.worldedit.regions.Regions.*; - -/** - * Region related commands. - * - * @author sk89q - */ -public class RegionCommands { - private final WorldEdit we; - - public RegionCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "/set" }, - usage = "", - desc = "Set all the blocks inside the selection to a block", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.region.set") - @Logging(REGION) - public void set(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Pattern pattern = we.getBlockPattern(player, args.getString(0)); - - int affected; - - if (pattern instanceof SingleBlockPattern) { - affected = editSession.setBlocks(session.getSelection(player.getWorld()), - ((SingleBlockPattern) pattern).getBlock()); - } else { - affected = editSession.setBlocks(session.getSelection(player.getWorld()), pattern); - } - - player.print(affected + " block(s) have been changed."); - } - - @Command( - aliases = { "/line" }, - usage = " [thickness]", - desc = "Draws a line segment between cuboid selection corners", - help = - "Draws a line segment between cuboid selection corners.\n" + - "Can only be used with cuboid selections.\n" + - "Flags:\n" + - " -h generates only a shell", - flags = "h", - min = 1, - max = 2 - ) - @CommandPermissions("worldedit.region.line") - @Logging(REGION) - public void line(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Region region = session.getSelection(session.getSelectionWorld()); - if (!(region instanceof CuboidRegion)) { - player.printError("Invalid region type"); - return; - } - if (args.argsLength() < 2 ? false : args.getDouble(1) < 0) { - player.printError("Invalid thickness. Must not be negative"); - return; - } - - Pattern pattern = we.getBlockPattern(player, args.getString(0)); - CuboidRegion cuboidregion = (CuboidRegion) region; - Vector pos1 = cuboidregion.getPos1(); - Vector pos2 = cuboidregion.getPos2(); - int blocksChanged = editSession.drawLine(pattern, pos1, pos2, args.argsLength() < 2 ? 0 : args.getDouble(1), !args.hasFlag('h')); - - player.print(blocksChanged + " block(s) have been changed."); - } - - @Command( - aliases = { "/curve" }, - usage = " [thickness]", - desc = "Draws a spline through selected points", - help = - "Draws a spline through selected points.\n" + - "Can only be uesd with convex polyhedral selections.\n" + - "Flags:\n" + - " -h generates only a shell", - flags = "h", - min = 1, - max = 2 - ) - @CommandPermissions("worldedit.region.curve") - @Logging(REGION) - public void curve(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Region region = session.getSelection(session.getSelectionWorld()); - if (!(region instanceof ConvexPolyhedralRegion)) { - player.printError("Invalid region type"); - return; - } - if (args.argsLength() < 2 ? false : args.getDouble(1) < 0) { - player.printError("Invalid thickness. Must not be negative"); - return; - } - - Pattern pattern = we.getBlockPattern(player, args.getString(0)); - ConvexPolyhedralRegion cpregion = (ConvexPolyhedralRegion) region; - List vectors = new ArrayList(cpregion.getVertices()); - - int blocksChanged = editSession.drawSpline(pattern, vectors, 0, 0, 0, 10, args.argsLength() < 2 ? 0 : args.getDouble(1), !args.hasFlag('h')); - - player.print(blocksChanged + " block(s) have been changed."); - } - - @Command( - aliases = { "/replace", "/re", "/rep" }, - usage = "[from-block] ", - desc = "Replace all blocks in the selection with another", - flags = "f", - min = 1, - max = 2 - ) - @CommandPermissions("worldedit.region.replace") - @Logging(REGION) - public void replace(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Set from; - Pattern to; - if (args.argsLength() == 1) { - from = null; - to = we.getBlockPattern(player, args.getString(0)); - } else { - from = we.getBlocks(player, args.getString(0), true, !args.hasFlag('f')); - to = we.getBlockPattern(player, args.getString(1)); - } - - final int affected; - if (to instanceof SingleBlockPattern) { - affected = editSession.replaceBlocks(session.getSelection(player.getWorld()), from, - ((SingleBlockPattern) to).getBlock()); - } else { - affected = editSession.replaceBlocks(session.getSelection(player.getWorld()), from, to); - } - - player.print(affected + " block(s) have been replaced."); - } - - @Command( - aliases = { "/overlay" }, - usage = "", - desc = "Set a block on top of blocks in the region", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.region.overlay") - @Logging(REGION) - public void overlay(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Pattern pat = we.getBlockPattern(player, args.getString(0)); - - Region region = session.getSelection(player.getWorld()); - int affected = 0; - if (pat instanceof SingleBlockPattern) { - affected = editSession.overlayCuboidBlocks(region, - ((SingleBlockPattern) pat).getBlock()); - } else { - affected = editSession.overlayCuboidBlocks(region, pat); - } - player.print(affected + " block(s) have been overlayed."); - } - - @Command( - aliases = { "/center", "/middle" }, - usage = "", - desc = "Set the center block(s)", - min = 1, - max = 1 - ) - @Logging(REGION) - @CommandPermissions("worldedit.region.center") - public void center(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - Pattern pattern = we.getBlockPattern(player, args.getString(0)); - Region region = session.getSelection(player.getWorld()); - - int affected = editSession.center(region, pattern); - player.print("Center set ("+ affected + " blocks changed)"); - } - - @Command( - aliases = { "/naturalize" }, - usage = "", - desc = "3 layers of dirt on top then rock below", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.region.naturalize") - @Logging(REGION) - public void naturalize(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Region region = session.getSelection(player.getWorld()); - int affected = editSession.naturalizeCuboidBlocks(region); - player.print(affected + " block(s) have been naturalized."); - } - - @Command( - aliases = { "/walls" }, - usage = "", - desc = "Build the four sides of the selection", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.region.walls") - @Logging(REGION) - public void walls(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final Pattern pattern = we.getBlockPattern(player, args.getString(0)); - final int affected; - final Region region = session.getSelection(player.getWorld()); - if (!(region instanceof CuboidRegion)) { - affected = editSession.makeWalls(region, pattern); - } else if (pattern instanceof SingleBlockPattern) { - affected = editSession.makeCuboidWalls(region, ((SingleBlockPattern) pattern).getBlock()); - } else { - affected = editSession.makeCuboidWalls(region, pattern); - } - - player.print(affected + " block(s) have been changed."); - } - - @Command( - aliases = { "/faces", "/outline" }, - usage = "", - desc = "Build the walls, ceiling, and floor of a selection", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.region.faces") - @Logging(REGION) - public void faces(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final Pattern pattern = we.getBlockPattern(player, args.getString(0)); - final int affected; - final Region region = session.getSelection(player.getWorld()); - if (!(region instanceof CuboidRegion)) { - affected = editSession.makeFaces(region, pattern); - } else if (pattern instanceof SingleBlockPattern) { - affected = editSession.makeCuboidFaces(region, ((SingleBlockPattern) pattern).getBlock()); - } else { - affected = editSession.makeCuboidFaces(region, pattern); - } - - player.print(affected + " block(s) have been changed."); - } - - @Command( - aliases = { "/smooth" }, - usage = "[iterations]", - flags = "n", - desc = "Smooth the elevation in the selection", - help = - "Smooths the elevation in the selection.\n" + - "The -n flag makes it only consider naturally occuring blocks.", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.region.smooth") - @Logging(REGION) - public void smooth(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int iterations = 1; - if (args.argsLength() > 0) { - iterations = args.getInteger(0); - } - - HeightMap heightMap = new HeightMap(editSession, session.getSelection(player.getWorld()), args.hasFlag('n')); - HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0)); - int affected = heightMap.applyFilter(filter, iterations); - player.print("Terrain's height map smoothed. " + affected + " block(s) changed."); - - } - - @Command( - aliases = { "/move" }, - usage = "[count] [direction] [leave-id]", - flags = "s", - desc = "Move the contents of the selection", - help = - "Moves the contents of the selection.\n" + - "The -s flag shifts the selection to the target location.\n" + - "Optionally fills the old location with .", - min = 0, - max = 3 - ) - @CommandPermissions("worldedit.region.move") - @Logging(ORIENTATION_REGION) - public void move(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int count = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1; - Vector dir = we.getDirection(player, - args.argsLength() > 1 ? args.getString(1).toLowerCase() : "me"); - BaseBlock replace; - - // Replacement block argument - if (args.argsLength() > 2) { - replace = we.getBlock(player, args.getString(2)); - } else { - replace = new BaseBlock(BlockID.AIR); - } - - int affected = editSession.moveRegion(session.getSelection(player.getWorld()), - dir, count, true, replace); - - if (args.hasFlag('s')) { - try { - Region region = session.getSelection(player.getWorld()); - region.shift(dir.multiply(count)); - - session.getRegionSelector(player.getWorld()).learnChanges(); - session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); - } catch (RegionOperationException e) { - player.printError(e.getMessage()); - } - } - - player.print(affected + " blocks moved."); - } - - @Command( - aliases = { "/stack" }, - usage = "[count] [direction]", - flags = "sa", - desc = "Repeat the contents of the selection", - help = - "Repeats the contents of the selection.\n" + - "Flags:\n" + - " -s shifts the selection to the last stacked copy\n" + - " -a skips air blocks", - min = 0, - max = 2 - ) - @CommandPermissions("worldedit.region.stack") - @Logging(ORIENTATION_REGION) - public void stack(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int count = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1; - Vector dir = we.getDiagonalDirection(player, - args.argsLength() > 1 ? args.getString(1).toLowerCase() : "me"); - - int affected = editSession.stackCuboidRegion(session.getSelection(player.getWorld()), - dir, count, !args.hasFlag('a')); - - if (args.hasFlag('s')) { - try { - final Region region = session.getSelection(player.getWorld()); - final Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()); - - final Vector shiftVector = dir.multiply(count * (Math.abs(dir.dot(size)) + 1)); - region.shift(shiftVector); - - session.getRegionSelector(player.getWorld()).learnChanges(); - session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); - } catch (RegionOperationException e) { - player.printError(e.getMessage()); - } - } - - player.print(affected + " blocks changed. Undo with //undo"); - } - - @Command( - aliases = { "/regen" }, - usage = "", - 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 - ) - @CommandPermissions("worldedit.regen") - @Logging(REGION) - public void regenerateChunk(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Region region = session.getSelection(player.getWorld()); - Mask mask = session.getMask(); - session.setMask(null); - player.getWorld().regenerate(region, editSession); - session.setMask(mask); - player.print("Region regenerated."); - } - - @Command( - aliases = { "/deform" }, - usage = "", - desc = "Deforms a selected region with an expression", - help = - "Deforms a selected region with an expression\n" + - "The expression is executed for each block and is expected\n" + - "to modify the variables x, y and z to point to a new block\n" + - "to fetch. See also tinyurl.com/wesyntax.", - flags = "ro", - min = 1, - max = -1 - ) - @CommandPermissions("worldedit.region.deform") - @Logging(ALL) - public void deform(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final Region region = session.getSelection(player.getWorld()); - - final String expression = args.getJoinedStrings(0); - - final Vector zero; - Vector unit; - - if (args.hasFlag('r')) { - zero = Vector.ZERO; - unit = Vector.ONE; - } else if (args.hasFlag('o')) { - zero = session.getPlacementPosition(player); - 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.deformRegion(region, zero, unit, expression); - player.findFreePosition(); - player.print(affected + " block(s) have been deformed."); - } catch (ExpressionException e) { - player.printError(e.getMessage()); - } - } - - @Command( - aliases = { "/hollow" }, - usage = "[[ ]]", - desc = "Hollows out the object contained in this selection", - help = - "Hollows out the object contained in this selection.\n" + - "Optionally fills the hollowed out part with the given block.\n" + - "Thickness is measured in manhattan distance.", - min = 0, - max = 2 - ) - @CommandPermissions("worldedit.region.hollow") - @Logging(REGION) - public void hollow(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final int thickness = args.argsLength() >= 1 ? Math.max(1, args.getInteger(0)) : 1; - final Pattern pattern = args.argsLength() >= 2 ? we.getBlockPattern(player, args.getString(1)) : new SingleBlockPattern(new BaseBlock(BlockID.AIR)); - - final int affected = editSession.hollowOutRegion(session.getSelection(player.getWorld()), thickness, pattern); - - player.print(affected + " block(s) have been changed."); - } - - @Command( - aliases = { "/forest" }, - usage = "[type] [density]", - desc = "Make a forest within the region", - min = 0, - max = 2 - ) - @CommandPermissions("worldedit.region.forest") - @Logging(REGION) - public void forest(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - TreeGenerator.TreeType type = args.argsLength() > 0 ? TreeGenerator.lookup(args.getString(0)) : TreeGenerator.TreeType.TREE; - double density = args.argsLength() > 1 ? args.getDouble(1) / 100 : 0.05; - - if (type == null) { - player.printError("Tree type '" + args.getString(0) + "' is unknown."); - return; - } - - Region region = session.getSelection(player.getWorld()); - - ForestGenerator generator = new ForestGenerator(editSession, new TreeGenerator(type)); - GroundFunction ground = new GroundFunction(new ExistingBlockMask(editSession), generator); - LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground); - visitor.setMask(new NoiseFilter2D(new RandomNoise(), density)); - Operations.completeLegacy(visitor); - - player.print(ground.getAffected() + " trees created."); - } - - @Command( - aliases = { "/flora" }, - usage = "[density]", - desc = "Make flora within the region", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.region.flora") - @Logging(REGION) - public void flora(CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { - double density = args.argsLength() > 0 ? args.getDouble(0) / 100 : 0.1; - - Region region = session.getSelection(player.getWorld()); - FloraGenerator generator = new FloraGenerator(editSession); - GroundFunction ground = new GroundFunction(new ExistingBlockMask(editSession), generator); - LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground); - visitor.setMask(new NoiseFilter2D(new RandomNoise(), density)); - Operations.completeLegacy(visitor); - - player.print(ground.getAffected() + " flora created."); - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +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.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.internal.expression.ExpressionException; +import com.sk89q.worldedit.function.mask.ExistingBlockMask; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.convolution.GaussianKernel; +import com.sk89q.worldedit.math.convolution.HeightMap; +import com.sk89q.worldedit.math.convolution.HeightMapFilter; +import com.sk89q.worldedit.function.GroundFunction; +import com.sk89q.worldedit.function.generator.FloraGenerator; +import com.sk89q.worldedit.function.generator.ForestGenerator; +import com.sk89q.worldedit.function.visitor.LayerVisitor; +import com.sk89q.worldedit.masks.Mask; +import com.sk89q.worldedit.function.mask.NoiseFilter2D; +import com.sk89q.worldedit.patterns.Pattern; +import com.sk89q.worldedit.patterns.SingleBlockPattern; +import com.sk89q.worldedit.regions.ConvexPolyhedralRegion; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.regions.RegionOperationException; +import com.sk89q.worldedit.util.TreeGenerator; +import com.sk89q.worldedit.math.noise.RandomNoise; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static com.sk89q.minecraft.util.commands.Logging.LogMode.*; +import static com.sk89q.worldedit.regions.Regions.*; + +/** + * Region related commands. + * + * @author sk89q + */ +public class RegionCommands { + private final WorldEdit we; + + public RegionCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "/set" }, + usage = "", + desc = "Set all the blocks inside the selection to a block", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.region.set") + @Logging(REGION) + public void set(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Pattern pattern = we.getBlockPattern(player, args.getString(0)); + + int affected; + + if (pattern instanceof SingleBlockPattern) { + affected = editSession.setBlocks(session.getSelection(player.getWorld()), + ((SingleBlockPattern) pattern).getBlock()); + } else { + affected = editSession.setBlocks(session.getSelection(player.getWorld()), pattern); + } + + player.print(affected + " block(s) have been changed."); + } + + @Command( + aliases = { "/line" }, + usage = " [thickness]", + desc = "Draws a line segment between cuboid selection corners", + help = + "Draws a line segment between cuboid selection corners.\n" + + "Can only be used with cuboid selections.\n" + + "Flags:\n" + + " -h generates only a shell", + flags = "h", + min = 1, + max = 2 + ) + @CommandPermissions("worldedit.region.line") + @Logging(REGION) + public void line(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Region region = session.getSelection(session.getSelectionWorld()); + if (!(region instanceof CuboidRegion)) { + player.printError("Invalid region type"); + return; + } + if (args.argsLength() < 2 ? false : args.getDouble(1) < 0) { + player.printError("Invalid thickness. Must not be negative"); + return; + } + + Pattern pattern = we.getBlockPattern(player, args.getString(0)); + CuboidRegion cuboidregion = (CuboidRegion) region; + Vector pos1 = cuboidregion.getPos1(); + Vector pos2 = cuboidregion.getPos2(); + int blocksChanged = editSession.drawLine(pattern, pos1, pos2, args.argsLength() < 2 ? 0 : args.getDouble(1), !args.hasFlag('h')); + + player.print(blocksChanged + " block(s) have been changed."); + } + + @Command( + aliases = { "/curve" }, + usage = " [thickness]", + desc = "Draws a spline through selected points", + help = + "Draws a spline through selected points.\n" + + "Can only be uesd with convex polyhedral selections.\n" + + "Flags:\n" + + " -h generates only a shell", + flags = "h", + min = 1, + max = 2 + ) + @CommandPermissions("worldedit.region.curve") + @Logging(REGION) + public void curve(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Region region = session.getSelection(session.getSelectionWorld()); + if (!(region instanceof ConvexPolyhedralRegion)) { + player.printError("Invalid region type"); + return; + } + if (args.argsLength() < 2 ? false : args.getDouble(1) < 0) { + player.printError("Invalid thickness. Must not be negative"); + return; + } + + Pattern pattern = we.getBlockPattern(player, args.getString(0)); + ConvexPolyhedralRegion cpregion = (ConvexPolyhedralRegion) region; + List vectors = new ArrayList(cpregion.getVertices()); + + int blocksChanged = editSession.drawSpline(pattern, vectors, 0, 0, 0, 10, args.argsLength() < 2 ? 0 : args.getDouble(1), !args.hasFlag('h')); + + player.print(blocksChanged + " block(s) have been changed."); + } + + @Command( + aliases = { "/replace", "/re", "/rep" }, + usage = "[from-block] ", + desc = "Replace all blocks in the selection with another", + flags = "f", + min = 1, + max = 2 + ) + @CommandPermissions("worldedit.region.replace") + @Logging(REGION) + public void replace(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Set from; + Pattern to; + if (args.argsLength() == 1) { + from = null; + to = we.getBlockPattern(player, args.getString(0)); + } else { + from = we.getBlocks(player, args.getString(0), true, !args.hasFlag('f')); + to = we.getBlockPattern(player, args.getString(1)); + } + + final int affected; + if (to instanceof SingleBlockPattern) { + affected = editSession.replaceBlocks(session.getSelection(player.getWorld()), from, + ((SingleBlockPattern) to).getBlock()); + } else { + affected = editSession.replaceBlocks(session.getSelection(player.getWorld()), from, to); + } + + player.print(affected + " block(s) have been replaced."); + } + + @Command( + aliases = { "/overlay" }, + usage = "", + desc = "Set a block on top of blocks in the region", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.region.overlay") + @Logging(REGION) + public void overlay(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Pattern pat = we.getBlockPattern(player, args.getString(0)); + + Region region = session.getSelection(player.getWorld()); + int affected = 0; + if (pat instanceof SingleBlockPattern) { + affected = editSession.overlayCuboidBlocks(region, + ((SingleBlockPattern) pat).getBlock()); + } else { + affected = editSession.overlayCuboidBlocks(region, pat); + } + player.print(affected + " block(s) have been overlayed."); + } + + @Command( + aliases = { "/center", "/middle" }, + usage = "", + desc = "Set the center block(s)", + min = 1, + max = 1 + ) + @Logging(REGION) + @CommandPermissions("worldedit.region.center") + public void center(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + Pattern pattern = we.getBlockPattern(player, args.getString(0)); + Region region = session.getSelection(player.getWorld()); + + int affected = editSession.center(region, pattern); + player.print("Center set ("+ affected + " blocks changed)"); + } + + @Command( + aliases = { "/naturalize" }, + usage = "", + desc = "3 layers of dirt on top then rock below", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.region.naturalize") + @Logging(REGION) + public void naturalize(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Region region = session.getSelection(player.getWorld()); + int affected = editSession.naturalizeCuboidBlocks(region); + player.print(affected + " block(s) have been naturalized."); + } + + @Command( + aliases = { "/walls" }, + usage = "", + desc = "Build the four sides of the selection", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.region.walls") + @Logging(REGION) + public void walls(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final Pattern pattern = we.getBlockPattern(player, args.getString(0)); + final int affected; + final Region region = session.getSelection(player.getWorld()); + if (!(region instanceof CuboidRegion)) { + affected = editSession.makeWalls(region, pattern); + } else if (pattern instanceof SingleBlockPattern) { + affected = editSession.makeCuboidWalls(region, ((SingleBlockPattern) pattern).getBlock()); + } else { + affected = editSession.makeCuboidWalls(region, pattern); + } + + player.print(affected + " block(s) have been changed."); + } + + @Command( + aliases = { "/faces", "/outline" }, + usage = "", + desc = "Build the walls, ceiling, and floor of a selection", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.region.faces") + @Logging(REGION) + public void faces(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final Pattern pattern = we.getBlockPattern(player, args.getString(0)); + final int affected; + final Region region = session.getSelection(player.getWorld()); + if (!(region instanceof CuboidRegion)) { + affected = editSession.makeFaces(region, pattern); + } else if (pattern instanceof SingleBlockPattern) { + affected = editSession.makeCuboidFaces(region, ((SingleBlockPattern) pattern).getBlock()); + } else { + affected = editSession.makeCuboidFaces(region, pattern); + } + + player.print(affected + " block(s) have been changed."); + } + + @Command( + aliases = { "/smooth" }, + usage = "[iterations]", + flags = "n", + desc = "Smooth the elevation in the selection", + help = + "Smooths the elevation in the selection.\n" + + "The -n flag makes it only consider naturally occuring blocks.", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.region.smooth") + @Logging(REGION) + public void smooth(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int iterations = 1; + if (args.argsLength() > 0) { + iterations = args.getInteger(0); + } + + HeightMap heightMap = new HeightMap(editSession, session.getSelection(player.getWorld()), args.hasFlag('n')); + HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0)); + int affected = heightMap.applyFilter(filter, iterations); + player.print("Terrain's height map smoothed. " + affected + " block(s) changed."); + + } + + @Command( + aliases = { "/move" }, + usage = "[count] [direction] [leave-id]", + flags = "s", + desc = "Move the contents of the selection", + help = + "Moves the contents of the selection.\n" + + "The -s flag shifts the selection to the target location.\n" + + "Optionally fills the old location with .", + min = 0, + max = 3 + ) + @CommandPermissions("worldedit.region.move") + @Logging(ORIENTATION_REGION) + public void move(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int count = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1; + Vector dir = we.getDirection(player, + args.argsLength() > 1 ? args.getString(1).toLowerCase() : "me"); + BaseBlock replace; + + // Replacement block argument + if (args.argsLength() > 2) { + replace = we.getBlock(player, args.getString(2)); + } else { + replace = new BaseBlock(BlockID.AIR); + } + + int affected = editSession.moveRegion(session.getSelection(player.getWorld()), + dir, count, true, replace); + + if (args.hasFlag('s')) { + try { + Region region = session.getSelection(player.getWorld()); + region.shift(dir.multiply(count)); + + session.getRegionSelector(player.getWorld()).learnChanges(); + session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); + } catch (RegionOperationException e) { + player.printError(e.getMessage()); + } + } + + player.print(affected + " blocks moved."); + } + + @Command( + aliases = { "/stack" }, + usage = "[count] [direction]", + flags = "sa", + desc = "Repeat the contents of the selection", + help = + "Repeats the contents of the selection.\n" + + "Flags:\n" + + " -s shifts the selection to the last stacked copy\n" + + " -a skips air blocks", + min = 0, + max = 2 + ) + @CommandPermissions("worldedit.region.stack") + @Logging(ORIENTATION_REGION) + public void stack(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int count = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1; + Vector dir = we.getDiagonalDirection(player, + args.argsLength() > 1 ? args.getString(1).toLowerCase() : "me"); + + int affected = editSession.stackCuboidRegion(session.getSelection(player.getWorld()), + dir, count, !args.hasFlag('a')); + + if (args.hasFlag('s')) { + try { + final Region region = session.getSelection(player.getWorld()); + final Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()); + + final Vector shiftVector = dir.multiply(count * (Math.abs(dir.dot(size)) + 1)); + region.shift(shiftVector); + + session.getRegionSelector(player.getWorld()).learnChanges(); + session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); + } catch (RegionOperationException e) { + player.printError(e.getMessage()); + } + } + + player.print(affected + " blocks changed. Undo with //undo"); + } + + @Command( + aliases = { "/regen" }, + usage = "", + 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 + ) + @CommandPermissions("worldedit.regen") + @Logging(REGION) + public void regenerateChunk(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Region region = session.getSelection(player.getWorld()); + Mask mask = session.getMask(); + session.setMask(null); + player.getWorld().regenerate(region, editSession); + session.setMask(mask); + player.print("Region regenerated."); + } + + @Command( + aliases = { "/deform" }, + usage = "", + desc = "Deforms a selected region with an expression", + help = + "Deforms a selected region with an expression\n" + + "The expression is executed for each block and is expected\n" + + "to modify the variables x, y and z to point to a new block\n" + + "to fetch. See also tinyurl.com/wesyntax.", + flags = "ro", + min = 1, + max = -1 + ) + @CommandPermissions("worldedit.region.deform") + @Logging(ALL) + public void deform(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final Region region = session.getSelection(player.getWorld()); + + final String expression = args.getJoinedStrings(0); + + final Vector zero; + Vector unit; + + if (args.hasFlag('r')) { + zero = Vector.ZERO; + unit = Vector.ONE; + } else if (args.hasFlag('o')) { + zero = session.getPlacementPosition(player); + 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.deformRegion(region, zero, unit, expression); + player.findFreePosition(); + player.print(affected + " block(s) have been deformed."); + } catch (ExpressionException e) { + player.printError(e.getMessage()); + } + } + + @Command( + aliases = { "/hollow" }, + usage = "[[ ]]", + desc = "Hollows out the object contained in this selection", + help = + "Hollows out the object contained in this selection.\n" + + "Optionally fills the hollowed out part with the given block.\n" + + "Thickness is measured in manhattan distance.", + min = 0, + max = 2 + ) + @CommandPermissions("worldedit.region.hollow") + @Logging(REGION) + public void hollow(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final int thickness = args.argsLength() >= 1 ? Math.max(1, args.getInteger(0)) : 1; + final Pattern pattern = args.argsLength() >= 2 ? we.getBlockPattern(player, args.getString(1)) : new SingleBlockPattern(new BaseBlock(BlockID.AIR)); + + final int affected = editSession.hollowOutRegion(session.getSelection(player.getWorld()), thickness, pattern); + + player.print(affected + " block(s) have been changed."); + } + + @Command( + aliases = { "/forest" }, + usage = "[type] [density]", + desc = "Make a forest within the region", + min = 0, + max = 2 + ) + @CommandPermissions("worldedit.region.forest") + @Logging(REGION) + public void forest(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + TreeGenerator.TreeType type = args.argsLength() > 0 ? TreeGenerator.lookup(args.getString(0)) : TreeGenerator.TreeType.TREE; + double density = args.argsLength() > 1 ? args.getDouble(1) / 100 : 0.05; + + if (type == null) { + player.printError("Tree type '" + args.getString(0) + "' is unknown."); + return; + } + + Region region = session.getSelection(player.getWorld()); + + ForestGenerator generator = new ForestGenerator(editSession, new TreeGenerator(type)); + GroundFunction ground = new GroundFunction(new ExistingBlockMask(editSession), generator); + LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground); + visitor.setMask(new NoiseFilter2D(new RandomNoise(), density)); + Operations.completeLegacy(visitor); + + player.print(ground.getAffected() + " trees created."); + } + + @Command( + aliases = { "/flora" }, + usage = "[density]", + desc = "Make flora within the region", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.region.flora") + @Logging(REGION) + public void flora(CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { + double density = args.argsLength() > 0 ? args.getDouble(0) / 100 : 0.1; + + Region region = session.getSelection(player.getWorld()); + FloraGenerator generator = new FloraGenerator(editSession); + GroundFunction ground = new GroundFunction(new ExistingBlockMask(editSession), generator); + LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground); + visitor.setMask(new NoiseFilter2D(new RandomNoise(), density)); + Operations.completeLegacy(visitor); + + player.print(ground.getAffected() + " flora created."); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/commands/SchematicCommands.java b/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java similarity index 98% rename from src/main/java/com/sk89q/worldedit/commands/SchematicCommands.java rename to src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index 8c5114273..7c768cc81 100644 --- a/src/main/java/com/sk89q/worldedit/commands/SchematicCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.commands; +package com.sk89q.worldedit.command; import java.io.File; import java.io.IOException; @@ -35,13 +35,13 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.schematic.SchematicFormat; /** * Commands related to schematics * - * @see com.sk89q.worldedit.commands.ClipboardCommands#schematic() + * @see com.sk89q.worldedit.command.ClipboardCommands#schematic() */ public class SchematicCommands { private final WorldEdit we; diff --git a/src/main/java/com/sk89q/worldedit/commands/ScriptingCommands.java b/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/commands/ScriptingCommands.java rename to src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java index 170ccfa88..452e6c2d2 100644 --- a/src/main/java/com/sk89q/worldedit/commands/ScriptingCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java @@ -1,101 +1,101 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -import java.io.File; -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 static com.sk89q.minecraft.util.commands.Logging.LogMode.*; -import com.sk89q.worldedit.*; - -/** - * Scripting commands. - * - * @author sk89q - */ -public class ScriptingCommands { - private final WorldEdit we; - - public ScriptingCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "cs" }, - usage = " [args...]", - desc = "Execute a CraftScript", - min = 1, - max = -1 - ) - @CommandPermissions("worldedit.scripting.execute") - @Logging(ALL) - public void execute(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - String[] scriptArgs = args.getSlice(1); - String name = args.getString(0); - - if (!player.hasPermission("worldedit.scripting.execute." + name)) { - player.printError("You don't have permission to use that script."); - return; - } - - session.setLastScript(name); - - File dir = we.getWorkingDirectoryFile(we.getConfiguration().scriptsDir); - File f = we.getSafeOpenFile(player, dir, name, "js", "js"); - - we.runScript(player, f, scriptArgs); - } - - @Command( - aliases = { ".s" }, - usage = "[args...]", - desc = "Execute last CraftScript", - min = 0, - max = -1 - ) - @CommandPermissions("worldedit.scripting.execute") - @Logging(ALL) - public void executeLast(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - String lastScript = session.getLastScript(); - - if (!player.hasPermission("worldedit.scripting.execute." + lastScript)) { - player.printError("You don't have permission to use that script."); - return; - } - - if (lastScript == null) { - player.printError("Use /cs with a script name first."); - return; - } - - String[] scriptArgs = args.getSlice(0); - - File dir = we.getWorkingDirectoryFile(we.getConfiguration().scriptsDir); - File f = we.getSafeOpenFile(player, dir, lastScript, "js", "js"); - - we.runScript(player, f, scriptArgs); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +import java.io.File; +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 static com.sk89q.minecraft.util.commands.Logging.LogMode.*; +import com.sk89q.worldedit.*; + +/** + * Scripting commands. + * + * @author sk89q + */ +public class ScriptingCommands { + private final WorldEdit we; + + public ScriptingCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "cs" }, + usage = " [args...]", + desc = "Execute a CraftScript", + min = 1, + max = -1 + ) + @CommandPermissions("worldedit.scripting.execute") + @Logging(ALL) + public void execute(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + String[] scriptArgs = args.getSlice(1); + String name = args.getString(0); + + if (!player.hasPermission("worldedit.scripting.execute." + name)) { + player.printError("You don't have permission to use that script."); + return; + } + + session.setLastScript(name); + + File dir = we.getWorkingDirectoryFile(we.getConfiguration().scriptsDir); + File f = we.getSafeOpenFile(player, dir, name, "js", "js"); + + we.runScript(player, f, scriptArgs); + } + + @Command( + aliases = { ".s" }, + usage = "[args...]", + desc = "Execute last CraftScript", + min = 0, + max = -1 + ) + @CommandPermissions("worldedit.scripting.execute") + @Logging(ALL) + public void executeLast(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + String lastScript = session.getLastScript(); + + if (!player.hasPermission("worldedit.scripting.execute." + lastScript)) { + player.printError("You don't have permission to use that script."); + return; + } + + if (lastScript == null) { + player.printError("Use /cs with a script name first."); + return; + } + + String[] scriptArgs = args.getSlice(0); + + File dir = we.getWorkingDirectoryFile(we.getConfiguration().scriptsDir); + File f = we.getSafeOpenFile(player, dir, lastScript, "js", "js"); + + we.runScript(player, f, scriptArgs); + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/SelectionCommands.java b/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java similarity index 97% rename from src/main/java/com/sk89q/worldedit/commands/SelectionCommands.java rename to src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index b268467d0..4aa6443f9 100644 --- a/src/main/java/com/sk89q/worldedit/commands/SelectionCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -1,788 +1,788 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION; -import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import com.sk89q.minecraft.util.commands.Command; -import com.sk89q.minecraft.util.commands.CommandAlias; -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.Countable; -import com.sk89q.worldedit.CuboidClipboard; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.LocalPlayer; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.LocalWorld; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.Vector2D; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockType; -import com.sk89q.worldedit.data.ChunkStore; -import com.sk89q.worldedit.regions.ConvexPolyhedralRegionSelector; -import com.sk89q.worldedit.regions.CuboidRegionSelector; -import com.sk89q.worldedit.regions.CylinderRegionSelector; -import com.sk89q.worldedit.regions.EllipsoidRegionSelector; -import com.sk89q.worldedit.regions.ExtendingCuboidRegionSelector; -import com.sk89q.worldedit.regions.Polygonal2DRegionSelector; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.regions.RegionOperationException; -import com.sk89q.worldedit.regions.RegionSelector; -import com.sk89q.worldedit.regions.SphereRegionSelector; - -/** - * Selection commands. - * - * @author sk89q - */ -public class SelectionCommands { - private final WorldEdit we; - - public SelectionCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "/pos1" }, - usage = "[coordinates]", - desc = "Set position 1", - min = 0, - max = 1 - ) - @Logging(POSITION) - @CommandPermissions("worldedit.selection.pos") - public void pos1(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Vector pos; - - if (args.argsLength() == 1) { - if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) { - String[] coords = args.getString(0).split(","); - pos = new Vector(Integer.parseInt(coords[0]), Integer.parseInt(coords[1]), Integer.parseInt(coords[2])); - } else { - player.printError("Invalid coordinates " + args.getString(0)); - return; - } - } else { - pos = player.getBlockIn(); - } - - if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos)) { - player.printError("Position already set."); - return; - } - - session.getRegionSelector(player.getWorld()) - .explainPrimarySelection(player, session, pos); - } - - @Command( - aliases = { "/pos2" }, - usage = "[coordinates]", - desc = "Set position 2", - min = 0, - max = 1 - ) - @Logging(POSITION) - @CommandPermissions("worldedit.selection.pos") - public void pos2(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Vector pos; - if (args.argsLength() == 1) { - if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) { - String[] coords = args.getString(0).split(","); - pos = new Vector(Integer.parseInt(coords[0]), - Integer.parseInt(coords[1]), - Integer.parseInt(coords[2])); - } else { - player.printError("Invalid coordinates " + args.getString(0)); - return; - } - } else { - pos = player.getBlockIn(); - } - - if (!session.getRegionSelector(player.getWorld()).selectSecondary(pos)) { - player.printError("Position already set."); - return; - } - - session.getRegionSelector(player.getWorld()) - .explainSecondarySelection(player, session, pos); - } - - @Command( - aliases = { "/hpos1" }, - usage = "", - desc = "Set position 1 to targeted block", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.selection.hpos") - public void hpos1(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Vector pos = player.getBlockTrace(300); - - if (pos != null) { - if (!session.getRegionSelector(player.getWorld()) - .selectPrimary(pos)) { - player.printError("Position already set."); - return; - } - - session.getRegionSelector(player.getWorld()) - .explainPrimarySelection(player, session, pos); - } else { - player.printError("No block in sight!"); - } - } - - @Command( - aliases = { "/hpos2" }, - usage = "", - desc = "Set position 2 to targeted block", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.selection.hpos") - public void hpos2(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - Vector pos = player.getBlockTrace(300); - - if (pos != null) { - if (!session.getRegionSelector(player.getWorld()) - .selectSecondary(pos)) { - player.printError("Position already set."); - return; - } - - session.getRegionSelector(player.getWorld()) - .explainSecondarySelection(player, session, pos); - } else { - player.printError("No block in sight!"); - } - } - - @Command( - aliases = { "/chunk" }, - usage = "[x,z coordinates]", - flags = "sc", - desc = "Set the selection to your current chunk.", - help = - "Set the selection to the chunk you are currently in.\n" + - "With the -s flag, your current selection is expanded\n" + - "to encompass all chunks that are part of it.\n\n" + - "Specifying coordinates will use those instead of your\n"+ - "current position. Use -c to specify chunk coordinates,\n" + - "otherwise full coordinates will be implied.\n" + - "(for example, the coordinates 5,5 are the same as -c 0,0)", - min = 0, - max = 1 - ) - @Logging(POSITION) - @CommandPermissions("worldedit.selection.chunk") - public void chunk(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final Vector min; - final Vector max; - final LocalWorld world = player.getWorld(); - if (args.hasFlag('s')) { - Region region = session.getSelection(world); - - final Vector2D min2D = ChunkStore.toChunk(region.getMinimumPoint()); - final Vector2D max2D = ChunkStore.toChunk(region.getMaximumPoint()); - - min = new Vector(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16); - max = new Vector(max2D.getBlockX() * 16 + 15, world.getMaxY(), max2D.getBlockZ() * 16 + 15); - - player.print("Chunks selected: (" - + min2D.getBlockX() + ", " + min2D.getBlockZ() + ") - (" - + max2D.getBlockX() + ", " + max2D.getBlockZ() + ")"); - } else { - final Vector2D min2D; - if (args.argsLength() == 1) { - // coords specified - String[] coords = args.getString(0).split(","); - if (coords.length != 2) { - throw new InsufficientArgumentsException("Invalid coordinates specified."); - } - int x = Integer.parseInt(coords[0]); - int z = Integer.parseInt(coords[1]); - Vector2D pos = new Vector2D(x, z); - min2D = (args.hasFlag('c')) ? pos : ChunkStore.toChunk(pos.toVector()); - } else { - // use player loc - min2D = ChunkStore.toChunk(player.getBlockIn()); - } - - min = new Vector(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16); - max = min.add(15, world.getMaxY(), 15); - - player.print("Chunk selected: " - + min2D.getBlockX() + ", " + min2D.getBlockZ()); - } - - final CuboidRegionSelector selector; - if (session.getRegionSelector(world) instanceof ExtendingCuboidRegionSelector) { - selector = new ExtendingCuboidRegionSelector(world); - } else { - selector = new CuboidRegionSelector(world); - } - selector.selectPrimary(min); - selector.selectSecondary(max); - session.setRegionSelector(world, selector); - - session.dispatchCUISelection(player); - - } - - @Command( - aliases = { "/wand" }, - usage = "", - desc = "Get the wand object", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.wand") - public void wand(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - player.giveItem(we.getConfiguration().wandItem, 1); - player.print("Left click: select pos #1; Right click: select pos #2"); - } - - @Command( - aliases = { "toggleeditwand" }, - usage = "", - desc = "Toggle functionality of the edit wand", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.wand.toggle") - public void toggleWand(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - session.setToolControl(!session.isToolControlEnabled()); - - if (session.isToolControlEnabled()) { - player.print("Edit wand enabled."); - } else { - player.print("Edit wand disabled."); - } - } - - @Command( - aliases = { "/expand" }, - usage = " [reverse-amount] ", - desc = "Expand the selection area", - min = 1, - max = 3 - ) - @Logging(REGION) - @CommandPermissions("worldedit.selection.expand") - public void expand(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - // Special syntax (//expand vert) to expand the selection between - // sky and bedrock. - if (args.getString(0).equalsIgnoreCase("vert") - || args.getString(0).equalsIgnoreCase("vertical")) { - Region region = session.getSelection(player.getWorld()); - try { - int oldSize = region.getArea(); - region.expand( - new Vector(0, (player.getWorld().getMaxY() + 1), 0), - new Vector(0, -(player.getWorld().getMaxY() + 1), 0)); - session.getRegionSelector(player.getWorld()).learnChanges(); - int newSize = region.getArea(); - session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); - player.print("Region expanded " + (newSize - oldSize) - + " blocks [top-to-bottom]."); - } catch (RegionOperationException e) { - player.printError(e.getMessage()); - } - - return; - } - - List dirs = new ArrayList(); - int change = args.getInteger(0); - int reverseChange = 0; - - switch (args.argsLength()) { - case 2: - // Either a reverse amount or a direction - try { - reverseChange = args.getInteger(1); - dirs.add(we.getDirection(player, "me")); - } catch (NumberFormatException e) { - if (args.getString(1).contains(",")) { - String[] split = args.getString(1).split(","); - for (String s : split) { - dirs.add(we.getDirection(player, s.toLowerCase())); - } - } else { - dirs.add(we.getDirection(player, args.getString(1).toLowerCase())); - } - } - break; - - case 3: - // Both reverse amount and direction - reverseChange = args.getInteger(1); - if (args.getString(2).contains(",")) { - String[] split = args.getString(2).split(","); - for (String s : split) { - dirs.add(we.getDirection(player, s.toLowerCase())); - } - } else { - dirs.add(we.getDirection(player, args.getString(2).toLowerCase())); - } - break; - - default: - dirs.add(we.getDirection(player, "me")); - break; - - } - - Region region = session.getSelection(player.getWorld()); - int oldSize = region.getArea(); - - if (reverseChange == 0) { - for (Vector dir : dirs) { - region.expand(dir.multiply(change)); - } - } else { - for (Vector dir : dirs) { - region.expand(dir.multiply(change), dir.multiply(-reverseChange)); - } - } - - session.getRegionSelector(player.getWorld()).learnChanges(); - int newSize = region.getArea(); - - session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); - - player.print("Region expanded " + (newSize - oldSize) + " blocks."); - } - - @Command( - aliases = { "/contract" }, - usage = " [reverse-amount] [direction]", - desc = "Contract the selection area", - min = 1, - max = 3 - ) - @Logging(REGION) - @CommandPermissions("worldedit.selection.contract") - public void contract(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - List dirs = new ArrayList(); - int change = args.getInteger(0); - int reverseChange = 0; - - switch (args.argsLength()) { - case 2: - // Either a reverse amount or a direction - try { - reverseChange = args.getInteger(1); - dirs.add(we.getDirection(player, "me")); - } catch (NumberFormatException e) { - if (args.getString(1).contains(",")) { - String[] split = args.getString(1).split(","); - for (String s : split) { - dirs.add(we.getDirection(player, s.toLowerCase())); - } - } else { - dirs.add(we.getDirection(player, args.getString(1).toLowerCase())); - } - } - break; - - case 3: - // Both reverse amount and direction - reverseChange = args.getInteger(1); - if (args.getString(2).contains(",")) { - String[] split = args.getString(2).split(","); - for (String s : split) { - dirs.add(we.getDirection(player, s.toLowerCase())); - } - } else { - dirs.add(we.getDirection(player, args.getString(2).toLowerCase())); - } - break; - - default: - dirs.add(we.getDirection(player, "me")); - break; - } - - try { - Region region = session.getSelection(player.getWorld()); - int oldSize = region.getArea(); - if (reverseChange == 0) { - for (Vector dir : dirs) { - region.contract(dir.multiply(change)); - } - } else { - for (Vector dir : dirs) { - region.contract(dir.multiply(change), dir.multiply(-reverseChange)); - } - } - session.getRegionSelector(player.getWorld()).learnChanges(); - int newSize = region.getArea(); - - session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); - - - player.print("Region contracted " + (oldSize - newSize) + " blocks."); - } catch (RegionOperationException e) { - player.printError(e.getMessage()); - } - } - - @Command( - aliases = { "/shift" }, - usage = " [direction]", - desc = "Shift the selection area", - min = 1, - max = 2 - ) - @Logging(REGION) - @CommandPermissions("worldedit.selection.shift") - public void shift(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - List dirs = new ArrayList(); - int change = args.getInteger(0); - if (args.argsLength() == 2) { - if (args.getString(1).contains(",")) { - for (String s : args.getString(1).split(",")) { - dirs.add(we.getDirection(player, s.toLowerCase())); - } - } else { - dirs.add(we.getDirection(player, args.getString(1).toLowerCase())); - } - } else { - dirs.add(we.getDirection(player, "me")); - } - - try { - Region region = session.getSelection(player.getWorld()); - - for (Vector dir : dirs) { - region.shift(dir.multiply(change)); - } - - session.getRegionSelector(player.getWorld()).learnChanges(); - - session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); - - player.print("Region shifted."); - } catch (RegionOperationException e) { - player.printError(e.getMessage()); - } - } - - @Command( - aliases = { "/outset" }, - usage = "", - desc = "Outset the selection area", - help = - "Expands the selection by the given amount in all directions.\n" + - "Flags:\n" + - " -h only expand horizontally\n" + - " -v only expand vertically\n", - flags = "hv", - min = 1, - max = 1 - ) - @Logging(REGION) - @CommandPermissions("worldedit.selection.outset") - public void outset(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - Region region = session.getSelection(player.getWorld()); - region.expand(getChangesForEachDir(args)); - session.getRegionSelector(player.getWorld()).learnChanges(); - session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); - player.print("Region outset."); - } - - @Command( - aliases = { "/inset" }, - usage = "", - desc = "Inset the selection area", - help = - "Contracts the selection by the given amount in all directions.\n" + - "Flags:\n" + - " -h only contract horizontally\n" + - " -v only contract vertically\n", - flags = "hv", - min = 1, - max = 1 - ) - @Logging(REGION) - @CommandPermissions("worldedit.selection.inset") - public void inset(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - Region region = session.getSelection(player.getWorld()); - region.contract(getChangesForEachDir(args)); - session.getRegionSelector(player.getWorld()).learnChanges(); - session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); - player.print("Region inset."); - } - - private Vector[] getChangesForEachDir(CommandContext args) { - List changes = new ArrayList(6); - int change = args.getInteger(0); - - if (!args.hasFlag('h')) { - changes.add((new Vector(0, 1, 0)).multiply(change)); - changes.add((new Vector(0, -1, 0)).multiply(change)); - } - - if (!args.hasFlag('v')) { - changes.add((new Vector(1, 0, 0)).multiply(change)); - changes.add((new Vector(-1, 0, 0)).multiply(change)); - changes.add((new Vector(0, 0, 1)).multiply(change)); - changes.add((new Vector(0, 0, -1)).multiply(change)); - } - - return changes.toArray(new Vector[0]); - } - - @Command( - aliases = { "/size" }, - flags = "c", - usage = "", - desc = "Get information about the selection", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.selection.size") - public void size(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - if (args.hasFlag('c')) { - CuboidClipboard clipboard = session.getClipboard(); - Vector size = clipboard.getSize(); - Vector offset = clipboard.getOffset(); - - player.print("Size: " + size); - player.print("Offset: " + offset); - player.print("Cuboid distance: " + size.distance(Vector.ONE)); - player.print("# of blocks: " - + (int) (size.getX() * size.getY() * size.getZ())); - return; - } - - Region region = session.getSelection(player.getWorld()); - Vector size = region.getMaximumPoint() - .subtract(region.getMinimumPoint()) - .add(1, 1, 1); - - player.print("Type: " + session.getRegionSelector(player.getWorld()) - .getTypeName()); - - for (String line : session.getRegionSelector(player.getWorld()) - .getInformationLines()) { - player.print(line); - } - - player.print("Size: " + size); - player.print("Cuboid distance: " + region.getMaximumPoint() - .distance(region.getMinimumPoint())); - player.print("# of blocks: " + region.getArea()); - } - - - @Command( - aliases = { "/count" }, - usage = "", - desc = "Counts the number of a certain type of block", - flags = "d", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.analysis.count") - public void count(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - boolean useData = args.hasFlag('d'); - if (args.getString(0).contains(":")) { - useData = true; //override d flag, if they specified data they want it - } - if (useData) { - Set searchBlocks = we.getBlocks(player, args.getString(0), true); - int count = editSession.countBlocks(session.getSelection(player.getWorld()), searchBlocks); - player.print("Counted: " + count); - } else { - Set searchIDs = we.getBlockIDs(player, args.getString(0), true); - int count = editSession.countBlock(session.getSelection(player.getWorld()), searchIDs); - player.print("Counted: " + count); - } - } - - @Command( - aliases = { "/distr" }, - usage = "", - desc = "Get the distribution of blocks in the selection", - help = - "Gets the distribution of blocks in the selection.\n" + - "The -c flag gets the distribution of your clipboard.\n" + - "The -d flag separates blocks by data", - flags = "cd", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.analysis.distr") - public void distr(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int size; - boolean useData = args.hasFlag('d'); - List> distribution = null; - List> distributionData = null; - - if (args.hasFlag('c')) { - CuboidClipboard clip = session.getClipboard(); - if (useData) { - distributionData = clip.getBlockDistributionWithData(); - } else { - distribution = clip.getBlockDistribution(); - } - size = clip.getHeight() * clip.getLength() * clip.getWidth(); - } else { - if (useData) { - distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld())); - } else { - distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld())); - } - size = session.getSelection(player.getWorld()).getArea(); - } - - if ((useData && distributionData.size() <= 0) - || (!useData && distribution.size() <= 0)) { // *Should* always be false - player.printError("No blocks counted."); - return; - } - - player.print("# total blocks: " + size); - - if (useData) { - for (Countable c : distributionData) { - String name = BlockType.fromID(c.getID().getId()).getName(); - String str = String.format("%-7s (%.3f%%) %s #%d:%d", - String.valueOf(c.getAmount()), - c.getAmount() / (double) size * 100, - name == null ? "Unknown" : name, - c.getID().getType(), c.getID().getData()); - player.print(str); - } - } else { - for (Countable c : distribution) { - BlockType block = BlockType.fromID(c.getID()); - String str = String.format("%-7s (%.3f%%) %s #%d", - String.valueOf(c.getAmount()), - c.getAmount() / (double) size * 100, - block == null ? "Unknown" : block.getName(), c.getID()); - player.print(str); - } - } - } - - @Command( - aliases = { "/sel", ";" }, - usage = "[cuboid|extend|poly|ellipsoid|sphere|cyl|convex]", - desc = "Choose a region selector", - min = 0, - max = 1 - ) - public void select(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - final LocalWorld world = player.getWorld(); - if (args.argsLength() == 0) { - session.getRegionSelector(world).clear(); - session.dispatchCUISelection(player); - player.print("Selection cleared."); - return; - } - - final String typeName = args.getString(0); - final RegionSelector oldSelector = session.getRegionSelector(world); - - final RegionSelector selector; - if (typeName.equalsIgnoreCase("cuboid")) { - selector = new CuboidRegionSelector(oldSelector); - player.print("Cuboid: left click for point 1, right click for point 2"); - } else if (typeName.equalsIgnoreCase("extend")) { - selector = new ExtendingCuboidRegionSelector(oldSelector); - player.print("Cuboid: left click for a starting point, right click to extend"); - } else if (typeName.equalsIgnoreCase("poly")) { - int maxPoints = we.getMaximumPolygonalPoints(player); - selector = new Polygonal2DRegionSelector(oldSelector, maxPoints); - player.print("2D polygon selector: Left/right click to add a point."); - if (maxPoints > -1) { - player.print(maxPoints + " points maximum."); - } - } else if (typeName.equalsIgnoreCase("ellipsoid")) { - selector = new EllipsoidRegionSelector(oldSelector); - player.print("Ellipsoid selector: left click=center, right click to extend"); - } else if (typeName.equalsIgnoreCase("sphere")) { - selector = new SphereRegionSelector(oldSelector); - player.print("Sphere selector: left click=center, right click to set radius"); - } else if (typeName.equalsIgnoreCase("cyl")) { - selector = new CylinderRegionSelector(oldSelector); - player.print("Cylindrical selector: Left click=center, right click to extend."); - } else if (typeName.equalsIgnoreCase("convex") || typeName.equalsIgnoreCase("hull") || typeName.equalsIgnoreCase("polyhedron")) { - int maxVertices = we.getMaximumPolyhedronPoints(player); - selector = new ConvexPolyhedralRegionSelector(oldSelector, maxVertices); - player.print("Convex polyhedral selector: Left click=First vertex, right click to add more."); - } else { - player.printError("Only cuboid|extend|poly|ellipsoid|sphere|cyl|convex are accepted."); - return; - } - - session.setRegionSelector(world, selector); - session.dispatchCUISelection(player); - } - - @Command(aliases = {"/desel", "/deselect"}, desc = "Deselect the current selection") - @CommandAlias("/sel") - public void deselect() { - - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION; +import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandAlias; +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.util.Countable; +import com.sk89q.worldedit.CuboidClipboard; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockType; +import com.sk89q.worldedit.world.storage.ChunkStore; +import com.sk89q.worldedit.regions.ConvexPolyhedralRegionSelector; +import com.sk89q.worldedit.regions.CuboidRegionSelector; +import com.sk89q.worldedit.regions.CylinderRegionSelector; +import com.sk89q.worldedit.regions.EllipsoidRegionSelector; +import com.sk89q.worldedit.regions.ExtendingCuboidRegionSelector; +import com.sk89q.worldedit.regions.Polygonal2DRegionSelector; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.regions.RegionOperationException; +import com.sk89q.worldedit.regions.RegionSelector; +import com.sk89q.worldedit.regions.SphereRegionSelector; + +/** + * Selection commands. + * + * @author sk89q + */ +public class SelectionCommands { + private final WorldEdit we; + + public SelectionCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "/pos1" }, + usage = "[coordinates]", + desc = "Set position 1", + min = 0, + max = 1 + ) + @Logging(POSITION) + @CommandPermissions("worldedit.selection.pos") + public void pos1(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Vector pos; + + if (args.argsLength() == 1) { + if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) { + String[] coords = args.getString(0).split(","); + pos = new Vector(Integer.parseInt(coords[0]), Integer.parseInt(coords[1]), Integer.parseInt(coords[2])); + } else { + player.printError("Invalid coordinates " + args.getString(0)); + return; + } + } else { + pos = player.getBlockIn(); + } + + if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos)) { + player.printError("Position already set."); + return; + } + + session.getRegionSelector(player.getWorld()) + .explainPrimarySelection(player, session, pos); + } + + @Command( + aliases = { "/pos2" }, + usage = "[coordinates]", + desc = "Set position 2", + min = 0, + max = 1 + ) + @Logging(POSITION) + @CommandPermissions("worldedit.selection.pos") + public void pos2(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Vector pos; + if (args.argsLength() == 1) { + if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) { + String[] coords = args.getString(0).split(","); + pos = new Vector(Integer.parseInt(coords[0]), + Integer.parseInt(coords[1]), + Integer.parseInt(coords[2])); + } else { + player.printError("Invalid coordinates " + args.getString(0)); + return; + } + } else { + pos = player.getBlockIn(); + } + + if (!session.getRegionSelector(player.getWorld()).selectSecondary(pos)) { + player.printError("Position already set."); + return; + } + + session.getRegionSelector(player.getWorld()) + .explainSecondarySelection(player, session, pos); + } + + @Command( + aliases = { "/hpos1" }, + usage = "", + desc = "Set position 1 to targeted block", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.selection.hpos") + public void hpos1(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Vector pos = player.getBlockTrace(300); + + if (pos != null) { + if (!session.getRegionSelector(player.getWorld()) + .selectPrimary(pos)) { + player.printError("Position already set."); + return; + } + + session.getRegionSelector(player.getWorld()) + .explainPrimarySelection(player, session, pos); + } else { + player.printError("No block in sight!"); + } + } + + @Command( + aliases = { "/hpos2" }, + usage = "", + desc = "Set position 2 to targeted block", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.selection.hpos") + public void hpos2(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + Vector pos = player.getBlockTrace(300); + + if (pos != null) { + if (!session.getRegionSelector(player.getWorld()) + .selectSecondary(pos)) { + player.printError("Position already set."); + return; + } + + session.getRegionSelector(player.getWorld()) + .explainSecondarySelection(player, session, pos); + } else { + player.printError("No block in sight!"); + } + } + + @Command( + aliases = { "/chunk" }, + usage = "[x,z coordinates]", + flags = "sc", + desc = "Set the selection to your current chunk.", + help = + "Set the selection to the chunk you are currently in.\n" + + "With the -s flag, your current selection is expanded\n" + + "to encompass all chunks that are part of it.\n\n" + + "Specifying coordinates will use those instead of your\n"+ + "current position. Use -c to specify chunk coordinates,\n" + + "otherwise full coordinates will be implied.\n" + + "(for example, the coordinates 5,5 are the same as -c 0,0)", + min = 0, + max = 1 + ) + @Logging(POSITION) + @CommandPermissions("worldedit.selection.chunk") + public void chunk(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final Vector min; + final Vector max; + final LocalWorld world = player.getWorld(); + if (args.hasFlag('s')) { + Region region = session.getSelection(world); + + final Vector2D min2D = ChunkStore.toChunk(region.getMinimumPoint()); + final Vector2D max2D = ChunkStore.toChunk(region.getMaximumPoint()); + + min = new Vector(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16); + max = new Vector(max2D.getBlockX() * 16 + 15, world.getMaxY(), max2D.getBlockZ() * 16 + 15); + + player.print("Chunks selected: (" + + min2D.getBlockX() + ", " + min2D.getBlockZ() + ") - (" + + max2D.getBlockX() + ", " + max2D.getBlockZ() + ")"); + } else { + final Vector2D min2D; + if (args.argsLength() == 1) { + // coords specified + String[] coords = args.getString(0).split(","); + if (coords.length != 2) { + throw new InsufficientArgumentsException("Invalid coordinates specified."); + } + int x = Integer.parseInt(coords[0]); + int z = Integer.parseInt(coords[1]); + Vector2D pos = new Vector2D(x, z); + min2D = (args.hasFlag('c')) ? pos : ChunkStore.toChunk(pos.toVector()); + } else { + // use player loc + min2D = ChunkStore.toChunk(player.getBlockIn()); + } + + min = new Vector(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16); + max = min.add(15, world.getMaxY(), 15); + + player.print("Chunk selected: " + + min2D.getBlockX() + ", " + min2D.getBlockZ()); + } + + final CuboidRegionSelector selector; + if (session.getRegionSelector(world) instanceof ExtendingCuboidRegionSelector) { + selector = new ExtendingCuboidRegionSelector(world); + } else { + selector = new CuboidRegionSelector(world); + } + selector.selectPrimary(min); + selector.selectSecondary(max); + session.setRegionSelector(world, selector); + + session.dispatchCUISelection(player); + + } + + @Command( + aliases = { "/wand" }, + usage = "", + desc = "Get the wand object", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.wand") + public void wand(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + player.giveItem(we.getConfiguration().wandItem, 1); + player.print("Left click: select pos #1; Right click: select pos #2"); + } + + @Command( + aliases = { "toggleeditwand" }, + usage = "", + desc = "Toggle functionality of the edit wand", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.wand.toggle") + public void toggleWand(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + session.setToolControl(!session.isToolControlEnabled()); + + if (session.isToolControlEnabled()) { + player.print("Edit wand enabled."); + } else { + player.print("Edit wand disabled."); + } + } + + @Command( + aliases = { "/expand" }, + usage = " [reverse-amount] ", + desc = "Expand the selection area", + min = 1, + max = 3 + ) + @Logging(REGION) + @CommandPermissions("worldedit.selection.expand") + public void expand(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + // Special syntax (//expand vert) to expand the selection between + // sky and bedrock. + if (args.getString(0).equalsIgnoreCase("vert") + || args.getString(0).equalsIgnoreCase("vertical")) { + Region region = session.getSelection(player.getWorld()); + try { + int oldSize = region.getArea(); + region.expand( + new Vector(0, (player.getWorld().getMaxY() + 1), 0), + new Vector(0, -(player.getWorld().getMaxY() + 1), 0)); + session.getRegionSelector(player.getWorld()).learnChanges(); + int newSize = region.getArea(); + session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); + player.print("Region expanded " + (newSize - oldSize) + + " blocks [top-to-bottom]."); + } catch (RegionOperationException e) { + player.printError(e.getMessage()); + } + + return; + } + + List dirs = new ArrayList(); + int change = args.getInteger(0); + int reverseChange = 0; + + switch (args.argsLength()) { + case 2: + // Either a reverse amount or a direction + try { + reverseChange = args.getInteger(1); + dirs.add(we.getDirection(player, "me")); + } catch (NumberFormatException e) { + if (args.getString(1).contains(",")) { + String[] split = args.getString(1).split(","); + for (String s : split) { + dirs.add(we.getDirection(player, s.toLowerCase())); + } + } else { + dirs.add(we.getDirection(player, args.getString(1).toLowerCase())); + } + } + break; + + case 3: + // Both reverse amount and direction + reverseChange = args.getInteger(1); + if (args.getString(2).contains(",")) { + String[] split = args.getString(2).split(","); + for (String s : split) { + dirs.add(we.getDirection(player, s.toLowerCase())); + } + } else { + dirs.add(we.getDirection(player, args.getString(2).toLowerCase())); + } + break; + + default: + dirs.add(we.getDirection(player, "me")); + break; + + } + + Region region = session.getSelection(player.getWorld()); + int oldSize = region.getArea(); + + if (reverseChange == 0) { + for (Vector dir : dirs) { + region.expand(dir.multiply(change)); + } + } else { + for (Vector dir : dirs) { + region.expand(dir.multiply(change), dir.multiply(-reverseChange)); + } + } + + session.getRegionSelector(player.getWorld()).learnChanges(); + int newSize = region.getArea(); + + session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); + + player.print("Region expanded " + (newSize - oldSize) + " blocks."); + } + + @Command( + aliases = { "/contract" }, + usage = " [reverse-amount] [direction]", + desc = "Contract the selection area", + min = 1, + max = 3 + ) + @Logging(REGION) + @CommandPermissions("worldedit.selection.contract") + public void contract(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + List dirs = new ArrayList(); + int change = args.getInteger(0); + int reverseChange = 0; + + switch (args.argsLength()) { + case 2: + // Either a reverse amount or a direction + try { + reverseChange = args.getInteger(1); + dirs.add(we.getDirection(player, "me")); + } catch (NumberFormatException e) { + if (args.getString(1).contains(",")) { + String[] split = args.getString(1).split(","); + for (String s : split) { + dirs.add(we.getDirection(player, s.toLowerCase())); + } + } else { + dirs.add(we.getDirection(player, args.getString(1).toLowerCase())); + } + } + break; + + case 3: + // Both reverse amount and direction + reverseChange = args.getInteger(1); + if (args.getString(2).contains(",")) { + String[] split = args.getString(2).split(","); + for (String s : split) { + dirs.add(we.getDirection(player, s.toLowerCase())); + } + } else { + dirs.add(we.getDirection(player, args.getString(2).toLowerCase())); + } + break; + + default: + dirs.add(we.getDirection(player, "me")); + break; + } + + try { + Region region = session.getSelection(player.getWorld()); + int oldSize = region.getArea(); + if (reverseChange == 0) { + for (Vector dir : dirs) { + region.contract(dir.multiply(change)); + } + } else { + for (Vector dir : dirs) { + region.contract(dir.multiply(change), dir.multiply(-reverseChange)); + } + } + session.getRegionSelector(player.getWorld()).learnChanges(); + int newSize = region.getArea(); + + session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); + + + player.print("Region contracted " + (oldSize - newSize) + " blocks."); + } catch (RegionOperationException e) { + player.printError(e.getMessage()); + } + } + + @Command( + aliases = { "/shift" }, + usage = " [direction]", + desc = "Shift the selection area", + min = 1, + max = 2 + ) + @Logging(REGION) + @CommandPermissions("worldedit.selection.shift") + public void shift(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + List dirs = new ArrayList(); + int change = args.getInteger(0); + if (args.argsLength() == 2) { + if (args.getString(1).contains(",")) { + for (String s : args.getString(1).split(",")) { + dirs.add(we.getDirection(player, s.toLowerCase())); + } + } else { + dirs.add(we.getDirection(player, args.getString(1).toLowerCase())); + } + } else { + dirs.add(we.getDirection(player, "me")); + } + + try { + Region region = session.getSelection(player.getWorld()); + + for (Vector dir : dirs) { + region.shift(dir.multiply(change)); + } + + session.getRegionSelector(player.getWorld()).learnChanges(); + + session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); + + player.print("Region shifted."); + } catch (RegionOperationException e) { + player.printError(e.getMessage()); + } + } + + @Command( + aliases = { "/outset" }, + usage = "", + desc = "Outset the selection area", + help = + "Expands the selection by the given amount in all directions.\n" + + "Flags:\n" + + " -h only expand horizontally\n" + + " -v only expand vertically\n", + flags = "hv", + min = 1, + max = 1 + ) + @Logging(REGION) + @CommandPermissions("worldedit.selection.outset") + public void outset(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + Region region = session.getSelection(player.getWorld()); + region.expand(getChangesForEachDir(args)); + session.getRegionSelector(player.getWorld()).learnChanges(); + session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); + player.print("Region outset."); + } + + @Command( + aliases = { "/inset" }, + usage = "", + desc = "Inset the selection area", + help = + "Contracts the selection by the given amount in all directions.\n" + + "Flags:\n" + + " -h only contract horizontally\n" + + " -v only contract vertically\n", + flags = "hv", + min = 1, + max = 1 + ) + @Logging(REGION) + @CommandPermissions("worldedit.selection.inset") + public void inset(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + Region region = session.getSelection(player.getWorld()); + region.contract(getChangesForEachDir(args)); + session.getRegionSelector(player.getWorld()).learnChanges(); + session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); + player.print("Region inset."); + } + + private Vector[] getChangesForEachDir(CommandContext args) { + List changes = new ArrayList(6); + int change = args.getInteger(0); + + if (!args.hasFlag('h')) { + changes.add((new Vector(0, 1, 0)).multiply(change)); + changes.add((new Vector(0, -1, 0)).multiply(change)); + } + + if (!args.hasFlag('v')) { + changes.add((new Vector(1, 0, 0)).multiply(change)); + changes.add((new Vector(-1, 0, 0)).multiply(change)); + changes.add((new Vector(0, 0, 1)).multiply(change)); + changes.add((new Vector(0, 0, -1)).multiply(change)); + } + + return changes.toArray(new Vector[0]); + } + + @Command( + aliases = { "/size" }, + flags = "c", + usage = "", + desc = "Get information about the selection", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.selection.size") + public void size(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + if (args.hasFlag('c')) { + CuboidClipboard clipboard = session.getClipboard(); + Vector size = clipboard.getSize(); + Vector offset = clipboard.getOffset(); + + player.print("Size: " + size); + player.print("Offset: " + offset); + player.print("Cuboid distance: " + size.distance(Vector.ONE)); + player.print("# of blocks: " + + (int) (size.getX() * size.getY() * size.getZ())); + return; + } + + Region region = session.getSelection(player.getWorld()); + Vector size = region.getMaximumPoint() + .subtract(region.getMinimumPoint()) + .add(1, 1, 1); + + player.print("Type: " + session.getRegionSelector(player.getWorld()) + .getTypeName()); + + for (String line : session.getRegionSelector(player.getWorld()) + .getInformationLines()) { + player.print(line); + } + + player.print("Size: " + size); + player.print("Cuboid distance: " + region.getMaximumPoint() + .distance(region.getMinimumPoint())); + player.print("# of blocks: " + region.getArea()); + } + + + @Command( + aliases = { "/count" }, + usage = "", + desc = "Counts the number of a certain type of block", + flags = "d", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.analysis.count") + public void count(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + boolean useData = args.hasFlag('d'); + if (args.getString(0).contains(":")) { + useData = true; //override d flag, if they specified data they want it + } + if (useData) { + Set searchBlocks = we.getBlocks(player, args.getString(0), true); + int count = editSession.countBlocks(session.getSelection(player.getWorld()), searchBlocks); + player.print("Counted: " + count); + } else { + Set searchIDs = we.getBlockIDs(player, args.getString(0), true); + int count = editSession.countBlock(session.getSelection(player.getWorld()), searchIDs); + player.print("Counted: " + count); + } + } + + @Command( + aliases = { "/distr" }, + usage = "", + desc = "Get the distribution of blocks in the selection", + help = + "Gets the distribution of blocks in the selection.\n" + + "The -c flag gets the distribution of your clipboard.\n" + + "The -d flag separates blocks by data", + flags = "cd", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.analysis.distr") + public void distr(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int size; + boolean useData = args.hasFlag('d'); + List> distribution = null; + List> distributionData = null; + + if (args.hasFlag('c')) { + CuboidClipboard clip = session.getClipboard(); + if (useData) { + distributionData = clip.getBlockDistributionWithData(); + } else { + distribution = clip.getBlockDistribution(); + } + size = clip.getHeight() * clip.getLength() * clip.getWidth(); + } else { + if (useData) { + distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld())); + } else { + distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld())); + } + size = session.getSelection(player.getWorld()).getArea(); + } + + if ((useData && distributionData.size() <= 0) + || (!useData && distribution.size() <= 0)) { // *Should* always be false + player.printError("No blocks counted."); + return; + } + + player.print("# total blocks: " + size); + + if (useData) { + for (Countable c : distributionData) { + String name = BlockType.fromID(c.getID().getId()).getName(); + String str = String.format("%-7s (%.3f%%) %s #%d:%d", + String.valueOf(c.getAmount()), + c.getAmount() / (double) size * 100, + name == null ? "Unknown" : name, + c.getID().getType(), c.getID().getData()); + player.print(str); + } + } else { + for (Countable c : distribution) { + BlockType block = BlockType.fromID(c.getID()); + String str = String.format("%-7s (%.3f%%) %s #%d", + String.valueOf(c.getAmount()), + c.getAmount() / (double) size * 100, + block == null ? "Unknown" : block.getName(), c.getID()); + player.print(str); + } + } + } + + @Command( + aliases = { "/sel", ";" }, + usage = "[cuboid|extend|poly|ellipsoid|sphere|cyl|convex]", + desc = "Choose a region selector", + min = 0, + max = 1 + ) + public void select(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + final LocalWorld world = player.getWorld(); + if (args.argsLength() == 0) { + session.getRegionSelector(world).clear(); + session.dispatchCUISelection(player); + player.print("Selection cleared."); + return; + } + + final String typeName = args.getString(0); + final RegionSelector oldSelector = session.getRegionSelector(world); + + final RegionSelector selector; + if (typeName.equalsIgnoreCase("cuboid")) { + selector = new CuboidRegionSelector(oldSelector); + player.print("Cuboid: left click for point 1, right click for point 2"); + } else if (typeName.equalsIgnoreCase("extend")) { + selector = new ExtendingCuboidRegionSelector(oldSelector); + player.print("Cuboid: left click for a starting point, right click to extend"); + } else if (typeName.equalsIgnoreCase("poly")) { + int maxPoints = we.getMaximumPolygonalPoints(player); + selector = new Polygonal2DRegionSelector(oldSelector, maxPoints); + player.print("2D polygon selector: Left/right click to add a point."); + if (maxPoints > -1) { + player.print(maxPoints + " points maximum."); + } + } else if (typeName.equalsIgnoreCase("ellipsoid")) { + selector = new EllipsoidRegionSelector(oldSelector); + player.print("Ellipsoid selector: left click=center, right click to extend"); + } else if (typeName.equalsIgnoreCase("sphere")) { + selector = new SphereRegionSelector(oldSelector); + player.print("Sphere selector: left click=center, right click to set radius"); + } else if (typeName.equalsIgnoreCase("cyl")) { + selector = new CylinderRegionSelector(oldSelector); + player.print("Cylindrical selector: Left click=center, right click to extend."); + } else if (typeName.equalsIgnoreCase("convex") || typeName.equalsIgnoreCase("hull") || typeName.equalsIgnoreCase("polyhedron")) { + int maxVertices = we.getMaximumPolyhedronPoints(player); + selector = new ConvexPolyhedralRegionSelector(oldSelector, maxVertices); + player.print("Convex polyhedral selector: Left click=First vertex, right click to add more."); + } else { + player.printError("Only cuboid|extend|poly|ellipsoid|sphere|cyl|convex are accepted."); + return; + } + + session.setRegionSelector(world, selector); + session.dispatchCUISelection(player); + } + + @Command(aliases = {"/desel", "/deselect"}, desc = "Deselect the current selection") + @CommandAlias("/sel") + public void deselect() { + + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/SnapshotCommands.java b/src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/commands/SnapshotCommands.java rename to src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java index b7e8e9648..ef818977c 100644 --- a/src/main/java/com/sk89q/worldedit/commands/SnapshotCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java @@ -1,272 +1,272 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.sk89q.worldedit.commands; - -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; -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.data.MissingWorldException; -import com.sk89q.worldedit.snapshots.InvalidSnapshotException; -import com.sk89q.worldedit.snapshots.Snapshot; - -/** - * Snapshot commands. - * - * @author sk89q - */ -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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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.size() > 0) { - - int num = args.argsLength() > 0 ? Math.min(40, Math.max(5, args.getInteger(0))) : 5; - - player.print("Snapshots for world: '" + player.getWorld().getName() + "'"); - for (byte i = 0; i < Math.min(num, snapshots.size()); i++) { - player.print((i + 1) + ". " + snapshots.get(i).getName()); - } - - player.print("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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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("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("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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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("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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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("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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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("Snapshot set to: " + snapshot.getName()); - } - } catch (MissingWorldException ex) { - player.printError("No snapshots were found for this world."); - } - } - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.sk89q.worldedit.command; + +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; +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.world.storage.MissingWorldException; +import com.sk89q.worldedit.world.snapshot.InvalidSnapshotException; +import com.sk89q.worldedit.world.snapshot.Snapshot; + +/** + * Snapshot commands. + * + * @author sk89q + */ +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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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.size() > 0) { + + int num = args.argsLength() > 0 ? Math.min(40, Math.max(5, args.getInteger(0))) : 5; + + player.print("Snapshots for world: '" + player.getWorld().getName() + "'"); + for (byte i = 0; i < Math.min(num, snapshots.size()); i++) { + player.print((i + 1) + ". " + snapshots.get(i).getName()); + } + + player.print("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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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("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("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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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("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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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("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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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("Snapshot set to: " + snapshot.getName()); + } + } catch (MissingWorldException ex) { + player.printError("No snapshots were found for this world."); + } + } + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/SnapshotUtilCommands.java b/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/commands/SnapshotUtilCommands.java rename to src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java index 7dde042b2..0332fb513 100644 --- a/src/main/java/com/sk89q/worldedit/commands/SnapshotUtilCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java @@ -1,169 +1,169 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.commands; - -import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION; - -import java.io.File; -import java.io.IOException; -import java.util.logging.Logger; - -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.minecraft.util.commands.NestedCommand; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.LocalConfiguration; -import com.sk89q.worldedit.LocalPlayer; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.data.ChunkStore; -import com.sk89q.worldedit.data.DataException; -import com.sk89q.worldedit.data.MissingWorldException; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.snapshots.InvalidSnapshotException; -import com.sk89q.worldedit.snapshots.Snapshot; -import com.sk89q.worldedit.snapshots.SnapshotRestore; - -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 = { "snapshot", "snap" }, - desc = "Snapshot commands" - ) - @NestedCommand(SnapshotCommands.class) - public void snapshot(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - } - - @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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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("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(String.format("Restored; %d " - + "missing chunks and %d other errors.", - restore.getMissingChunks().size(), - restore.getErrorChunks().size())); - } - } finally { - try { - chunkStore.close(); - } catch (IOException e) { - } - } - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command; + +import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION; + +import java.io.File; +import java.io.IOException; +import java.util.logging.Logger; + +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.minecraft.util.commands.NestedCommand; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.world.storage.ChunkStore; +import com.sk89q.worldedit.world.DataException; +import com.sk89q.worldedit.world.storage.MissingWorldException; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.snapshot.InvalidSnapshotException; +import com.sk89q.worldedit.world.snapshot.Snapshot; +import com.sk89q.worldedit.world.snapshot.SnapshotRestore; + +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 = { "snapshot", "snap" }, + desc = "Snapshot commands" + ) + @NestedCommand(SnapshotCommands.class) + public void snapshot(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + } + + @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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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("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(String.format("Restored; %d " + + "missing chunks and %d other errors.", + restore.getMissingChunks().size(), + restore.getErrorChunks().size())); + } + } finally { + try { + chunkStore.close(); + } catch (IOException e) { + } + } + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/SuperPickaxeCommands.java b/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/commands/SuperPickaxeCommands.java rename to src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java index 141bc27e3..29af51931 100644 --- a/src/main/java/com/sk89q/worldedit/commands/SuperPickaxeCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java @@ -1,105 +1,105 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -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.LocalPlayer; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.tools.AreaPickaxe; -import com.sk89q.worldedit.tools.RecursivePickaxe; -import com.sk89q.worldedit.tools.SinglePickaxe; - -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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - session.setSuperPickaxe(new SinglePickaxe()); - session.enableSuperPickAxe(); - player.print("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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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("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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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("Mode changed. Left click with a pickaxe. // to disable."); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +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.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.command.tool.AreaPickaxe; +import com.sk89q.worldedit.command.tool.RecursivePickaxe; +import com.sk89q.worldedit.command.tool.SinglePickaxe; + +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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + session.setSuperPickaxe(new SinglePickaxe()); + session.enableSuperPickAxe(); + player.print("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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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("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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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("Mode changed. Left click with a pickaxe. // to disable."); + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/ToolCommands.java b/src/main/java/com/sk89q/worldedit/command/ToolCommands.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/commands/ToolCommands.java rename to src/main/java/com/sk89q/worldedit/command/ToolCommands.java index c3e3662d8..2b5fb4b22 100644 --- a/src/main/java/com/sk89q/worldedit/commands/ToolCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/ToolCommands.java @@ -1,212 +1,212 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -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.NestedCommand; -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.ItemType; -import com.sk89q.worldedit.patterns.Pattern; -import com.sk89q.worldedit.tools.*; -import com.sk89q.worldedit.util.TreeGenerator; - -public class ToolCommands { - private final WorldEdit we; - - public ToolCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "none" }, - usage = "", - desc = "Unbind a bound tool from your current item", - min = 0, - max = 0 - ) - public void none(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - session.setTool(player.getItemInHand(), null); - player.print("Tool unbound from your current item."); - } - - @Command( - aliases = { "info" }, - usage = "", - desc = "Block information tool", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.tool.info") - public void info(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - session.setTool(player.getItemInHand(), new QueryTool()); - player.print("Info tool bound to " - + ItemType.toHeldName(player.getItemInHand()) + "."); - } - - @Command( - aliases = { "tree" }, - usage = "[type]", - desc = "Tree generator tool", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.tool.tree") - @SuppressWarnings("deprecation") - public void tree(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - TreeGenerator.TreeType type = args.argsLength() > 0 ? - type = TreeGenerator.lookup(args.getString(0)) - : TreeGenerator.TreeType.TREE; - - if (type == null) { - player.printError("Tree type '" + args.getString(0) + "' is unknown."); - return; - } - - session.setTool(player.getItemInHand(), new TreePlanter(new TreeGenerator(type))); - player.print("Tree tool bound to " - + ItemType.toHeldName(player.getItemInHand()) + "."); - } - - @Command( - aliases = { "repl" }, - usage = "", - desc = "Block replacer tool", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.tool.replacer") - public void repl(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - BaseBlock targetBlock = we.getBlock(player, args.getString(0)); - session.setTool(player.getItemInHand(), new BlockReplacer(targetBlock)); - player.print("Block replacer tool bound to " - + ItemType.toHeldName(player.getItemInHand()) + "."); - } - - @Command( - aliases = { "cycler" }, - usage = "", - desc = "Block data cycler tool", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.tool.data-cycler") - public void cycler(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - session.setTool(player.getItemInHand(), new BlockDataCyler()); - player.print("Block data cycler tool bound to " - + ItemType.toHeldName(player.getItemInHand()) + "."); - } - - @Command( - aliases = { "floodfill", "flood" }, - usage = " ", - desc = "Flood fill tool", - min = 2, - max = 2 - ) - @CommandPermissions("worldedit.tool.flood-fill") - public void floodFill(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - LocalConfiguration config = we.getConfiguration(); - int range = args.getInteger(1); - - if (range > config.maxSuperPickaxeSize) { - player.printError("Maximum range: " + config.maxSuperPickaxeSize); - return; - } - - Pattern pattern = we.getBlockPattern(player, args.getString(0)); - session.setTool(player.getItemInHand(), new FloodFillTool(range, pattern)); - player.print("Block flood fill tool bound to " - + ItemType.toHeldName(player.getItemInHand()) + "."); - } - - @Command( - aliases = { "brush", "br" }, - desc = "Brush tool" - ) - @NestedCommand(BrushCommands.class) - public void brush(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - } - - @Command( - aliases = { "deltree" }, - usage = "", - desc = "Floating tree remover tool", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.tool.deltree") - public void deltree(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - session.setTool(player.getItemInHand(), new FloatingTreeRemover()); - player.print("Floating tree remover tool bound to " - + ItemType.toHeldName(player.getItemInHand()) + "."); - } - - @Command( - aliases = { "farwand" }, - usage = "", - desc = "Wand at a distance tool", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.tool.farwand") - public void farwand(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - session.setTool(player.getItemInHand(), new DistanceWand()); - player.print("Far wand tool bound to " + ItemType.toHeldName(player.getItemInHand()) + "."); - } - - @Command( - aliases = { "lrbuild", "/lrbuild" }, - usage = " ", - desc = "Long-range building tool", - min = 2, - max = 2 - ) - @CommandPermissions("worldedit.tool.lrbuild") - public void longrangebuildtool(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - BaseBlock secondary = we.getBlock(player, args.getString(0)); - BaseBlock primary = we.getBlock(player, args.getString(1)); - session.setTool(player.getItemInHand(), new LongRangeBuildTool(primary, secondary)); - player.print("Long-range building tool bound to " + ItemType.toHeldName(player.getItemInHand()) + "."); - player.print("Left-click set to " + ItemType.toName(secondary.getType()) + "; right-click set to " - + ItemType.toName(primary.getType()) + "."); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +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.NestedCommand; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.ItemType; +import com.sk89q.worldedit.patterns.Pattern; +import com.sk89q.worldedit.command.tool.*; +import com.sk89q.worldedit.util.TreeGenerator; + +public class ToolCommands { + private final WorldEdit we; + + public ToolCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "none" }, + usage = "", + desc = "Unbind a bound tool from your current item", + min = 0, + max = 0 + ) + public void none(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + session.setTool(player.getItemInHand(), null); + player.print("Tool unbound from your current item."); + } + + @Command( + aliases = { "info" }, + usage = "", + desc = "Block information tool", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.tool.info") + public void info(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + session.setTool(player.getItemInHand(), new QueryTool()); + player.print("Info tool bound to " + + ItemType.toHeldName(player.getItemInHand()) + "."); + } + + @Command( + aliases = { "tree" }, + usage = "[type]", + desc = "Tree generator tool", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.tool.tree") + @SuppressWarnings("deprecation") + public void tree(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + TreeGenerator.TreeType type = args.argsLength() > 0 ? + type = TreeGenerator.lookup(args.getString(0)) + : TreeGenerator.TreeType.TREE; + + if (type == null) { + player.printError("Tree type '" + args.getString(0) + "' is unknown."); + return; + } + + session.setTool(player.getItemInHand(), new TreePlanter(new TreeGenerator(type))); + player.print("Tree tool bound to " + + ItemType.toHeldName(player.getItemInHand()) + "."); + } + + @Command( + aliases = { "repl" }, + usage = "", + desc = "Block replacer tool", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.tool.replacer") + public void repl(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + BaseBlock targetBlock = we.getBlock(player, args.getString(0)); + session.setTool(player.getItemInHand(), new BlockReplacer(targetBlock)); + player.print("Block replacer tool bound to " + + ItemType.toHeldName(player.getItemInHand()) + "."); + } + + @Command( + aliases = { "cycler" }, + usage = "", + desc = "Block data cycler tool", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.tool.data-cycler") + public void cycler(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + session.setTool(player.getItemInHand(), new BlockDataCyler()); + player.print("Block data cycler tool bound to " + + ItemType.toHeldName(player.getItemInHand()) + "."); + } + + @Command( + aliases = { "floodfill", "flood" }, + usage = " ", + desc = "Flood fill tool", + min = 2, + max = 2 + ) + @CommandPermissions("worldedit.tool.flood-fill") + public void floodFill(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + int range = args.getInteger(1); + + if (range > config.maxSuperPickaxeSize) { + player.printError("Maximum range: " + config.maxSuperPickaxeSize); + return; + } + + Pattern pattern = we.getBlockPattern(player, args.getString(0)); + session.setTool(player.getItemInHand(), new FloodFillTool(range, pattern)); + player.print("Block flood fill tool bound to " + + ItemType.toHeldName(player.getItemInHand()) + "."); + } + + @Command( + aliases = { "brush", "br" }, + desc = "Brush tool" + ) + @NestedCommand(BrushCommands.class) + public void brush(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + } + + @Command( + aliases = { "deltree" }, + usage = "", + desc = "Floating tree remover tool", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.tool.deltree") + public void deltree(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + session.setTool(player.getItemInHand(), new FloatingTreeRemover()); + player.print("Floating tree remover tool bound to " + + ItemType.toHeldName(player.getItemInHand()) + "."); + } + + @Command( + aliases = { "farwand" }, + usage = "", + desc = "Wand at a distance tool", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.tool.farwand") + public void farwand(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + session.setTool(player.getItemInHand(), new DistanceWand()); + player.print("Far wand tool bound to " + ItemType.toHeldName(player.getItemInHand()) + "."); + } + + @Command( + aliases = { "lrbuild", "/lrbuild" }, + usage = " ", + desc = "Long-range building tool", + min = 2, + max = 2 + ) + @CommandPermissions("worldedit.tool.lrbuild") + public void longrangebuildtool(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + BaseBlock secondary = we.getBlock(player, args.getString(0)); + BaseBlock primary = we.getBlock(player, args.getString(1)); + session.setTool(player.getItemInHand(), new LongRangeBuildTool(primary, secondary)); + player.print("Long-range building tool bound to " + ItemType.toHeldName(player.getItemInHand()) + "."); + player.print("Left-click set to " + ItemType.toName(secondary.getType()) + "; right-click set to " + + ItemType.toName(primary.getType()) + "."); + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/ToolUtilCommands.java b/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/commands/ToolUtilCommands.java rename to src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java index 18ed67f9a..9385a3767 100644 --- a/src/main/java/com/sk89q/worldedit/commands/ToolUtilCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java @@ -1,158 +1,158 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -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.NestedCommand; -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.masks.Mask; -import com.sk89q.worldedit.patterns.Pattern; - -/** - * Tool commands. - * - * @author sk89q - */ -public class ToolUtilCommands { - private final WorldEdit we; - - public ToolUtilCommands(WorldEdit we) { - this.we = we; - } - - @Command( - aliases = { "/", "," }, - usage = "[on|off]", - desc = "Toggle the super pickaxe pickaxe function", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.superpickaxe") - public void togglePickaxe(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - String newState = args.getString(0, null); - if (session.hasSuperPickAxe()) { - if ("on".equals(newState)) { - player.printError("Super pick axe already enabled."); - return; - } - - session.disableSuperPickAxe(); - player.print("Super pick axe disabled."); - } else { - if ("off".equals(newState)) { - player.printError("Super pick axe already disabled."); - return; - } - session.enableSuperPickAxe(); - player.print("Super pick axe enabled."); - } - - } - - @Command( - aliases = { "superpickaxe", "pickaxe", "sp" }, - desc = "Select super pickaxe mode" - ) - @NestedCommand(SuperPickaxeCommands.class) - public void pickaxe(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - } - - @Command( - aliases = {"tool"}, - desc = "Select a tool to bind" - ) - @NestedCommand(ToolCommands.class) - public void tool(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - } - - @Command( - aliases = { "mask" }, - usage = "[mask]", - desc = "Set the brush mask", - min = 0, - max = -1 - ) - @CommandPermissions("worldedit.brush.options.mask") - public void mask(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - if (args.argsLength() == 0) { - session.getBrushTool(player.getItemInHand()).setMask(null); - player.print("Brush mask disabled."); - } else { - Mask mask = we.getBlockMask(player, session, args.getJoinedStrings(0)); - session.getBrushTool(player.getItemInHand()).setMask(mask); - player.print("Brush mask set."); - } - } - - @Command( - aliases = { "mat", "material" }, - usage = "[pattern]", - desc = "Set the brush material", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.brush.options.material") - public void material(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - Pattern pattern = we.getBlockPattern(player, args.getString(0)); - session.getBrushTool(player.getItemInHand()).setFill(pattern); - player.print("Brush material set."); - } - - @Command( - aliases = { "range" }, - usage = "[pattern]", - desc = "Set the brush range", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.brush.options.range") - public void range(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - int range = args.getInteger(0); - session.getBrushTool(player.getItemInHand()).setRange(range); - player.print("Brush range set."); - } - - @Command( - aliases = { "size" }, - usage = "[pattern]", - desc = "Set the brush size", - min = 1, - max = 1 - ) - @CommandPermissions("worldedit.brush.options.size") - public void size(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int radius = args.getInteger(0); - we.checkMaxBrushRadius(radius); - - session.getBrushTool(player.getItemInHand()).setSize(radius); - player.print("Brush size set."); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +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.NestedCommand; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.masks.Mask; +import com.sk89q.worldedit.patterns.Pattern; + +/** + * Tool commands. + * + * @author sk89q + */ +public class ToolUtilCommands { + private final WorldEdit we; + + public ToolUtilCommands(WorldEdit we) { + this.we = we; + } + + @Command( + aliases = { "/", "," }, + usage = "[on|off]", + desc = "Toggle the super pickaxe pickaxe function", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.superpickaxe") + public void togglePickaxe(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + String newState = args.getString(0, null); + if (session.hasSuperPickAxe()) { + if ("on".equals(newState)) { + player.printError("Super pick axe already enabled."); + return; + } + + session.disableSuperPickAxe(); + player.print("Super pick axe disabled."); + } else { + if ("off".equals(newState)) { + player.printError("Super pick axe already disabled."); + return; + } + session.enableSuperPickAxe(); + player.print("Super pick axe enabled."); + } + + } + + @Command( + aliases = { "superpickaxe", "pickaxe", "sp" }, + desc = "Select super pickaxe mode" + ) + @NestedCommand(SuperPickaxeCommands.class) + public void pickaxe(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + } + + @Command( + aliases = {"tool"}, + desc = "Select a tool to bind" + ) + @NestedCommand(ToolCommands.class) + public void tool(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + } + + @Command( + aliases = { "mask" }, + usage = "[mask]", + desc = "Set the brush mask", + min = 0, + max = -1 + ) + @CommandPermissions("worldedit.brush.options.mask") + public void mask(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + if (args.argsLength() == 0) { + session.getBrushTool(player.getItemInHand()).setMask(null); + player.print("Brush mask disabled."); + } else { + Mask mask = we.getBlockMask(player, session, args.getJoinedStrings(0)); + session.getBrushTool(player.getItemInHand()).setMask(mask); + player.print("Brush mask set."); + } + } + + @Command( + aliases = { "mat", "material" }, + usage = "[pattern]", + desc = "Set the brush material", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.brush.options.material") + public void material(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + Pattern pattern = we.getBlockPattern(player, args.getString(0)); + session.getBrushTool(player.getItemInHand()).setFill(pattern); + player.print("Brush material set."); + } + + @Command( + aliases = { "range" }, + usage = "[pattern]", + desc = "Set the brush range", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.brush.options.range") + public void range(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + int range = args.getInteger(0); + session.getBrushTool(player.getItemInHand()).setRange(range); + player.print("Brush range set."); + } + + @Command( + aliases = { "size" }, + usage = "[pattern]", + desc = "Set the brush size", + min = 1, + max = 1 + ) + @CommandPermissions("worldedit.brush.options.size") + public void size(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int radius = args.getInteger(0); + we.checkMaxBrushRadius(radius); + + session.getBrushTool(player.getItemInHand()).setSize(radius); + player.print("Brush size set."); + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java similarity index 97% rename from src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java rename to src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index b194f74d7..9ca9c6533 100644 --- a/src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -1,554 +1,554 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -import com.sk89q.minecraft.util.commands.*; -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.LocalWorld.KillFlags; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.patterns.Pattern; -import com.sk89q.worldedit.patterns.SingleBlockPattern; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.regions.Region; - -import java.util.Comparator; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT; - -/** - * Utility commands. - * - * @author sk89q - */ -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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - double radius = Math.max(0, args.getDouble(0)); - we.checkMaxRadius(radius); - int affected = editSession.drainArea( - session.getPlacementPosition(player), radius); - player.print(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1; - we.checkMaxRadius(size); - LocalWorld 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(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1; - we.checkMaxRadius(size); - LocalWorld 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(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10; - - int affected = editSession.simulateSnow(session.getPlacementPosition(player), size); - player.print(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10; - - int affected = editSession.thaw(session.getPlacementPosition(player), size); - player.print(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) 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(affected + " block(s) have been removed."); - } - - @Command( - aliases = { "butcher" }, - usage = "[radius]", - flags = "plangbf", - desc = "Kill all or nearby mobs", - help = - "Kills nearby mobs, based on radius, if none is given uses default in configuration.\n" + - "Flags:" + - " -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" + - " -f compounds all previous flags.\n" + - " -l strikes lightning on each killed mob.", - min = 0, - max = 1 - ) - @CommandPermissions("worldedit.butcher") - @Logging(PLACEMENT) - @Console - public void butcher(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - LocalConfiguration config = we.getConfiguration(); - - // 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 (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); - } - } - } - - FlagContainer flags = new FlagContainer(player); - flags.or(KillFlags.FRIENDLY , args.hasFlag('f')); // No permission check here. Flags will instead be filtered by the subsequent calls. - flags.or(KillFlags.PETS , args.hasFlag('p'), "worldedit.butcher.pets"); - flags.or(KillFlags.NPCS , args.hasFlag('n'), "worldedit.butcher.npcs"); - flags.or(KillFlags.GOLEMS , args.hasFlag('g'), "worldedit.butcher.golems"); - flags.or(KillFlags.ANIMALS , args.hasFlag('a'), "worldedit.butcher.animals"); - flags.or(KillFlags.AMBIENT , args.hasFlag('b'), "worldedit.butcher.ambient"); - flags.or(KillFlags.WITH_LIGHTNING, args.hasFlag('l'), "worldedit.butcher.lightning"); - // If you add flags here, please add them to com.sk89q.worldedit.commands.BrushCommands.butcherBrush() as well - - int killed; - if (player.isPlayer()) { - killed = player.getWorld().killMobs(session.getPlacementPosition(player), radius, flags.flags); - } else { - killed = 0; - for (LocalWorld world : we.getServer().getWorlds()) { - killed += world.killMobs(new Vector(), radius, flags.flags); - } - } - - if (radius < 0) { - player.print("Killed " + killed + " mobs."); - } else { - player.print("Killed " + killed + " mobs in a radius of " + radius + "."); - } - } - - public static class FlagContainer { - private final LocalPlayer player; - public int flags = 0; - public FlagContainer(LocalPlayer player) { - this.player = player; - } - - public void or(int flag, boolean on) { - if (on) flags |= flag; - } - - public void or(int flag, boolean on, String permission) { - or(flag, on); - - if ((flags & flag) != 0 && !player.hasPermission(permission)) { - flags &= ~flag; - } - } - } - - @Command( - aliases = { "remove", "rem", "rement" }, - usage = " ", - desc = "Remove all entities of a type", - min = 2, - max = 2 - ) - @CommandPermissions("worldedit.remove") - @Logging(PLACEMENT) - @Console - public void remove(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - String typeStr = args.getString(0); - int radius = args.getInteger(1); - - if (radius < -1) { - player.printError("Use -1 to remove all entities in loaded chunks"); - return; - } - - EntityType type = null; - - if (typeStr.matches("all")) { - type = EntityType.ALL; - } else if (typeStr.matches("projectiles?|arrows?")) { - type = EntityType.PROJECTILES; - } else if (typeStr.matches("items?") - || typeStr.matches("drops?")) { - type = EntityType.ITEMS; - } else if (typeStr.matches("falling(blocks?|sand|gravel)")) { - type = EntityType.FALLING_BLOCKS; - } else if (typeStr.matches("paintings?") - || typeStr.matches("art")) { - type = EntityType.PAINTINGS; - } else if (typeStr.matches("(item)frames?")) { - type = EntityType.ITEM_FRAMES; - } else if (typeStr.matches("boats?")) { - type = EntityType.BOATS; - } else if (typeStr.matches("minecarts?") - || typeStr.matches("carts?")) { - type = EntityType.MINECARTS; - } else if (typeStr.matches("tnt")) { - type = EntityType.TNT; - } else if (typeStr.matches("xp")) { - type = EntityType.XP_ORBS; - } else { - player.printError("Acceptable types: projectiles, items, paintings, itemframes, boats, minecarts, tnt, xp, or all"); - return; - } - - int removed = 0; - if (player.isPlayer()) { - Vector origin = session.getPlacementPosition(player); - removed = player.getWorld().removeEntities(type, origin, radius); - } else { - for (LocalWorld world : we.getServer().getWorlds()) { - removed += world.removeEntities(type, new Vector(), radius); - } - } - player.print("Marked " + removed + " entit(ies) for removal."); - } - - @Command( - aliases = { "/help" }, - usage = "[]", - desc = "Displays help for the given command or lists all commands.", - min = 0, - max = -1 - ) - @Console - @CommandPermissions("worldedit.help") - public void help(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - help(args, we, session, player, editSession); - } - - public static void help(CommandContext args, WorldEdit we, LocalSession session, LocalPlayer player, EditSession editSession) { - final CommandsManager commandsManager = we.getCommandsManager(); - - if (args.argsLength() == 0) { - SortedSet commands = new TreeSet(new Comparator() { - @Override - public int compare(String o1, String o2) { - final int ret = o1.replaceAll("/", "").compareToIgnoreCase(o2.replaceAll("/", "")); - if (ret == 0) { - return o1.compareToIgnoreCase(o2); - } - return ret; - } - }); - commands.addAll(commandsManager.getCommands().keySet()); - - StringBuilder sb = new StringBuilder(); - boolean first = true; - for (String command : commands) { - if (!first) { - sb.append(", "); - } - - sb.append('/'); - sb.append(command); - first = false; - } - - player.print(sb.toString()); - - return; - } - - String command = args.getJoinedStrings(0).toLowerCase().replaceAll("/", ""); - - String helpMessage = commandsManager.getHelpMessages().get(command); - if (helpMessage == null) { - player.printError("Unknown command '" + command + "'."); - return; - } - - player.print(helpMessage); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +import com.sk89q.minecraft.util.commands.*; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.LocalWorld.KillFlags; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.patterns.Pattern; +import com.sk89q.worldedit.patterns.SingleBlockPattern; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; + +import java.util.Comparator; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT; + +/** + * Utility commands. + * + * @author sk89q + */ +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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + double radius = Math.max(0, args.getDouble(0)); + we.checkMaxRadius(radius); + int affected = editSession.drainArea( + session.getPlacementPosition(player), radius); + player.print(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1; + we.checkMaxRadius(size); + LocalWorld 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(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1; + we.checkMaxRadius(size); + LocalWorld 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(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10; + + int affected = editSession.simulateSnow(session.getPlacementPosition(player), size); + player.print(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10; + + int affected = editSession.thaw(session.getPlacementPosition(player), size); + player.print(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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(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(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) 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(affected + " block(s) have been removed."); + } + + @Command( + aliases = { "butcher" }, + usage = "[radius]", + flags = "plangbf", + desc = "Kill all or nearby mobs", + help = + "Kills nearby mobs, based on radius, if none is given uses default in configuration.\n" + + "Flags:" + + " -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" + + " -f compounds all previous flags.\n" + + " -l strikes lightning on each killed mob.", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.butcher") + @Logging(PLACEMENT) + @Console + public void butcher(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + LocalConfiguration config = we.getConfiguration(); + + // 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 (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); + } + } + } + + FlagContainer flags = new FlagContainer(player); + flags.or(KillFlags.FRIENDLY , args.hasFlag('f')); // No permission check here. Flags will instead be filtered by the subsequent calls. + flags.or(KillFlags.PETS , args.hasFlag('p'), "worldedit.butcher.pets"); + flags.or(KillFlags.NPCS , args.hasFlag('n'), "worldedit.butcher.npcs"); + flags.or(KillFlags.GOLEMS , args.hasFlag('g'), "worldedit.butcher.golems"); + flags.or(KillFlags.ANIMALS , args.hasFlag('a'), "worldedit.butcher.animals"); + flags.or(KillFlags.AMBIENT , args.hasFlag('b'), "worldedit.butcher.ambient"); + flags.or(KillFlags.WITH_LIGHTNING, args.hasFlag('l'), "worldedit.butcher.lightning"); + // If you add flags here, please add them to com.sk89q.worldedit.commands.BrushCommands.butcherBrush() as well + + int killed; + if (player.isPlayer()) { + killed = player.getWorld().killMobs(session.getPlacementPosition(player), radius, flags.flags); + } else { + killed = 0; + for (LocalWorld world : we.getServer().getWorlds()) { + killed += world.killMobs(new Vector(), radius, flags.flags); + } + } + + if (radius < 0) { + player.print("Killed " + killed + " mobs."); + } else { + player.print("Killed " + killed + " mobs in a radius of " + radius + "."); + } + } + + public static class FlagContainer { + private final LocalPlayer player; + public int flags = 0; + public FlagContainer(LocalPlayer player) { + this.player = player; + } + + public void or(int flag, boolean on) { + if (on) flags |= flag; + } + + public void or(int flag, boolean on, String permission) { + or(flag, on); + + if ((flags & flag) != 0 && !player.hasPermission(permission)) { + flags &= ~flag; + } + } + } + + @Command( + aliases = { "remove", "rem", "rement" }, + usage = " ", + desc = "Remove all entities of a type", + min = 2, + max = 2 + ) + @CommandPermissions("worldedit.remove") + @Logging(PLACEMENT) + @Console + public void remove(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + String typeStr = args.getString(0); + int radius = args.getInteger(1); + + if (radius < -1) { + player.printError("Use -1 to remove all entities in loaded chunks"); + return; + } + + EntityType type = null; + + if (typeStr.matches("all")) { + type = EntityType.ALL; + } else if (typeStr.matches("projectiles?|arrows?")) { + type = EntityType.PROJECTILES; + } else if (typeStr.matches("items?") + || typeStr.matches("drops?")) { + type = EntityType.ITEMS; + } else if (typeStr.matches("falling(blocks?|sand|gravel)")) { + type = EntityType.FALLING_BLOCKS; + } else if (typeStr.matches("paintings?") + || typeStr.matches("art")) { + type = EntityType.PAINTINGS; + } else if (typeStr.matches("(item)frames?")) { + type = EntityType.ITEM_FRAMES; + } else if (typeStr.matches("boats?")) { + type = EntityType.BOATS; + } else if (typeStr.matches("minecarts?") + || typeStr.matches("carts?")) { + type = EntityType.MINECARTS; + } else if (typeStr.matches("tnt")) { + type = EntityType.TNT; + } else if (typeStr.matches("xp")) { + type = EntityType.XP_ORBS; + } else { + player.printError("Acceptable types: projectiles, items, paintings, itemframes, boats, minecarts, tnt, xp, or all"); + return; + } + + int removed = 0; + if (player.isPlayer()) { + Vector origin = session.getPlacementPosition(player); + removed = player.getWorld().removeEntities(type, origin, radius); + } else { + for (LocalWorld world : we.getServer().getWorlds()) { + removed += world.removeEntities(type, new Vector(), radius); + } + } + player.print("Marked " + removed + " entit(ies) for removal."); + } + + @Command( + aliases = { "/help" }, + usage = "[]", + desc = "Displays help for the given command or lists all commands.", + min = 0, + max = -1 + ) + @Console + @CommandPermissions("worldedit.help") + public void help(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + help(args, we, session, player, editSession); + } + + public static void help(CommandContext args, WorldEdit we, LocalSession session, LocalPlayer player, EditSession editSession) { + final CommandsManager commandsManager = we.getCommandsManager(); + + if (args.argsLength() == 0) { + SortedSet commands = new TreeSet(new Comparator() { + @Override + public int compare(String o1, String o2) { + final int ret = o1.replaceAll("/", "").compareToIgnoreCase(o2.replaceAll("/", "")); + if (ret == 0) { + return o1.compareToIgnoreCase(o2); + } + return ret; + } + }); + commands.addAll(commandsManager.getCommands().keySet()); + + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (String command : commands) { + if (!first) { + sb.append(", "); + } + + sb.append('/'); + sb.append(command); + first = false; + } + + player.print(sb.toString()); + + return; + } + + String command = args.getJoinedStrings(0).toLowerCase().replaceAll("/", ""); + + String helpMessage = commandsManager.getHelpMessages().get(command); + if (helpMessage == null) { + player.printError("Unknown command '" + command + "'."); + return; + } + + player.print(helpMessage); + } +} diff --git a/src/main/java/com/sk89q/worldedit/commands/WorldEditCommands.java b/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/commands/WorldEditCommands.java rename to src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java index 31d9838f9..b97dd80ae 100644 --- a/src/main/java/com/sk89q/worldedit/commands/WorldEditCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java @@ -1,120 +1,120 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.commands; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.TimeZone; -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.Console; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.LocalPlayer; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.WorldEditException; - -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 - ) - @Console - public void version(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - player.print("WorldEdit version " + WorldEdit.getVersion()); - player.print("http://www.sk89q.com/projects/worldedit/"); - } - - @Command( - aliases = { "reload" }, - usage = "", - desc = "Reload WorldEdit", - min = 0, - max = 0 - ) - @CommandPermissions("worldedit.reload") - @Console - public void reload(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - we.getServer().reload(); - player.print("Configuration reloaded!"); - } - - @Command( - aliases = { "cui" }, - usage = "", - desc = "Complete CUI handshake", - min = 0, - max = 0 - ) - public void cui(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - session.setCUISupport(true); - session.dispatchCUISetup(player); - } - - @Command( - aliases = { "tz" }, - usage = "[timezone]", - desc = "Set your timezone", - min = 1, - max = 1 - ) - @Console - public void tz(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - TimeZone tz = TimeZone.getTimeZone(args.getString(0)); - session.setTimezone(tz); - player.print("Timezone set for this session to: " + tz.getDisplayName()); - player.print("The current time in that timezone is: " - + dateFormat.format(Calendar.getInstance(tz).getTime())); - } - - @Command( - aliases = { "help" }, - usage = "[]", - desc = "Displays help for the given command or lists all commands.", - min = 0, - max = -1 - ) - @CommandPermissions("worldedit.help") - @Console - public void help(CommandContext args, LocalSession session, LocalPlayer player, - EditSession editSession) throws WorldEditException { - - UtilityCommands.help(args, we, session, player, editSession); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.TimeZone; +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.Console; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; + +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 + ) + @Console + public void version(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + player.print("WorldEdit version " + WorldEdit.getVersion()); + player.print("http://www.sk89q.com/projects/worldedit/"); + } + + @Command( + aliases = { "reload" }, + usage = "", + desc = "Reload WorldEdit", + min = 0, + max = 0 + ) + @CommandPermissions("worldedit.reload") + @Console + public void reload(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + we.getServer().reload(); + player.print("Configuration reloaded!"); + } + + @Command( + aliases = { "cui" }, + usage = "", + desc = "Complete CUI handshake", + min = 0, + max = 0 + ) + public void cui(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + session.setCUISupport(true); + session.dispatchCUISetup(player); + } + + @Command( + aliases = { "tz" }, + usage = "[timezone]", + desc = "Set your timezone", + min = 1, + max = 1 + ) + @Console + public void tz(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + TimeZone tz = TimeZone.getTimeZone(args.getString(0)); + session.setTimezone(tz); + player.print("Timezone set for this session to: " + tz.getDisplayName()); + player.print("The current time in that timezone is: " + + dateFormat.format(Calendar.getInstance(tz).getTime())); + } + + @Command( + aliases = { "help" }, + usage = "[]", + desc = "Displays help for the given command or lists all commands.", + min = 0, + max = -1 + ) + @CommandPermissions("worldedit.help") + @Console + public void help(CommandContext args, LocalSession session, LocalPlayer player, + EditSession editSession) throws WorldEditException { + + UtilityCommands.help(args, we, session, player, editSession); + } +} diff --git a/src/main/java/com/sk89q/worldedit/tools/AreaPickaxe.java b/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/tools/AreaPickaxe.java rename to src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java index 09980e24e..1ff96891b 100644 --- a/src/main/java/com/sk89q/worldedit/tools/AreaPickaxe.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java @@ -1,87 +1,87 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockID; - -/** - * A super pickaxe mode that will remove blocks in an area. - * - * @author sk89q - */ -public class AreaPickaxe implements BlockTool { - private static final BaseBlock air = new BaseBlock(0); - private int range; - - public AreaPickaxe(int range) { - this.range = range; - } - - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.superpickaxe.area"); - } - - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked) { - LocalWorld world = clicked.getWorld(); - int ox = clicked.getBlockX(); - int oy = clicked.getBlockY(); - int oz = clicked.getBlockZ(); - int initialType = world.getBlockType(clicked); - - if (initialType == 0) { - return true; - } - - if (initialType == BlockID.BEDROCK && !player.canDestroyBedrock()) { - return true; - } - - EditSession editSession = session.createEditSession(player); - - try { - for (int x = ox - range; x <= ox + range; ++x) { - for (int y = oy - range; y <= oy + range; ++y) { - for (int z = oz - range; z <= oz + range; ++z) { - Vector pos = new Vector(x, y, z); - if (world.getBlockType(pos) != initialType) { - continue; - } - if (config.superPickaxeManyDrop) { - world.simulateBlockMine(pos); - } - - world.queueBlockBreakEffect(server, pos, initialType, clicked.distanceSq(pos)); - - editSession.setBlock(pos, air); - } - } - } - } catch (MaxChangedBlocksException e) { - player.printError("Max blocks change limit reached."); - } finally { - session.remember(editSession); - } - - return true; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; + +/** + * A super pickaxe mode that will remove blocks in an area. + * + * @author sk89q + */ +public class AreaPickaxe implements BlockTool { + private static final BaseBlock air = new BaseBlock(0); + private int range; + + public AreaPickaxe(int range) { + this.range = range; + } + + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.superpickaxe.area"); + } + + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked) { + LocalWorld world = clicked.getWorld(); + int ox = clicked.getBlockX(); + int oy = clicked.getBlockY(); + int oz = clicked.getBlockZ(); + int initialType = world.getBlockType(clicked); + + if (initialType == 0) { + return true; + } + + if (initialType == BlockID.BEDROCK && !player.canDestroyBedrock()) { + return true; + } + + EditSession editSession = session.createEditSession(player); + + try { + for (int x = ox - range; x <= ox + range; ++x) { + for (int y = oy - range; y <= oy + range; ++y) { + for (int z = oz - range; z <= oz + range; ++z) { + Vector pos = new Vector(x, y, z); + if (world.getBlockType(pos) != initialType) { + continue; + } + if (config.superPickaxeManyDrop) { + world.simulateBlockMine(pos); + } + + world.queueBlockBreakEffect(server, pos, initialType, clicked.distanceSq(pos)); + + editSession.setBlock(pos, air); + } + } + } + } catch (MaxChangedBlocksException e) { + player.printError("Max blocks change limit reached."); + } finally { + session.remember(editSession); + } + + return true; + } +} diff --git a/src/main/java/com/sk89q/worldedit/tools/BlockDataCyler.java b/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/tools/BlockDataCyler.java rename to src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java index 3ea507555..eeac59eaf 100644 --- a/src/main/java/com/sk89q/worldedit/tools/BlockDataCyler.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java @@ -1,74 +1,74 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.blocks.BaseBlock; - -/** - * A mode that cycles the data values of supported blocks. - * - * @author sk89q - */ -public class BlockDataCyler implements DoubleActionBlockTool { - - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.tool.data-cycler"); - } - - private boolean handleCycle(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked, boolean forward) { - - LocalWorld world = clicked.getWorld(); - - int type = world.getBlockType(clicked); - int data = world.getBlockData(clicked); - - if (config.allowedDataCycleBlocks.size() > 0 - && !player.hasPermission("worldedit.override.data-cycler") - && !config.allowedDataCycleBlocks.contains(type)) { - player.printError("You are not permitted to cycle the data value of that block."); - return true; - } - - int increment = forward ? 1 : -1; - data = (new BaseBlock(type, data)).cycleData(increment); - - if (data < 0) { - player.printError("That block's data cannot be cycled!"); - } else { - world.setBlockData(clicked, data); - } - - return true; - } - - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked) { - return handleCycle(server, config, player, session, clicked, true); - } - - public boolean actSecondary(ServerInterface server, - LocalConfiguration config, LocalPlayer player, - LocalSession session, WorldVector clicked) { - return handleCycle(server, config, player, session, clicked, false); - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.BaseBlock; + +/** + * A mode that cycles the data values of supported blocks. + * + * @author sk89q + */ +public class BlockDataCyler implements DoubleActionBlockTool { + + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.tool.data-cycler"); + } + + private boolean handleCycle(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked, boolean forward) { + + LocalWorld world = clicked.getWorld(); + + int type = world.getBlockType(clicked); + int data = world.getBlockData(clicked); + + if (config.allowedDataCycleBlocks.size() > 0 + && !player.hasPermission("worldedit.override.data-cycler") + && !config.allowedDataCycleBlocks.contains(type)) { + player.printError("You are not permitted to cycle the data value of that block."); + return true; + } + + int increment = forward ? 1 : -1; + data = (new BaseBlock(type, data)).cycleData(increment); + + if (data < 0) { + player.printError("That block's data cannot be cycled!"); + } else { + world.setBlockData(clicked, data); + } + + return true; + } + + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked) { + return handleCycle(server, config, player, session, clicked, true); + } + + public boolean actSecondary(ServerInterface server, + LocalConfiguration config, LocalPlayer player, + LocalSession session, WorldVector clicked) { + return handleCycle(server, config, player, session, clicked, false); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/tools/BlockReplacer.java b/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/BlockReplacer.java rename to src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java index d6b829171..18a3e5a3d 100644 --- a/src/main/java/com/sk89q/worldedit/tools/BlockReplacer.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java @@ -1,80 +1,80 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.bags.BlockBag; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockType; - -/** - * A mode that replaces one block. - * - * @author sk89q - */ -public class BlockReplacer implements DoubleActionBlockTool { - private BaseBlock targetBlock; - - public BlockReplacer(BaseBlock targetBlock) { - this.targetBlock = targetBlock; - } - - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.tool.replacer"); - } - - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked) { - - BlockBag bag = session.getBlockBag(player); - - LocalWorld world = clicked.getWorld(); - EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1, bag, player); - - try { - editSession.setBlock(clicked, targetBlock); - } catch (MaxChangedBlocksException e) { - } finally { - if (bag != null) { - bag.flushChanges(); - } - session.remember(editSession); - } - - return true; - } - - public boolean actSecondary(ServerInterface server, - LocalConfiguration config, LocalPlayer player, - LocalSession session, WorldVector clicked) { - - LocalWorld world = clicked.getWorld(); - EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1, player); - targetBlock = (editSession).getBlock(clicked); - BlockType type = BlockType.fromID(targetBlock.getType()); - - if (type != null) { - player.print("Replacer tool switched to: " + type.getName()); - } - - return true; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockType; + +/** + * A mode that replaces one block. + * + * @author sk89q + */ +public class BlockReplacer implements DoubleActionBlockTool { + private BaseBlock targetBlock; + + public BlockReplacer(BaseBlock targetBlock) { + this.targetBlock = targetBlock; + } + + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.tool.replacer"); + } + + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked) { + + BlockBag bag = session.getBlockBag(player); + + LocalWorld world = clicked.getWorld(); + EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1, bag, player); + + try { + editSession.setBlock(clicked, targetBlock); + } catch (MaxChangedBlocksException e) { + } finally { + if (bag != null) { + bag.flushChanges(); + } + session.remember(editSession); + } + + return true; + } + + public boolean actSecondary(ServerInterface server, + LocalConfiguration config, LocalPlayer player, + LocalSession session, WorldVector clicked) { + + LocalWorld world = clicked.getWorld(); + EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1, player); + targetBlock = (editSession).getBlock(clicked); + BlockType type = BlockType.fromID(targetBlock.getType()); + + if (type != null) { + player.print("Replacer tool switched to: " + type.getName()); + } + + return true; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/tools/BlockTool.java b/src/main/java/com/sk89q/worldedit/command/tool/BlockTool.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/BlockTool.java rename to src/main/java/com/sk89q/worldedit/command/tool/BlockTool.java index 4ecb1a503..8c40858fb 100644 --- a/src/main/java/com/sk89q/worldedit/tools/BlockTool.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/BlockTool.java @@ -1,43 +1,43 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.*; - -/** - * Represents a tool that uses a block.. - * - * @author sk89q - */ -public interface BlockTool extends Tool { - /** - * Perform the action. Should return true to deny the default - * action. - * - * @param server - * @param config - * @param player - * @param session - * @param clicked - * @return true to deny - */ - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked); -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.*; + +/** + * Represents a tool that uses a block.. + * + * @author sk89q + */ +public interface BlockTool extends Tool { + /** + * Perform the action. Should return true to deny the default + * action. + * + * @param server + * @param config + * @param player + * @param session + * @param clicked + * @return true to deny + */ + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked); +} diff --git a/src/main/java/com/sk89q/worldedit/tools/BrushTool.java b/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/tools/BrushTool.java rename to src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java index 100036e2f..9004d6c0a 100644 --- a/src/main/java/com/sk89q/worldedit/tools/BrushTool.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java @@ -1,208 +1,208 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.bags.BlockBag; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockID; -import com.sk89q.worldedit.masks.CombinedMask; -import com.sk89q.worldedit.masks.Mask; -import com.sk89q.worldedit.patterns.Pattern; -import com.sk89q.worldedit.patterns.SingleBlockPattern; -import com.sk89q.worldedit.tools.brushes.Brush; -import com.sk89q.worldedit.tools.brushes.SphereBrush; - -/** - * Builds a shape at the place being looked at. - * - * @author sk89q - */ -public class BrushTool implements TraceTool { - protected static int MAX_RANGE = 500; - protected int range = -1; - private Mask mask = null; - private Brush brush = new SphereBrush(); - private Pattern material = new SingleBlockPattern(new BaseBlock(BlockID.COBBLESTONE)); - private double size = 1; - private String permission; - - /** - * Construct the tool. - * - * @param permission - */ - public BrushTool(String permission) { - this.permission = permission; - } - - /** - * Checks to see if the player can still be using this tool (considering - * permissions and such). - * - * @param player - * @return - */ - public boolean canUse(LocalPlayer player) { - return player.hasPermission(permission); - } - - /** - * Get the filter. - * - * @return the filter - */ - public Mask getMask() { - return mask; - } - - /** - * Set the block filter used for identifying blocks to replace. - * - * @param filter the filter to set - */ - public void setMask(Mask filter) { - this.mask = filter; - } - - /** - * Set the brush. - * - * @param brush - * @param perm - */ - public void setBrush(Brush brush, String perm) { - this.brush = brush; - this.permission = perm; - } - - /** - * Get the current brush. - * - * @return - */ - public Brush getBrush() { - return brush; - } - - /** - * Set the material. - * - * @param material - */ - public void setFill(Pattern material) { - this.material = material; - } - - /** - * Get the material. - * - * @return - */ - public Pattern getMaterial() { - return material; - } - - /** - * Get the set brush size. - * - * @return - */ - public double getSize() { - return size; - } - - /** - * Set the set brush size. - * - * @param radius - */ - public void setSize(double radius) { - this.size = radius; - } - - /** - * Get the set brush range. - * - * @return - */ - public int getRange() { - return (range < 0) ? MAX_RANGE : Math.min(range, MAX_RANGE); - } - - /** - * Set the set brush range. - * - * @param size - */ - public void setRange(int range) { - this.range = range; - } - - /** - * Perform the action. Should return true to deny the default - * action. - * - * @param player - * @param session - * @return true to deny - */ - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session) { - WorldVector target = null; - target = player.getBlockTrace(getRange(), true); - - if (target == null) { - player.printError("No block in sight!"); - return true; - } - - BlockBag bag = session.getBlockBag(player); - - EditSession editSession = session.createEditSession(player); - if (mask != null) { - mask.prepare(session, player, target); - Mask existingMask = editSession.getMask(); - if (existingMask == null) { - editSession.setMask(mask); - } else if (existingMask instanceof CombinedMask) { - ((CombinedMask) existingMask).add(mask); - } else { - CombinedMask newMask = new CombinedMask(existingMask); - newMask.add(mask); - editSession.setMask(newMask); - } - } - - try { - brush.build(editSession, target, material, size); - } catch (MaxChangedBlocksException e) { - player.printError("Max blocks change limit reached."); - } finally { - if (bag != null) { - bag.flushChanges(); - } - session.remember(editSession); - } - - return true; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.masks.CombinedMask; +import com.sk89q.worldedit.masks.Mask; +import com.sk89q.worldedit.patterns.Pattern; +import com.sk89q.worldedit.patterns.SingleBlockPattern; +import com.sk89q.worldedit.command.tool.brush.Brush; +import com.sk89q.worldedit.command.tool.brush.SphereBrush; + +/** + * Builds a shape at the place being looked at. + * + * @author sk89q + */ +public class BrushTool implements TraceTool { + protected static int MAX_RANGE = 500; + protected int range = -1; + private Mask mask = null; + private Brush brush = new SphereBrush(); + private Pattern material = new SingleBlockPattern(new BaseBlock(BlockID.COBBLESTONE)); + private double size = 1; + private String permission; + + /** + * Construct the tool. + * + * @param permission + */ + public BrushTool(String permission) { + this.permission = permission; + } + + /** + * Checks to see if the player can still be using this tool (considering + * permissions and such). + * + * @param player + * @return + */ + public boolean canUse(LocalPlayer player) { + return player.hasPermission(permission); + } + + /** + * Get the filter. + * + * @return the filter + */ + public Mask getMask() { + return mask; + } + + /** + * Set the block filter used for identifying blocks to replace. + * + * @param filter the filter to set + */ + public void setMask(Mask filter) { + this.mask = filter; + } + + /** + * Set the brush. + * + * @param brush + * @param perm + */ + public void setBrush(Brush brush, String perm) { + this.brush = brush; + this.permission = perm; + } + + /** + * Get the current brush. + * + * @return + */ + public Brush getBrush() { + return brush; + } + + /** + * Set the material. + * + * @param material + */ + public void setFill(Pattern material) { + this.material = material; + } + + /** + * Get the material. + * + * @return + */ + public Pattern getMaterial() { + return material; + } + + /** + * Get the set brush size. + * + * @return + */ + public double getSize() { + return size; + } + + /** + * Set the set brush size. + * + * @param radius + */ + public void setSize(double radius) { + this.size = radius; + } + + /** + * Get the set brush range. + * + * @return + */ + public int getRange() { + return (range < 0) ? MAX_RANGE : Math.min(range, MAX_RANGE); + } + + /** + * Set the set brush range. + * + * @param size + */ + public void setRange(int range) { + this.range = range; + } + + /** + * Perform the action. Should return true to deny the default + * action. + * + * @param player + * @param session + * @return true to deny + */ + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session) { + WorldVector target = null; + target = player.getBlockTrace(getRange(), true); + + if (target == null) { + player.printError("No block in sight!"); + return true; + } + + BlockBag bag = session.getBlockBag(player); + + EditSession editSession = session.createEditSession(player); + if (mask != null) { + mask.prepare(session, player, target); + Mask existingMask = editSession.getMask(); + if (existingMask == null) { + editSession.setMask(mask); + } else if (existingMask instanceof CombinedMask) { + ((CombinedMask) existingMask).add(mask); + } else { + CombinedMask newMask = new CombinedMask(existingMask); + newMask.add(mask); + editSession.setMask(newMask); + } + } + + try { + brush.build(editSession, target, material, size); + } catch (MaxChangedBlocksException e) { + player.printError("Max blocks change limit reached."); + } finally { + if (bag != null) { + bag.flushChanges(); + } + session.remember(editSession); + } + + return true; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/tools/DistanceWand.java b/src/main/java/com/sk89q/worldedit/command/tool/DistanceWand.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/tools/DistanceWand.java rename to src/main/java/com/sk89q/worldedit/command/tool/DistanceWand.java index 74337aa94..b34505e31 100644 --- a/src/main/java/com/sk89q/worldedit/tools/DistanceWand.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/DistanceWand.java @@ -1,90 +1,90 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.regions.RegionSelector; - -/** - * A wand that can be used at a distance. - * - * @author wizjany - */ -public class DistanceWand extends BrushTool implements DoubleActionTraceTool { - - public DistanceWand() { - super("worldedit.wand"); - } - - @Override - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.wand"); - } - - public boolean actSecondary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session) { - if (session.isToolControlEnabled() && player.hasPermission("worldedit.selection.pos")) { - WorldVector target = getTarget(player); - if (target == null) return true; - - RegionSelector selector = session.getRegionSelector(player.getWorld()); - if (selector.selectPrimary(target)) { - selector.explainPrimarySelection(player, session, target); - } - return true; - - } - return false; - - } - - @Override - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session) { - if (session.isToolControlEnabled() && player.hasPermission("worldedit.selection.pos")) { - WorldVector target = getTarget(player); - if (target == null) return true; - - RegionSelector selector = session.getRegionSelector(player.getWorld()); - if (selector.selectSecondary(target)) { - selector.explainSecondarySelection(player, session, target); - } - return true; - - } - return false; - } - - public WorldVector getTarget(LocalPlayer player) { - WorldVector target = null; - if (this.range > -1) { - target = player.getBlockTrace(getRange(), true); - } else { - target = player.getBlockTrace(MAX_RANGE); - } - - if (target == null) { - player.printError("No block in sight!"); - return null; - } - - return target; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.regions.RegionSelector; + +/** + * A wand that can be used at a distance. + * + * @author wizjany + */ +public class DistanceWand extends BrushTool implements DoubleActionTraceTool { + + public DistanceWand() { + super("worldedit.wand"); + } + + @Override + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.wand"); + } + + public boolean actSecondary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session) { + if (session.isToolControlEnabled() && player.hasPermission("worldedit.selection.pos")) { + WorldVector target = getTarget(player); + if (target == null) return true; + + RegionSelector selector = session.getRegionSelector(player.getWorld()); + if (selector.selectPrimary(target)) { + selector.explainPrimarySelection(player, session, target); + } + return true; + + } + return false; + + } + + @Override + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session) { + if (session.isToolControlEnabled() && player.hasPermission("worldedit.selection.pos")) { + WorldVector target = getTarget(player); + if (target == null) return true; + + RegionSelector selector = session.getRegionSelector(player.getWorld()); + if (selector.selectSecondary(target)) { + selector.explainSecondarySelection(player, session, target); + } + return true; + + } + return false; + } + + public WorldVector getTarget(LocalPlayer player) { + WorldVector target = null; + if (this.range > -1) { + target = player.getBlockTrace(getRange(), true); + } else { + target = player.getBlockTrace(MAX_RANGE); + } + + if (target == null) { + player.printError("No block in sight!"); + return null; + } + + return target; + } +} diff --git a/src/main/java/com/sk89q/worldedit/tools/DoubleActionBlockTool.java b/src/main/java/com/sk89q/worldedit/command/tool/DoubleActionBlockTool.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/DoubleActionBlockTool.java rename to src/main/java/com/sk89q/worldedit/command/tool/DoubleActionBlockTool.java index 5145f738a..a48c3391f 100644 --- a/src/main/java/com/sk89q/worldedit/tools/DoubleActionBlockTool.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/DoubleActionBlockTool.java @@ -1,47 +1,47 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.LocalConfiguration; -import com.sk89q.worldedit.LocalPlayer; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.ServerInterface; -import com.sk89q.worldedit.WorldVector; - -/** - * Represents a block tool that also has a secondary/primary function. - * - * @author sk89q - */ -public interface DoubleActionBlockTool extends BlockTool { - /** - * Perform the secondary action. Should return true to deny the default - * action. - * - * @param server - * @param config - * @param player - * @param session - * @param clicked - * @return true to deny - */ - public boolean actSecondary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked); -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.ServerInterface; +import com.sk89q.worldedit.WorldVector; + +/** + * Represents a block tool that also has a secondary/primary function. + * + * @author sk89q + */ +public interface DoubleActionBlockTool extends BlockTool { + /** + * Perform the secondary action. Should return true to deny the default + * action. + * + * @param server + * @param config + * @param player + * @param session + * @param clicked + * @return true to deny + */ + public boolean actSecondary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked); +} diff --git a/src/main/java/com/sk89q/worldedit/tools/DoubleActionTraceTool.java b/src/main/java/com/sk89q/worldedit/command/tool/DoubleActionTraceTool.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/DoubleActionTraceTool.java rename to src/main/java/com/sk89q/worldedit/command/tool/DoubleActionTraceTool.java index 6dce525f4..43695bfe6 100644 --- a/src/main/java/com/sk89q/worldedit/tools/DoubleActionTraceTool.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/DoubleActionTraceTool.java @@ -1,43 +1,43 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.LocalConfiguration; -import com.sk89q.worldedit.LocalPlayer; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.ServerInterface; - -/** - * Represents a trace tool that also has a secondary/primary function. - */ -public interface DoubleActionTraceTool extends TraceTool { - /** - * Perform the secondary action. Should return true to deny the default - * action. - * - * @param server - * @param config - * @param player - * @param session - * @return true to deny - */ - public boolean actSecondary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session); -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.ServerInterface; + +/** + * Represents a trace tool that also has a secondary/primary function. + */ +public interface DoubleActionTraceTool extends TraceTool { + /** + * Perform the secondary action. Should return true to deny the default + * action. + * + * @param server + * @param config + * @param player + * @param session + * @return true to deny + */ + public boolean actSecondary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session); +} diff --git a/src/main/java/com/sk89q/worldedit/tools/FloatingTreeRemover.java b/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java old mode 100755 new mode 100644 similarity index 96% rename from src/main/java/com/sk89q/worldedit/tools/FloatingTreeRemover.java rename to src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java index dac067df2..4620aa00d --- a/src/main/java/com/sk89q/worldedit/tools/FloatingTreeRemover.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java @@ -1,166 +1,166 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Set; -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockID; - -/** - * A pickaxe mode that removes floating treetops (logs and leaves not connected - * to anything else) - * - * @author Moo0 - */ -public class FloatingTreeRemover implements BlockTool { - private static final BaseBlock AIR = new BaseBlock(BlockID.AIR); - private int rangeSq; - - public FloatingTreeRemover() { - rangeSq = 100*100; - } - - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.tool.deltree"); - } - - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked) { - - final LocalWorld world = clicked.getWorld(); - - switch (world.getBlockType(clicked)) { - case BlockID.LOG: - case BlockID.LOG2: - case BlockID.LEAVES: - case BlockID.LEAVES2: - case BlockID.BROWN_MUSHROOM_CAP: - case BlockID.RED_MUSHROOM_CAP: - case BlockID.VINE: - break; - - default: - player.printError("That's not a tree."); - return true; - } - - final EditSession editSession = session.createEditSession(player); - - try { - final Set blockSet = bfs(world, clicked); - if (blockSet == null) { - player.printError("That's not a floating tree."); - return true; - } - - for (Vector blockVector : blockSet) { - final int typeId = editSession.getBlock(blockVector).getType(); - switch (typeId) { - case BlockID.LOG: - case BlockID.LOG2: - case BlockID.LEAVES: - case BlockID.LEAVES2: - case BlockID.BROWN_MUSHROOM_CAP: - case BlockID.RED_MUSHROOM_CAP: - case BlockID.VINE: - editSession.setBlock(blockVector, AIR); - } - } - } catch (MaxChangedBlocksException e) { - player.printError("Max blocks change limit reached."); - } finally { - session.remember(editSession); - } - - return true; - } - - Vector[] recurseDirections = { - PlayerDirection.NORTH.vector(), - PlayerDirection.EAST.vector(), - PlayerDirection.SOUTH.vector(), - PlayerDirection.WEST.vector(), - PlayerDirection.UP.vector(), - PlayerDirection.DOWN.vector(), - }; - - /** - * Helper method. - * - * @param world the world that contains the tree - * @param origin any point contained in the floating tree - * @return a set containing all blocks in the tree/shroom or null if this is not a floating tree/shroom. - */ - private Set bfs(LocalWorld world, Vector origin) throws MaxChangedBlocksException { - final Set visited = new HashSet(); - final LinkedList queue = new LinkedList(); - - queue.addLast(origin); - visited.add(origin); - - while (!queue.isEmpty()) { - final Vector current = queue.removeFirst(); - for (Vector recurseDirection : recurseDirections) { - final Vector next = current.add(recurseDirection); - if (origin.distanceSq(next) > rangeSq) { - // Maximum range exceeded => stop walking - continue; - } - - if (visited.add(next)) { - switch (world.getBlockType(next)) { - case BlockID.AIR: - case BlockID.SNOW: - // we hit air or snow => stop walking this route - continue; - - case BlockID.LOG: - case BlockID.LOG2: - case BlockID.LEAVES: - case BlockID.LEAVES2: - case BlockID.BROWN_MUSHROOM_CAP: - case BlockID.RED_MUSHROOM_CAP: - case BlockID.VINE: - // queue next point - queue.addLast(next); - break; - - default: - // we hit something solid - evaluate where we came from - final int curId = world.getBlockType(current); - if (curId == BlockID.LEAVES || curId == BlockID.LEAVES2 - || curId == BlockID.VINE) { - // leaves touching a wall/the ground => stop walking this route - continue; - } else { - // log/shroom touching a wall/the ground => this is not a floating tree, bail out - return null; - } - } // switch - } // if - } // for - } // while - - return visited; - } // bfs -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; + +/** + * A pickaxe mode that removes floating treetops (logs and leaves not connected + * to anything else) + * + * @author Moo0 + */ +public class FloatingTreeRemover implements BlockTool { + private static final BaseBlock AIR = new BaseBlock(BlockID.AIR); + private int rangeSq; + + public FloatingTreeRemover() { + rangeSq = 100*100; + } + + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.tool.deltree"); + } + + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked) { + + final LocalWorld world = clicked.getWorld(); + + switch (world.getBlockType(clicked)) { + case BlockID.LOG: + case BlockID.LOG2: + case BlockID.LEAVES: + case BlockID.LEAVES2: + case BlockID.BROWN_MUSHROOM_CAP: + case BlockID.RED_MUSHROOM_CAP: + case BlockID.VINE: + break; + + default: + player.printError("That's not a tree."); + return true; + } + + final EditSession editSession = session.createEditSession(player); + + try { + final Set blockSet = bfs(world, clicked); + if (blockSet == null) { + player.printError("That's not a floating tree."); + return true; + } + + for (Vector blockVector : blockSet) { + final int typeId = editSession.getBlock(blockVector).getType(); + switch (typeId) { + case BlockID.LOG: + case BlockID.LOG2: + case BlockID.LEAVES: + case BlockID.LEAVES2: + case BlockID.BROWN_MUSHROOM_CAP: + case BlockID.RED_MUSHROOM_CAP: + case BlockID.VINE: + editSession.setBlock(blockVector, AIR); + } + } + } catch (MaxChangedBlocksException e) { + player.printError("Max blocks change limit reached."); + } finally { + session.remember(editSession); + } + + return true; + } + + Vector[] recurseDirections = { + PlayerDirection.NORTH.vector(), + PlayerDirection.EAST.vector(), + PlayerDirection.SOUTH.vector(), + PlayerDirection.WEST.vector(), + PlayerDirection.UP.vector(), + PlayerDirection.DOWN.vector(), + }; + + /** + * Helper method. + * + * @param world the world that contains the tree + * @param origin any point contained in the floating tree + * @return a set containing all blocks in the tree/shroom or null if this is not a floating tree/shroom. + */ + private Set bfs(LocalWorld world, Vector origin) throws MaxChangedBlocksException { + final Set visited = new HashSet(); + final LinkedList queue = new LinkedList(); + + queue.addLast(origin); + visited.add(origin); + + while (!queue.isEmpty()) { + final Vector current = queue.removeFirst(); + for (Vector recurseDirection : recurseDirections) { + final Vector next = current.add(recurseDirection); + if (origin.distanceSq(next) > rangeSq) { + // Maximum range exceeded => stop walking + continue; + } + + if (visited.add(next)) { + switch (world.getBlockType(next)) { + case BlockID.AIR: + case BlockID.SNOW: + // we hit air or snow => stop walking this route + continue; + + case BlockID.LOG: + case BlockID.LOG2: + case BlockID.LEAVES: + case BlockID.LEAVES2: + case BlockID.BROWN_MUSHROOM_CAP: + case BlockID.RED_MUSHROOM_CAP: + case BlockID.VINE: + // queue next point + queue.addLast(next); + break; + + default: + // we hit something solid - evaluate where we came from + final int curId = world.getBlockType(current); + if (curId == BlockID.LEAVES || curId == BlockID.LEAVES2 + || curId == BlockID.VINE) { + // leaves touching a wall/the ground => stop walking this route + continue; + } else { + // log/shroom touching a wall/the ground => this is not a floating tree, bail out + return null; + } + } // switch + } // if + } // for + } // while + + return visited; + } // bfs +} diff --git a/src/main/java/com/sk89q/worldedit/tools/FloodFillTool.java b/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/tools/FloodFillTool.java rename to src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java index ba81116d3..f4901eac4 100644 --- a/src/main/java/com/sk89q/worldedit/tools/FloodFillTool.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java @@ -1,118 +1,118 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import java.util.HashSet; -import java.util.Set; -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.blocks.BlockID; -import com.sk89q.worldedit.patterns.Pattern; - -/** - * A tool that flood fills blocks. - * - * @author sk89q - */ -public class FloodFillTool implements BlockTool { - private int range; - private Pattern pattern; - - public FloodFillTool(int range, Pattern pattern) { - this.range = range; - this.pattern = pattern; - } - - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.tool.flood-fill"); - } - - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked) { - LocalWorld world = clicked.getWorld(); - - int initialType = world.getBlockType(clicked); - - if (initialType == BlockID.AIR) { - return true; - } - - if (initialType == BlockID.BEDROCK && !player.canDestroyBedrock()) { - return true; - } - - EditSession editSession = session.createEditSession(player); - - try { - recurse(server, editSession, world, clicked.toBlockVector(), - clicked, range, initialType, new HashSet()); - } catch (MaxChangedBlocksException e) { - player.printError("Max blocks change limit reached."); - } finally { - session.remember(editSession); - } - - return true; - } - - /** - * Helper method. - * - * @param server - * @param superPickaxeManyDrop - * @param world - * @param pos - * @param origin - * @param size - * @param initialType - * @param visited - */ - private void recurse(ServerInterface server, EditSession editSession, - LocalWorld world, BlockVector pos, - Vector origin, int size, int initialType, - Set visited) - throws MaxChangedBlocksException { - - if (origin.distance(pos) > size || visited.contains(pos)) { - return; - } - - visited.add(pos); - - if (editSession.getBlock(pos).getType() == initialType) { - editSession.setBlock(pos, pattern.next(pos)); - } else { - return; - } - - recurse(server, editSession, world, pos.add(1, 0, 0).toBlockVector(), - origin, size, initialType, visited); - recurse(server, editSession, world, pos.add(-1, 0, 0).toBlockVector(), - origin, size, initialType, visited); - recurse(server, editSession, world, pos.add(0, 0, 1).toBlockVector(), - origin, size, initialType, visited); - recurse(server, editSession, world, pos.add(0, 0, -1).toBlockVector(), - origin, size, initialType, visited); - recurse(server, editSession, world, pos.add(0, 1, 0).toBlockVector(), - origin, size, initialType, visited); - recurse(server, editSession, world, pos.add(0, -1, 0).toBlockVector(), - origin, size, initialType, visited); - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import java.util.HashSet; +import java.util.Set; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.patterns.Pattern; + +/** + * A tool that flood fills blocks. + * + * @author sk89q + */ +public class FloodFillTool implements BlockTool { + private int range; + private Pattern pattern; + + public FloodFillTool(int range, Pattern pattern) { + this.range = range; + this.pattern = pattern; + } + + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.tool.flood-fill"); + } + + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked) { + LocalWorld world = clicked.getWorld(); + + int initialType = world.getBlockType(clicked); + + if (initialType == BlockID.AIR) { + return true; + } + + if (initialType == BlockID.BEDROCK && !player.canDestroyBedrock()) { + return true; + } + + EditSession editSession = session.createEditSession(player); + + try { + recurse(server, editSession, world, clicked.toBlockVector(), + clicked, range, initialType, new HashSet()); + } catch (MaxChangedBlocksException e) { + player.printError("Max blocks change limit reached."); + } finally { + session.remember(editSession); + } + + return true; + } + + /** + * Helper method. + * + * @param server + * @param superPickaxeManyDrop + * @param world + * @param pos + * @param origin + * @param size + * @param initialType + * @param visited + */ + private void recurse(ServerInterface server, EditSession editSession, + LocalWorld world, BlockVector pos, + Vector origin, int size, int initialType, + Set visited) + throws MaxChangedBlocksException { + + if (origin.distance(pos) > size || visited.contains(pos)) { + return; + } + + visited.add(pos); + + if (editSession.getBlock(pos).getType() == initialType) { + editSession.setBlock(pos, pattern.next(pos)); + } else { + return; + } + + recurse(server, editSession, world, pos.add(1, 0, 0).toBlockVector(), + origin, size, initialType, visited); + recurse(server, editSession, world, pos.add(-1, 0, 0).toBlockVector(), + origin, size, initialType, visited); + recurse(server, editSession, world, pos.add(0, 0, 1).toBlockVector(), + origin, size, initialType, visited); + recurse(server, editSession, world, pos.add(0, 0, -1).toBlockVector(), + origin, size, initialType, visited); + recurse(server, editSession, world, pos.add(0, 1, 0).toBlockVector(), + origin, size, initialType, visited); + recurse(server, editSession, world, pos.add(0, -1, 0).toBlockVector(), + origin, size, initialType, visited); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/tools/LongRangeBuildTool.java b/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/tools/LongRangeBuildTool.java rename to src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java index ade228f06..53d80859a 100644 --- a/src/main/java/com/sk89q/worldedit/tools/LongRangeBuildTool.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java @@ -1,98 +1,98 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockID; - -/** - * A tool that can place (or remove) blocks at a distance. - * - * @author wizjany - */ -public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTool { - - BaseBlock primary; - BaseBlock secondary; - - public LongRangeBuildTool(BaseBlock primary, BaseBlock secondary) { - super("worldedit.tool.lrbuild"); - this.primary = primary; - this.secondary = secondary; - } - - @Override - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.tool.lrbuild"); - } - - public boolean actSecondary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session) { - - WorldVectorFace pos = getTargetFace(player); - if (pos == null) return false; - EditSession eS = session.createEditSession(player); - try { - if (secondary.getType() == BlockID.AIR) { - eS.setBlock(pos, secondary); - } else { - eS.setBlock(pos.getFaceVector(), secondary); - } - return true; - } catch (MaxChangedBlocksException e) { - // one block? eat it - } - return false; - - } - - @Override - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session) { - - WorldVectorFace pos = getTargetFace(player); - if (pos == null) return false; - EditSession eS = session.createEditSession(player); - try { - if (primary.getType() == BlockID.AIR) { - eS.setBlock(pos, primary); - } else { - eS.setBlock(pos.getFaceVector(), primary); - } - return true; - } catch (MaxChangedBlocksException e) { - // one block? eat it - } - return false; - } - - public WorldVectorFace getTargetFace(LocalPlayer player) { - WorldVectorFace target = null; - target = player.getBlockTraceFace(getRange(), true); - - if (target == null) { - player.printError("No block in sight!"); - return null; - } - - return target; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; + +/** + * A tool that can place (or remove) blocks at a distance. + * + * @author wizjany + */ +public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTool { + + BaseBlock primary; + BaseBlock secondary; + + public LongRangeBuildTool(BaseBlock primary, BaseBlock secondary) { + super("worldedit.tool.lrbuild"); + this.primary = primary; + this.secondary = secondary; + } + + @Override + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.tool.lrbuild"); + } + + public boolean actSecondary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session) { + + WorldVectorFace pos = getTargetFace(player); + if (pos == null) return false; + EditSession eS = session.createEditSession(player); + try { + if (secondary.getType() == BlockID.AIR) { + eS.setBlock(pos, secondary); + } else { + eS.setBlock(pos.getFaceVector(), secondary); + } + return true; + } catch (MaxChangedBlocksException e) { + // one block? eat it + } + return false; + + } + + @Override + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session) { + + WorldVectorFace pos = getTargetFace(player); + if (pos == null) return false; + EditSession eS = session.createEditSession(player); + try { + if (primary.getType() == BlockID.AIR) { + eS.setBlock(pos, primary); + } else { + eS.setBlock(pos.getFaceVector(), primary); + } + return true; + } catch (MaxChangedBlocksException e) { + // one block? eat it + } + return false; + } + + public WorldVectorFace getTargetFace(LocalPlayer player) { + WorldVectorFace target = null; + target = player.getBlockTraceFace(getRange(), true); + + if (target == null) { + player.printError("No block in sight!"); + return null; + } + + return target; + } +} diff --git a/src/main/java/com/sk89q/worldedit/tools/QueryTool.java b/src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/tools/QueryTool.java rename to src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java index 5621520a7..e66fe6e89 100644 --- a/src/main/java/com/sk89q/worldedit/tools/QueryTool.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java @@ -1,65 +1,65 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.blocks.*; - -/** - * Plants a tree. - * - * @author sk89q - */ -public class QueryTool implements BlockTool { - - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.tool.info"); - } - - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked) { - - LocalWorld world = clicked.getWorld(); - EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, 0, player); - BaseBlock block = (editSession).rawGetBlock(clicked); - BlockType type = BlockType.fromID(block.getType()); - - player.print("\u00A79@" + clicked + ": " + "\u00A7e" - + "#" + block.getType() + "\u00A77" + " (" - + (type == null ? "Unknown" : type.getName()) + ") " - + "\u00A7f" - + "[" + block.getData() + "]" + " (" + world.getBlockLightLevel(clicked) + "/" + world.getBlockLightLevel(clicked.add(0, 1, 0)) + ")"); - - if (block instanceof MobSpawnerBlock) { - player.printRaw("\u00A7e" + "Mob Type: " - + ((MobSpawnerBlock) block).getMobType()); - } else if (block instanceof NoteBlock) { - player.printRaw("\u00A7e" + "Note block: " - + ((NoteBlock) block).getNote()); - } else if (block.getType() == BlockID.CLOTH) { - // Should never be null - player.printRaw("\u00A7e" + "Color: " - + ClothColor.fromID(block.getData()).getName()); - } - - return true; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.*; + +/** + * Plants a tree. + * + * @author sk89q + */ +public class QueryTool implements BlockTool { + + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.tool.info"); + } + + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked) { + + LocalWorld world = clicked.getWorld(); + EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, 0, player); + BaseBlock block = (editSession).rawGetBlock(clicked); + BlockType type = BlockType.fromID(block.getType()); + + player.print("\u00A79@" + clicked + ": " + "\u00A7e" + + "#" + block.getType() + "\u00A77" + " (" + + (type == null ? "Unknown" : type.getName()) + ") " + + "\u00A7f" + + "[" + block.getData() + "]" + " (" + world.getBlockLightLevel(clicked) + "/" + world.getBlockLightLevel(clicked.add(0, 1, 0)) + ")"); + + if (block instanceof MobSpawnerBlock) { + player.printRaw("\u00A7e" + "Mob Type: " + + ((MobSpawnerBlock) block).getMobType()); + } else if (block instanceof NoteBlock) { + player.printRaw("\u00A7e" + "Note block: " + + ((NoteBlock) block).getNote()); + } else if (block.getType() == BlockID.CLOTH) { + // Should never be null + player.printRaw("\u00A7e" + "Color: " + + ClothColor.fromID(block.getData()).getName()); + } + + return true; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/tools/RecursivePickaxe.java b/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/tools/RecursivePickaxe.java rename to src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java index e0099d5d7..f21e9fc10 100644 --- a/src/main/java/com/sk89q/worldedit/tools/RecursivePickaxe.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java @@ -1,127 +1,127 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import java.util.HashSet; -import java.util.Set; - -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockID; - -/** - * A pickaxe mode that recursively finds adjacent blocks within range of - * an initial block and of the same type. - * - * @author sk89q - */ -public class RecursivePickaxe implements BlockTool { - private static final BaseBlock air = new BaseBlock(0); - private double range; - - public RecursivePickaxe(double range) { - this.range = range; - } - - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.superpickaxe.recursive"); - } - - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked) { - LocalWorld world = clicked.getWorld(); - - int initialType = world.getBlockType(clicked); - - if (initialType == BlockID.AIR) { - return true; - } - - if (initialType == BlockID.BEDROCK && !player.canDestroyBedrock()) { - return true; - } - - EditSession editSession = session.createEditSession(player); - - try { - recurse(server, editSession, world, clicked.toBlockVector(), - clicked, range, initialType, new HashSet(), - config.superPickaxeManyDrop); - } catch (MaxChangedBlocksException e) { - player.printError("Max blocks change limit reached."); - } finally { - session.remember(editSession); - } - - return true; - } - - /** - * Helper method. - * - * @param server - * @param superPickaxeManyDrop - * @param world - * @param pos - * @param origin - * @param size - * @param initialType - * @param visited - */ - private static void recurse(ServerInterface server, EditSession editSession, - LocalWorld world, BlockVector pos, - Vector origin, double size, int initialType, - Set visited, boolean drop) - throws MaxChangedBlocksException { - - final double distanceSq = origin.distanceSq(pos); - if (distanceSq > size*size || visited.contains(pos)) { - return; - } - - visited.add(pos); - - if (editSession.getBlock(pos).getType() != initialType) { - return; - } - - if (drop) { - world.simulateBlockMine(pos); - } - - world.queueBlockBreakEffect(server, pos, initialType, distanceSq); - - editSession.setBlock(pos, air); - - recurse(server, editSession, world, pos.add(1, 0, 0).toBlockVector(), - origin, size, initialType, visited, drop); - recurse(server, editSession, world, pos.add(-1, 0, 0).toBlockVector(), - origin, size, initialType, visited, drop); - recurse(server, editSession, world, pos.add(0, 0, 1).toBlockVector(), - origin, size, initialType, visited, drop); - recurse(server, editSession, world, pos.add(0, 0, -1).toBlockVector(), - origin, size, initialType, visited, drop); - recurse(server, editSession, world, pos.add(0, 1, 0).toBlockVector(), - origin, size, initialType, visited, drop); - recurse(server, editSession, world, pos.add(0, -1, 0).toBlockVector(), - origin, size, initialType, visited, drop); - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import java.util.HashSet; +import java.util.Set; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; + +/** + * A pickaxe mode that recursively finds adjacent blocks within range of + * an initial block and of the same type. + * + * @author sk89q + */ +public class RecursivePickaxe implements BlockTool { + private static final BaseBlock air = new BaseBlock(0); + private double range; + + public RecursivePickaxe(double range) { + this.range = range; + } + + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.superpickaxe.recursive"); + } + + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked) { + LocalWorld world = clicked.getWorld(); + + int initialType = world.getBlockType(clicked); + + if (initialType == BlockID.AIR) { + return true; + } + + if (initialType == BlockID.BEDROCK && !player.canDestroyBedrock()) { + return true; + } + + EditSession editSession = session.createEditSession(player); + + try { + recurse(server, editSession, world, clicked.toBlockVector(), + clicked, range, initialType, new HashSet(), + config.superPickaxeManyDrop); + } catch (MaxChangedBlocksException e) { + player.printError("Max blocks change limit reached."); + } finally { + session.remember(editSession); + } + + return true; + } + + /** + * Helper method. + * + * @param server + * @param superPickaxeManyDrop + * @param world + * @param pos + * @param origin + * @param size + * @param initialType + * @param visited + */ + private static void recurse(ServerInterface server, EditSession editSession, + LocalWorld world, BlockVector pos, + Vector origin, double size, int initialType, + Set visited, boolean drop) + throws MaxChangedBlocksException { + + final double distanceSq = origin.distanceSq(pos); + if (distanceSq > size*size || visited.contains(pos)) { + return; + } + + visited.add(pos); + + if (editSession.getBlock(pos).getType() != initialType) { + return; + } + + if (drop) { + world.simulateBlockMine(pos); + } + + world.queueBlockBreakEffect(server, pos, initialType, distanceSq); + + editSession.setBlock(pos, air); + + recurse(server, editSession, world, pos.add(1, 0, 0).toBlockVector(), + origin, size, initialType, visited, drop); + recurse(server, editSession, world, pos.add(-1, 0, 0).toBlockVector(), + origin, size, initialType, visited, drop); + recurse(server, editSession, world, pos.add(0, 0, 1).toBlockVector(), + origin, size, initialType, visited, drop); + recurse(server, editSession, world, pos.add(0, 0, -1).toBlockVector(), + origin, size, initialType, visited, drop); + recurse(server, editSession, world, pos.add(0, 1, 0).toBlockVector(), + origin, size, initialType, visited, drop); + recurse(server, editSession, world, pos.add(0, -1, 0).toBlockVector(), + origin, size, initialType, visited, drop); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/tools/SinglePickaxe.java b/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/SinglePickaxe.java rename to src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java index 67d269083..3e2a47de9 100644 --- a/src/main/java/com/sk89q/worldedit/tools/SinglePickaxe.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java @@ -1,57 +1,57 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.blocks.BlockID; - -/** - * A super pickaxe mode that removes one block. - * - * @author sk89q - */ -public class SinglePickaxe implements BlockTool { - - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.superpickaxe"); - } - - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked) { - LocalWorld world = clicked.getWorld(); - - final int blockType = world.getBlockType(clicked); - if (blockType == BlockID.BEDROCK - && !player.canDestroyBedrock()) { - return true; - } - - if (config.superPickaxeDrop) { - world.simulateBlockMine(clicked); - } - - world.setBlockType(clicked, BlockID.AIR); - - world.playEffect(clicked, 2001, blockType); - - return true; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.blocks.BlockID; + +/** + * A super pickaxe mode that removes one block. + * + * @author sk89q + */ +public class SinglePickaxe implements BlockTool { + + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.superpickaxe"); + } + + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked) { + LocalWorld world = clicked.getWorld(); + + final int blockType = world.getBlockType(clicked); + if (blockType == BlockID.BEDROCK + && !player.canDestroyBedrock()) { + return true; + } + + if (config.superPickaxeDrop) { + world.simulateBlockMine(clicked); + } + + world.setBlockType(clicked, BlockID.AIR); + + world.playEffect(clicked, 2001, blockType); + + return true; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/tools/Tool.java b/src/main/java/com/sk89q/worldedit/command/tool/Tool.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/Tool.java rename to src/main/java/com/sk89q/worldedit/command/tool/Tool.java index c20bf2b0d..aae350a51 100644 --- a/src/main/java/com/sk89q/worldedit/tools/Tool.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/Tool.java @@ -1,41 +1,41 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.LocalPlayer; - -/** - * Represents a tool. This interface alone defines nothing. A tool also - * has to implement BlockTool or TraceTool. - * - * @author sk89q - */ -public abstract interface Tool { - - /** - * Checks to see if the player can still be using this tool (considering - * permissions and such). - * - * @param player - * @return - */ - public boolean canUse(LocalPlayer player); - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.LocalPlayer; + +/** + * Represents a tool. This interface alone defines nothing. A tool also + * has to implement BlockTool or TraceTool. + * + * @author sk89q + */ +public abstract interface Tool { + + /** + * Checks to see if the player can still be using this tool (considering + * permissions and such). + * + * @param player + * @return + */ + public boolean canUse(LocalPlayer player); + +} diff --git a/src/main/java/com/sk89q/worldedit/tools/TraceTool.java b/src/main/java/com/sk89q/worldedit/command/tool/TraceTool.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/TraceTool.java rename to src/main/java/com/sk89q/worldedit/command/tool/TraceTool.java index 85e909c2d..c36a17eed 100644 --- a/src/main/java/com/sk89q/worldedit/tools/TraceTool.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/TraceTool.java @@ -1,45 +1,45 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.LocalConfiguration; -import com.sk89q.worldedit.LocalPlayer; -import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.ServerInterface; - -/** - * Represents a tool that does not require a block. - * - * @author sk89q - */ -public interface TraceTool extends Tool { - /** - * Perform the action. Should return true to deny the default - * action. - * - * @param server - * @param config - * @param player - * @param session - * @return true to deny - */ - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session); -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.ServerInterface; + +/** + * Represents a tool that does not require a block. + * + * @author sk89q + */ +public interface TraceTool extends Tool { + /** + * Perform the action. Should return true to deny the default + * action. + * + * @param server + * @param config + * @param player + * @param session + * @return true to deny + */ + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session); +} diff --git a/src/main/java/com/sk89q/worldedit/tools/TreePlanter.java b/src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/tools/TreePlanter.java rename to src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java index 7842dfcc1..4fdc5c235 100644 --- a/src/main/java/com/sk89q/worldedit/tools/TreePlanter.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java @@ -1,68 +1,68 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools; - -import com.sk89q.worldedit.*; -import com.sk89q.worldedit.util.TreeGenerator; - -/** - * Plants a tree. - * - * @author sk89q - */ -public class TreePlanter implements BlockTool { - private TreeGenerator gen; - - public TreePlanter(TreeGenerator gen) { - this.gen = gen; - } - - public boolean canUse(LocalPlayer player) { - return player.hasPermission("worldedit.tool.tree"); - } - - public boolean actPrimary(ServerInterface server, LocalConfiguration config, - LocalPlayer player, LocalSession session, WorldVector clicked) { - - EditSession editSession = session.createEditSession(player); - - try { - boolean successful = false; - - for (int i = 0; i < 10; i++) { - if (gen.generate(editSession, clicked.add(0, 1, 0))) { - successful = true; - break; - } - } - - if (!successful) { - player.printError("A tree can't go there."); - } - } catch (MaxChangedBlocksException e) { - player.printError("Max. blocks changed reached."); - } finally { - session.remember(editSession); - } - - return true; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.util.TreeGenerator; + +/** + * Plants a tree. + * + * @author sk89q + */ +public class TreePlanter implements BlockTool { + private TreeGenerator gen; + + public TreePlanter(TreeGenerator gen) { + this.gen = gen; + } + + public boolean canUse(LocalPlayer player) { + return player.hasPermission("worldedit.tool.tree"); + } + + public boolean actPrimary(ServerInterface server, LocalConfiguration config, + LocalPlayer player, LocalSession session, WorldVector clicked) { + + EditSession editSession = session.createEditSession(player); + + try { + boolean successful = false; + + for (int i = 0; i < 10; i++) { + if (gen.generate(editSession, clicked.add(0, 1, 0))) { + successful = true; + break; + } + } + + if (!successful) { + player.printError("A tree can't go there."); + } + } catch (MaxChangedBlocksException e) { + player.printError("Max. blocks changed reached."); + } finally { + session.remember(editSession); + } + + return true; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/Brush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/Brush.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/tools/brushes/Brush.java rename to src/main/java/com/sk89q/worldedit/command/tool/brush/Brush.java index 187183133..ae8ff33f1 100644 --- a/src/main/java/com/sk89q/worldedit/tools/brushes/Brush.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/Brush.java @@ -1,44 +1,44 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools.brushes; - -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.patterns.Pattern; - -/** - * Represents a brush. - * - * @author sk89q - */ -public interface Brush { - /** - * Build the object. - * - * @param editSession - * @param pos - * @param mat - * @param size - * @throws MaxChangedBlocksException - */ - public void build(EditSession editSession, Vector pos, Pattern mat, double size) - throws MaxChangedBlocksException; -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool.brush; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.patterns.Pattern; + +/** + * Represents a brush. + * + * @author sk89q + */ +public interface Brush { + /** + * Build the object. + * + * @param editSession + * @param pos + * @param mat + * @param size + * @throws MaxChangedBlocksException + */ + public void build(EditSession editSession, Vector pos, Pattern mat, double size) + throws MaxChangedBlocksException; +} diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/ButcherBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/ButcherBrush.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/tools/brushes/ButcherBrush.java rename to src/main/java/com/sk89q/worldedit/command/tool/brush/ButcherBrush.java index 7e4c97c3f..bbdeeb0a9 100644 --- a/src/main/java/com/sk89q/worldedit/tools/brushes/ButcherBrush.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/ButcherBrush.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.tools.brushes; +package com.sk89q.worldedit.command.tool.brush; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/ClipboardBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/ClipboardBrush.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/brushes/ClipboardBrush.java rename to src/main/java/com/sk89q/worldedit/command/tool/brush/ClipboardBrush.java index 83b436767..7037d12b3 100644 --- a/src/main/java/com/sk89q/worldedit/tools/brushes/ClipboardBrush.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/ClipboardBrush.java @@ -1,41 +1,41 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools.brushes; - -import com.sk89q.worldedit.CuboidClipboard; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.patterns.Pattern; - -public class ClipboardBrush implements Brush { - private CuboidClipboard clipboard; - private boolean noAir; - - public ClipboardBrush(CuboidClipboard clipboard, boolean noAir) { - this.clipboard = clipboard; - this.noAir = noAir; - } - - public void build(EditSession editSession, Vector pos, Pattern mat, double size) - throws MaxChangedBlocksException { - clipboard.place(editSession, pos.subtract(clipboard.getSize().divide(2)), noAir); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool.brush; + +import com.sk89q.worldedit.CuboidClipboard; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.patterns.Pattern; + +public class ClipboardBrush implements Brush { + private CuboidClipboard clipboard; + private boolean noAir; + + public ClipboardBrush(CuboidClipboard clipboard, boolean noAir) { + this.clipboard = clipboard; + this.noAir = noAir; + } + + public void build(EditSession editSession, Vector pos, Pattern mat, double size) + throws MaxChangedBlocksException { + clipboard.place(editSession, pos.subtract(clipboard.getSize().divide(2)), noAir); + } +} diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/CylinderBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/CylinderBrush.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/brushes/CylinderBrush.java rename to src/main/java/com/sk89q/worldedit/command/tool/brush/CylinderBrush.java index 400583261..c5ca176c5 100644 --- a/src/main/java/com/sk89q/worldedit/tools/brushes/CylinderBrush.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/CylinderBrush.java @@ -1,38 +1,38 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools.brushes; - -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.patterns.Pattern; - -public class CylinderBrush implements Brush { - private int height; - - public CylinderBrush(int height) { - this.height = height; - } - - public void build(EditSession editSession, Vector pos, Pattern mat, double size) - throws MaxChangedBlocksException { - editSession.makeCylinder(pos, mat, size, size, height, true); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool.brush; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.patterns.Pattern; + +public class CylinderBrush implements Brush { + private int height; + + public CylinderBrush(int height) { + this.height = height; + } + + public void build(EditSession editSession, Vector pos, Pattern mat, double size) + throws MaxChangedBlocksException { + editSession.makeCylinder(pos, mat, size, size, height, true); + } +} diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/GravityBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java similarity index 98% rename from src/main/java/com/sk89q/worldedit/tools/brushes/GravityBrush.java rename to src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java index 4786838e3..caeaed2e6 100644 --- a/src/main/java/com/sk89q/worldedit/tools/brushes/GravityBrush.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.tools.brushes; +package com.sk89q.worldedit.command.tool.brush; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/HollowCylinderBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowCylinderBrush.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/brushes/HollowCylinderBrush.java rename to src/main/java/com/sk89q/worldedit/command/tool/brush/HollowCylinderBrush.java index 7127e797d..30e4cc602 100644 --- a/src/main/java/com/sk89q/worldedit/tools/brushes/HollowCylinderBrush.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowCylinderBrush.java @@ -1,38 +1,38 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools.brushes; - -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.patterns.Pattern; - -public class HollowCylinderBrush implements Brush { - private int height; - - public HollowCylinderBrush(int height) { - this.height = height; - } - - public void build(EditSession editSession, Vector pos, Pattern mat, double size) - throws MaxChangedBlocksException { - editSession.makeCylinder(pos, mat, size, size, height, false); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool.brush; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.patterns.Pattern; + +public class HollowCylinderBrush implements Brush { + private int height; + + public HollowCylinderBrush(int height) { + this.height = height; + } + + public void build(EditSession editSession, Vector pos, Pattern mat, double size) + throws MaxChangedBlocksException { + editSession.makeCylinder(pos, mat, size, size, height, false); + } +} diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/HollowSphereBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowSphereBrush.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/tools/brushes/HollowSphereBrush.java rename to src/main/java/com/sk89q/worldedit/command/tool/brush/HollowSphereBrush.java index c7328f012..c9ca5f04d 100644 --- a/src/main/java/com/sk89q/worldedit/tools/brushes/HollowSphereBrush.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowSphereBrush.java @@ -1,35 +1,35 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools.brushes; - -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.patterns.Pattern; - -public class HollowSphereBrush implements Brush { - public HollowSphereBrush() { - } - - public void build(EditSession editSession, Vector pos, Pattern mat, double size) - throws MaxChangedBlocksException { - editSession.makeSphere(pos, mat, size, size, size, false); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool.brush; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.patterns.Pattern; + +public class HollowSphereBrush implements Brush { + public HollowSphereBrush() { + } + + public void build(EditSession editSession, Vector pos, Pattern mat, double size) + throws MaxChangedBlocksException { + editSession.makeSphere(pos, mat, size, size, size, false); + } +} diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java rename to src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java index 27a41c0c1..973621a97 100644 --- a/src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java @@ -1,56 +1,56 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools.brushes; - -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.math.convolution.HeightMap; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.WorldVector; -import com.sk89q.worldedit.math.convolution.GaussianKernel; -import com.sk89q.worldedit.math.convolution.HeightMapFilter; -import com.sk89q.worldedit.patterns.Pattern; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.regions.Region; - -public class SmoothBrush implements Brush { - private int iterations; - private boolean naturalOnly; - - public SmoothBrush(int iterations) { - this(iterations, false); - } - - public SmoothBrush(int iterations, boolean naturalOnly) { - this.iterations = iterations; - this.naturalOnly = naturalOnly; - } - - public void build(EditSession editSession, Vector pos, Pattern mat, double size) - throws MaxChangedBlocksException { - double rad = size; - WorldVector min = new WorldVector(editSession.getWorld(), pos.subtract(rad, rad, rad)); - Vector max = pos.add(rad, rad + 10, rad); - Region region = new CuboidRegion(editSession.getWorld(), min, max); - HeightMap heightMap = new HeightMap(editSession, region, naturalOnly); - HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0)); - heightMap.applyFilter(filter, iterations); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool.brush; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.math.convolution.HeightMap; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.math.convolution.GaussianKernel; +import com.sk89q.worldedit.math.convolution.HeightMapFilter; +import com.sk89q.worldedit.patterns.Pattern; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; + +public class SmoothBrush implements Brush { + private int iterations; + private boolean naturalOnly; + + public SmoothBrush(int iterations) { + this(iterations, false); + } + + public SmoothBrush(int iterations, boolean naturalOnly) { + this.iterations = iterations; + this.naturalOnly = naturalOnly; + } + + public void build(EditSession editSession, Vector pos, Pattern mat, double size) + throws MaxChangedBlocksException { + double rad = size; + WorldVector min = new WorldVector(editSession.getWorld(), pos.subtract(rad, rad, rad)); + Vector max = pos.add(rad, rad + 10, rad); + Region region = new CuboidRegion(editSession.getWorld(), min, max); + HeightMap heightMap = new HeightMap(editSession, region, naturalOnly); + HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0)); + heightMap.applyFilter(filter, iterations); + } +} diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/SphereBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/SphereBrush.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/tools/brushes/SphereBrush.java rename to src/main/java/com/sk89q/worldedit/command/tool/brush/SphereBrush.java index e3f29f26c..aa09018d1 100644 --- a/src/main/java/com/sk89q/worldedit/tools/brushes/SphereBrush.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/SphereBrush.java @@ -1,35 +1,35 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.tools.brushes; - -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.patterns.Pattern; - -public class SphereBrush implements Brush { - public SphereBrush() { - } - - public void build(EditSession editSession, Vector pos, Pattern mat, double size) - throws MaxChangedBlocksException { - editSession.makeSphere(pos, mat, size, size, size, true); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.command.tool.brush; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.patterns.Pattern; + +public class SphereBrush implements Brush { + public SphereBrush() { + } + + public void build(EditSession editSession, Vector pos, Pattern mat, double size) + throws MaxChangedBlocksException { + editSession.makeSphere(pos, mat, size, size, size, true); + } +} diff --git a/src/main/java/com/sk89q/worldedit/extent/ForgetfulExtentBuffer.java b/src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java similarity index 97% rename from src/main/java/com/sk89q/worldedit/extent/ForgetfulExtentBuffer.java rename to src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java index ce8df1606..102e7a33a 100644 --- a/src/main/java/com/sk89q/worldedit/extent/ForgetfulExtentBuffer.java +++ b/src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java @@ -17,13 +17,15 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extent; +package com.sk89q.worldedit.extent.buffer; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.ExtentDelegate; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Masks; import com.sk89q.worldedit.function.pattern.Pattern; diff --git a/src/main/java/com/sk89q/worldedit/extent/LastAccessExtentCache.java b/src/main/java/com/sk89q/worldedit/extent/cache/LastAccessExtentCache.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/extent/LastAccessExtentCache.java rename to src/main/java/com/sk89q/worldedit/extent/cache/LastAccessExtentCache.java index d7277cb0d..218362710 100644 --- a/src/main/java/com/sk89q/worldedit/extent/LastAccessExtentCache.java +++ b/src/main/java/com/sk89q/worldedit/extent/cache/LastAccessExtentCache.java @@ -17,11 +17,13 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extent; +package com.sk89q.worldedit.extent.cache; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.ExtentDelegate; /** * Returns the same cached {@link BaseBlock} for repeated calls to diff --git a/src/main/java/com/sk89q/worldedit/bags/BlockBag.java b/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBag.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/bags/BlockBag.java rename to src/main/java/com/sk89q/worldedit/extent/inventory/BlockBag.java index 265d608b9..1a7a9b93f 100644 --- a/src/main/java/com/sk89q/worldedit/bags/BlockBag.java +++ b/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBag.java @@ -1,199 +1,199 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.bags; - -import com.sk89q.worldedit.WorldVector; -import com.sk89q.worldedit.blocks.*; - -/** - * Represents a source to get blocks from and store removed ones. - * - * @author sk89q - */ -public abstract class BlockBag { - /** - * Stores a block as if it was mined. - * - * @param id - * @throws BlockBagException - * @deprecated Use {@link BlockBag#storeDroppedBlock(int, int)} instead - */ - @Deprecated - public void storeDroppedBlock(int id) throws BlockBagException { - storeDroppedBlock(id, 0); - } - - /** - * Stores a block as if it was mined. - * - * @param id - * @param data - * @throws BlockBagException - */ - public void storeDroppedBlock(int id, int data) throws BlockBagException { - BaseItem dropped = BlockType.getBlockBagItem(id, data); - if (dropped == null) return; - if (dropped.getType() == BlockID.AIR) return; - - storeItem(dropped); - } - - /** - * Sets a block as if it was placed by hand. - * - * @param id - * @throws BlockBagException - * @deprecated Use {@link #fetchPlacedBlock(int,int)} instead - */ - @Deprecated - public void fetchPlacedBlock(int id) throws BlockBagException { - fetchPlacedBlock(id, 0); - } - - /** - * Sets a block as if it was placed by hand. - * - * @param id - * @param data TODO - * @throws BlockBagException - */ - public void fetchPlacedBlock(int id, int data) throws BlockBagException { - try { - // Blocks that can't be fetched... - switch (id) { - case BlockID.BEDROCK: - case BlockID.GOLD_ORE: - case BlockID.IRON_ORE: - case BlockID.COAL_ORE: - case BlockID.DIAMOND_ORE: - case BlockID.TNT: - case BlockID.MOB_SPAWNER: - case BlockID.CROPS: - case BlockID.REDSTONE_ORE: - case BlockID.GLOWING_REDSTONE_ORE: - case BlockID.SNOW: - case BlockID.LIGHTSTONE: - case BlockID.PORTAL: - throw new UnplaceableBlockException(); - - case BlockID.WATER: - case BlockID.STATIONARY_WATER: - case BlockID.LAVA: - case BlockID.STATIONARY_LAVA: - // Override liquids - return; - - default: - fetchBlock(id); - break; - } - - } catch (OutOfBlocksException e) { - BaseItem placed = BlockType.getBlockBagItem(id, data); - if (placed == null) throw e; // TODO: check - if (placed.getType() == BlockID.AIR) throw e; // TODO: check - - fetchItem(placed); - } - } - - /** - * Get a block. - * - * Either this method or fetchItem needs to be overridden - * - * @param id - * @throws BlockBagException - */ - public void fetchBlock(int id) throws BlockBagException { - fetchItem(new BaseItem(id)); - } - - /** - * Get a block. - * - * Either this method or fetchBlock needs to be overridden - * - * @param item - * @throws BlockBagException - */ - public void fetchItem(BaseItem item) throws BlockBagException { - fetchBlock(item.getType()); - } - - /** - * Store a block. - * - * Either this method or storeItem needs to be overridden - * - * @param id - * @throws BlockBagException - */ - public void storeBlock(int id) throws BlockBagException { - storeItem(new BaseItem(id)); - } - - /** - * Store a block. - * - * Either this method or storeBlock needs to be overridden - * - * @param item - * @throws BlockBagException - */ - public void storeItem(BaseItem item) throws BlockBagException { - storeBlock(item.getType()); - } - - /** - * Checks to see if a block exists without removing it. - * - * @param id - * @return whether the block exists - */ - public boolean peekBlock(int id) { - try { - fetchBlock(id); - storeBlock(id); - return true; - } catch (BlockBagException e) { - return false; - } - } - - /** - * Flush any changes. This is called at the end. - */ - public abstract void flushChanges(); - - /** - * Adds a position to be used a source. - * - * @param pos - */ - public abstract void addSourcePosition(WorldVector pos); - - /** - * Adds a position to be used a source. - * - * @param pos - */ - public abstract void addSingleSourcePosition(WorldVector pos); -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.extent.inventory; + +import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.blocks.*; + +/** + * Represents a source to get blocks from and store removed ones. + * + * @author sk89q + */ +public abstract class BlockBag { + /** + * Stores a block as if it was mined. + * + * @param id + * @throws BlockBagException + * @deprecated Use {@link BlockBag#storeDroppedBlock(int, int)} instead + */ + @Deprecated + public void storeDroppedBlock(int id) throws BlockBagException { + storeDroppedBlock(id, 0); + } + + /** + * Stores a block as if it was mined. + * + * @param id + * @param data + * @throws BlockBagException + */ + public void storeDroppedBlock(int id, int data) throws BlockBagException { + BaseItem dropped = BlockType.getBlockBagItem(id, data); + if (dropped == null) return; + if (dropped.getType() == BlockID.AIR) return; + + storeItem(dropped); + } + + /** + * Sets a block as if it was placed by hand. + * + * @param id + * @throws BlockBagException + * @deprecated Use {@link #fetchPlacedBlock(int,int)} instead + */ + @Deprecated + public void fetchPlacedBlock(int id) throws BlockBagException { + fetchPlacedBlock(id, 0); + } + + /** + * Sets a block as if it was placed by hand. + * + * @param id + * @param data TODO + * @throws BlockBagException + */ + public void fetchPlacedBlock(int id, int data) throws BlockBagException { + try { + // Blocks that can't be fetched... + switch (id) { + case BlockID.BEDROCK: + case BlockID.GOLD_ORE: + case BlockID.IRON_ORE: + case BlockID.COAL_ORE: + case BlockID.DIAMOND_ORE: + case BlockID.TNT: + case BlockID.MOB_SPAWNER: + case BlockID.CROPS: + case BlockID.REDSTONE_ORE: + case BlockID.GLOWING_REDSTONE_ORE: + case BlockID.SNOW: + case BlockID.LIGHTSTONE: + case BlockID.PORTAL: + throw new UnplaceableBlockException(); + + case BlockID.WATER: + case BlockID.STATIONARY_WATER: + case BlockID.LAVA: + case BlockID.STATIONARY_LAVA: + // Override liquids + return; + + default: + fetchBlock(id); + break; + } + + } catch (OutOfBlocksException e) { + BaseItem placed = BlockType.getBlockBagItem(id, data); + if (placed == null) throw e; // TODO: check + if (placed.getType() == BlockID.AIR) throw e; // TODO: check + + fetchItem(placed); + } + } + + /** + * Get a block. + * + * Either this method or fetchItem needs to be overridden + * + * @param id + * @throws BlockBagException + */ + public void fetchBlock(int id) throws BlockBagException { + fetchItem(new BaseItem(id)); + } + + /** + * Get a block. + * + * Either this method or fetchBlock needs to be overridden + * + * @param item + * @throws BlockBagException + */ + public void fetchItem(BaseItem item) throws BlockBagException { + fetchBlock(item.getType()); + } + + /** + * Store a block. + * + * Either this method or storeItem needs to be overridden + * + * @param id + * @throws BlockBagException + */ + public void storeBlock(int id) throws BlockBagException { + storeItem(new BaseItem(id)); + } + + /** + * Store a block. + * + * Either this method or storeBlock needs to be overridden + * + * @param item + * @throws BlockBagException + */ + public void storeItem(BaseItem item) throws BlockBagException { + storeBlock(item.getType()); + } + + /** + * Checks to see if a block exists without removing it. + * + * @param id + * @return whether the block exists + */ + public boolean peekBlock(int id) { + try { + fetchBlock(id); + storeBlock(id); + return true; + } catch (BlockBagException e) { + return false; + } + } + + /** + * Flush any changes. This is called at the end. + */ + public abstract void flushChanges(); + + /** + * Adds a position to be used a source. + * + * @param pos + */ + public abstract void addSourcePosition(WorldVector pos); + + /** + * Adds a position to be used a source. + * + * @param pos + */ + public abstract void addSingleSourcePosition(WorldVector pos); +} diff --git a/src/main/java/com/sk89q/worldedit/bags/BlockBagException.java b/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagException.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/bags/BlockBagException.java rename to src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagException.java index 0104737c8..c17595098 100644 --- a/src/main/java/com/sk89q/worldedit/bags/BlockBagException.java +++ b/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagException.java @@ -1,28 +1,28 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.bags; - -/** - * - * @author sk89q - */ -public class BlockBagException extends Exception { - private static final long serialVersionUID = 4672190086028430655L; -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.extent.inventory; + +/** + * + * @author sk89q + */ +public class BlockBagException extends Exception { + private static final long serialVersionUID = 4672190086028430655L; +} diff --git a/src/main/java/com/sk89q/worldedit/extent/BlockBagExtent.java b/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/extent/BlockBagExtent.java rename to src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java index 0255a9faf..c67997531 100644 --- a/src/main/java/com/sk89q/worldedit/extent/BlockBagExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java @@ -17,14 +17,16 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extent; +package com.sk89q.worldedit.extent.inventory; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.bags.BlockBag; -import com.sk89q.worldedit.bags.BlockBagException; -import com.sk89q.worldedit.bags.UnplaceableBlockException; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.ExtentDelegate; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.extent.inventory.BlockBagException; +import com.sk89q.worldedit.extent.inventory.UnplaceableBlockException; import com.sk89q.worldedit.blocks.BaseBlock; import javax.annotation.Nullable; diff --git a/src/main/java/com/sk89q/worldedit/bags/OutOfBlocksException.java b/src/main/java/com/sk89q/worldedit/extent/inventory/OutOfBlocksException.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/bags/OutOfBlocksException.java rename to src/main/java/com/sk89q/worldedit/extent/inventory/OutOfBlocksException.java index 4733d4920..8714cc067 100644 --- a/src/main/java/com/sk89q/worldedit/bags/OutOfBlocksException.java +++ b/src/main/java/com/sk89q/worldedit/extent/inventory/OutOfBlocksException.java @@ -1,28 +1,28 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.bags; - -/** - * - * @author sk89q - */ -public class OutOfBlocksException extends BlockBagException { - private static final long serialVersionUID = 7495899825677689509L; -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.extent.inventory; + +/** + * + * @author sk89q + */ +public class OutOfBlocksException extends BlockBagException { + private static final long serialVersionUID = 7495899825677689509L; +} diff --git a/src/main/java/com/sk89q/worldedit/bags/OutOfSpaceException.java b/src/main/java/com/sk89q/worldedit/extent/inventory/OutOfSpaceException.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/bags/OutOfSpaceException.java rename to src/main/java/com/sk89q/worldedit/extent/inventory/OutOfSpaceException.java index 7dd5435fe..066aed6ac 100644 --- a/src/main/java/com/sk89q/worldedit/bags/OutOfSpaceException.java +++ b/src/main/java/com/sk89q/worldedit/extent/inventory/OutOfSpaceException.java @@ -1,48 +1,48 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.bags; - -/** - * - * @author sk89q - */ -public class OutOfSpaceException extends BlockBagException { - private static final long serialVersionUID = -2962840237632916821L; - - /** - * Stores the block ID. - */ - private int id; - - /** - * Construct the object. - * @param id - */ - public OutOfSpaceException(int id) { - this.id = id; - } - - /** - * @return the id - */ - public int getID() { - return id; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.extent.inventory; + +/** + * + * @author sk89q + */ +public class OutOfSpaceException extends BlockBagException { + private static final long serialVersionUID = -2962840237632916821L; + + /** + * Stores the block ID. + */ + private int id; + + /** + * Construct the object. + * @param id + */ + public OutOfSpaceException(int id) { + this.id = id; + } + + /** + * @return the id + */ + public int getID() { + return id; + } +} diff --git a/src/main/java/com/sk89q/worldedit/bags/UnplaceableBlockException.java b/src/main/java/com/sk89q/worldedit/extent/inventory/UnplaceableBlockException.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/bags/UnplaceableBlockException.java rename to src/main/java/com/sk89q/worldedit/extent/inventory/UnplaceableBlockException.java index 28c4014b7..459b501a1 100644 --- a/src/main/java/com/sk89q/worldedit/bags/UnplaceableBlockException.java +++ b/src/main/java/com/sk89q/worldedit/extent/inventory/UnplaceableBlockException.java @@ -1,29 +1,29 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.bags; - -/** - * - * @author sk89q - */ -public class UnplaceableBlockException extends BlockBagException { - private static final long serialVersionUID = 7227883966999843526L; - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.extent.inventory; + +/** + * + * @author sk89q + */ +public class UnplaceableBlockException extends BlockBagException { + private static final long serialVersionUID = 7227883966999843526L; + +} diff --git a/src/main/java/com/sk89q/worldedit/extent/AbstractLoggingExtent.java b/src/main/java/com/sk89q/worldedit/extent/logging/AbstractLoggingExtent.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/extent/AbstractLoggingExtent.java rename to src/main/java/com/sk89q/worldedit/extent/logging/AbstractLoggingExtent.java index 4baa97e3e..dea92b817 100644 --- a/src/main/java/com/sk89q/worldedit/extent/AbstractLoggingExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/logging/AbstractLoggingExtent.java @@ -17,11 +17,13 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extent; +package com.sk89q.worldedit.extent.logging; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.ExtentDelegate; /** * An abstract class to implement block loggers and so on with. diff --git a/src/main/java/com/sk89q/worldedit/extent/BlockChangeLimiter.java b/src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/extent/BlockChangeLimiter.java rename to src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java index 9c7ecf331..5f1fd1457 100644 --- a/src/main/java/com/sk89q/worldedit/extent/BlockChangeLimiter.java +++ b/src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java @@ -17,12 +17,14 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extent; +package com.sk89q.worldedit.extent.validation; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.ExtentDelegate; import static com.google.common.base.Preconditions.checkArgument; diff --git a/src/main/java/com/sk89q/worldedit/extent/DataValidatorExtent.java b/src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/extent/DataValidatorExtent.java rename to src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java index 1402ed712..1066517dd 100644 --- a/src/main/java/com/sk89q/worldedit/extent/DataValidatorExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java @@ -17,12 +17,14 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extent; +package com.sk89q.worldedit.extent.validation; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.ExtentDelegate; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/src/main/java/com/sk89q/worldedit/extent/BlockQuirkExtent.java b/src/main/java/com/sk89q/worldedit/extent/world/BlockQuirkExtent.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/extent/BlockQuirkExtent.java rename to src/main/java/com/sk89q/worldedit/extent/world/BlockQuirkExtent.java index 9d52a8778..ff1221bcf 100644 --- a/src/main/java/com/sk89q/worldedit/extent/BlockQuirkExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/world/BlockQuirkExtent.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extent; +package com.sk89q.worldedit.extent.world; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; @@ -25,6 +25,8 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockType; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.ExtentDelegate; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/src/main/java/com/sk89q/worldedit/extent/ChunkLoadingExtent.java b/src/main/java/com/sk89q/worldedit/extent/world/ChunkLoadingExtent.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/extent/ChunkLoadingExtent.java rename to src/main/java/com/sk89q/worldedit/extent/world/ChunkLoadingExtent.java index 36e0c0eb1..ab31ff5f1 100644 --- a/src/main/java/com/sk89q/worldedit/extent/ChunkLoadingExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/world/ChunkLoadingExtent.java @@ -17,12 +17,14 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extent; +package com.sk89q.worldedit.extent.world; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.ExtentDelegate; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/src/main/java/com/sk89q/worldedit/extent/FastModeExtent.java b/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java similarity index 97% rename from src/main/java/com/sk89q/worldedit/extent/FastModeExtent.java rename to src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java index 6914f5993..33f3a5596 100644 --- a/src/main/java/com/sk89q/worldedit/extent/FastModeExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java @@ -17,13 +17,14 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extent; +package com.sk89q.worldedit.extent.world; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.extent.ExtentDelegate; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.RunContext; diff --git a/src/main/java/com/sk89q/worldedit/foundation/Block.java b/src/main/java/com/sk89q/worldedit/foundation/Block.java index c3ffcabe9..35f922bd0 100644 --- a/src/main/java/com/sk89q/worldedit/foundation/Block.java +++ b/src/main/java/com/sk89q/worldedit/foundation/Block.java @@ -23,7 +23,7 @@ import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.TileEntityBlock; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * Represents a mutable copy of a block that is not tied to any 'real' block in a world. diff --git a/src/main/java/com/sk89q/worldedit/foundation/NbtValued.java b/src/main/java/com/sk89q/worldedit/foundation/NbtValued.java index 89dcd2069..b92d966d1 100644 --- a/src/main/java/com/sk89q/worldedit/foundation/NbtValued.java +++ b/src/main/java/com/sk89q/worldedit/foundation/NbtValued.java @@ -19,7 +19,7 @@ package com.sk89q.worldedit.foundation; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * Indicates an object that contains extra data identified as an NBT structure. This diff --git a/src/main/java/com/sk89q/worldedit/cui/CUIEvent.java b/src/main/java/com/sk89q/worldedit/internal/cui/CUIEvent.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/cui/CUIEvent.java rename to src/main/java/com/sk89q/worldedit/internal/cui/CUIEvent.java index f1f85107d..e272fe9f6 100644 --- a/src/main/java/com/sk89q/worldedit/cui/CUIEvent.java +++ b/src/main/java/com/sk89q/worldedit/internal/cui/CUIEvent.java @@ -1,27 +1,27 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.cui; - -public interface CUIEvent { - - public String getTypeId(); - - public String[] getParameters(); -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.cui; + +public interface CUIEvent { + + public String getTypeId(); + + public String[] getParameters(); +} diff --git a/src/main/java/com/sk89q/worldedit/cui/CUIRegion.java b/src/main/java/com/sk89q/worldedit/internal/cui/CUIRegion.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/cui/CUIRegion.java rename to src/main/java/com/sk89q/worldedit/internal/cui/CUIRegion.java index b781304d9..8bdd9e39f 100644 --- a/src/main/java/com/sk89q/worldedit/cui/CUIRegion.java +++ b/src/main/java/com/sk89q/worldedit/internal/cui/CUIRegion.java @@ -1,65 +1,65 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.cui; - -import com.sk89q.worldedit.LocalPlayer; -import com.sk89q.worldedit.LocalSession; - -public interface CUIRegion { - - /** - * Sends CUI events describing the region for - * versions of CUI equal to or greater than the - * value supplied by getProtocolVersion(). - * - */ - public void describeCUI(LocalSession session, LocalPlayer player); - - /** - * Sends CUI events describing the region for - * versions of CUI smaller than the value - * supplied by getProtocolVersion(). - * - */ - public void describeLegacyCUI(LocalSession session, LocalPlayer player); - - /** - * Returns the CUI version that is required to send - * up-to-date data. If the CUI version is smaller than - * this value, the legacy methods will be called. - * - * @return - */ - public int getProtocolVersion(); - - /** - * Returns the type ID to send to CUI in the selection event. - * @return - */ - public String getTypeID(); - - /** - * Returns the type ID to send to CUI in the selection - * event if the CUI is in legacy mode. - * - * @return - */ - public String getLegacyTypeID(); -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.cui; + +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; + +public interface CUIRegion { + + /** + * Sends CUI events describing the region for + * versions of CUI equal to or greater than the + * value supplied by getProtocolVersion(). + * + */ + public void describeCUI(LocalSession session, LocalPlayer player); + + /** + * Sends CUI events describing the region for + * versions of CUI smaller than the value + * supplied by getProtocolVersion(). + * + */ + public void describeLegacyCUI(LocalSession session, LocalPlayer player); + + /** + * Returns the CUI version that is required to send + * up-to-date data. If the CUI version is smaller than + * this value, the legacy methods will be called. + * + * @return + */ + public int getProtocolVersion(); + + /** + * Returns the type ID to send to CUI in the selection event. + * @return + */ + public String getTypeID(); + + /** + * Returns the type ID to send to CUI in the selection + * event if the CUI is in legacy mode. + * + * @return + */ + public String getLegacyTypeID(); +} diff --git a/src/main/java/com/sk89q/worldedit/cui/SelectionCylinderEvent.java b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionCylinderEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/cui/SelectionCylinderEvent.java rename to src/main/java/com/sk89q/worldedit/internal/cui/SelectionCylinderEvent.java index a3fd03475..904d8a794 100644 --- a/src/main/java/com/sk89q/worldedit/cui/SelectionCylinderEvent.java +++ b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionCylinderEvent.java @@ -1,47 +1,47 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.sk89q.worldedit.cui; - -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.Vector2D; - -public class SelectionCylinderEvent implements CUIEvent { - - protected final Vector pos; - protected final Vector2D radius; - - public SelectionCylinderEvent(Vector pos, Vector2D radius) { - this.pos = pos; - this.radius = radius; - } - - public String getTypeId() { - return "cyl"; - } - - public String[] getParameters() { - return new String[] { - String.valueOf(pos.getBlockX()), - String.valueOf(pos.getBlockY()), - String.valueOf(pos.getBlockZ()), - String.valueOf(radius.getX()), - String.valueOf(radius.getZ()) - }; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.sk89q.worldedit.internal.cui; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; + +public class SelectionCylinderEvent implements CUIEvent { + + protected final Vector pos; + protected final Vector2D radius; + + public SelectionCylinderEvent(Vector pos, Vector2D radius) { + this.pos = pos; + this.radius = radius; + } + + public String getTypeId() { + return "cyl"; + } + + public String[] getParameters() { + return new String[] { + String.valueOf(pos.getBlockX()), + String.valueOf(pos.getBlockY()), + String.valueOf(pos.getBlockZ()), + String.valueOf(radius.getX()), + String.valueOf(radius.getZ()) + }; + } +} diff --git a/src/main/java/com/sk89q/worldedit/cui/SelectionEllipsoidPointEvent.java b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionEllipsoidPointEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/cui/SelectionEllipsoidPointEvent.java rename to src/main/java/com/sk89q/worldedit/internal/cui/SelectionEllipsoidPointEvent.java index 0b3ad9b7e..b770c97e9 100644 --- a/src/main/java/com/sk89q/worldedit/cui/SelectionEllipsoidPointEvent.java +++ b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionEllipsoidPointEvent.java @@ -1,45 +1,45 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.cui; - -import com.sk89q.worldedit.Vector; - -public class SelectionEllipsoidPointEvent implements CUIEvent { - protected final int id; - protected final Vector pos; - - public SelectionEllipsoidPointEvent(int id, Vector pos) { - this.id = id; - this.pos = pos; - } - - public String getTypeId() { - return "e"; - } - - public String[] getParameters() { - return new String[] { - String.valueOf(id), - String.valueOf(pos.getBlockX()), - String.valueOf(pos.getBlockY()), - String.valueOf(pos.getBlockZ()) - }; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.cui; + +import com.sk89q.worldedit.Vector; + +public class SelectionEllipsoidPointEvent implements CUIEvent { + protected final int id; + protected final Vector pos; + + public SelectionEllipsoidPointEvent(int id, Vector pos) { + this.id = id; + this.pos = pos; + } + + public String getTypeId() { + return "e"; + } + + public String[] getParameters() { + return new String[] { + String.valueOf(id), + String.valueOf(pos.getBlockX()), + String.valueOf(pos.getBlockY()), + String.valueOf(pos.getBlockZ()) + }; + } +} diff --git a/src/main/java/com/sk89q/worldedit/cui/SelectionMinMaxEvent.java b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionMinMaxEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/cui/SelectionMinMaxEvent.java rename to src/main/java/com/sk89q/worldedit/internal/cui/SelectionMinMaxEvent.java index faccd8bc2..24ed88692 100644 --- a/src/main/java/com/sk89q/worldedit/cui/SelectionMinMaxEvent.java +++ b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionMinMaxEvent.java @@ -1,43 +1,43 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.cui; - -public class SelectionMinMaxEvent implements CUIEvent { - - protected final int min; - protected final int max; - - public SelectionMinMaxEvent(int min, int max) { - this.min = min; - this.max = max; - } - - public String getTypeId() { - return "mm"; - } - - public String[] getParameters() { - return new String[] { - String.valueOf(min), - String.valueOf(max), - }; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.cui; + +public class SelectionMinMaxEvent implements CUIEvent { + + protected final int min; + protected final int max; + + public SelectionMinMaxEvent(int min, int max) { + this.min = min; + this.max = max; + } + + public String getTypeId() { + return "mm"; + } + + public String[] getParameters() { + return new String[] { + String.valueOf(min), + String.valueOf(max), + }; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/cui/SelectionPoint2DEvent.java b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/cui/SelectionPoint2DEvent.java rename to src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java index be36dbe61..3f0a9a2ba 100644 --- a/src/main/java/com/sk89q/worldedit/cui/SelectionPoint2DEvent.java +++ b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java @@ -1,59 +1,59 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.cui; - -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.Vector2D; - -public class SelectionPoint2DEvent implements CUIEvent { - - protected final int id; - protected final int blockx; - protected final int blockz; - protected final int area; - - public SelectionPoint2DEvent(int id, Vector2D pos, int area) { - this.id = id; - this.blockx = pos.getBlockX(); - this.blockz = pos.getBlockZ(); - this.area = area; - } - - public SelectionPoint2DEvent(int id, Vector pos, int area) { - this.id = id; - this.blockx = pos.getBlockX(); - this.blockz = pos.getBlockZ(); - this.area = area; - } - - public String getTypeId() { - return "p2"; - } - - public String[] getParameters() { - return new String[] { - String.valueOf(id), - String.valueOf(blockx), - String.valueOf(blockz), - String.valueOf(area) - }; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.cui; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; + +public class SelectionPoint2DEvent implements CUIEvent { + + protected final int id; + protected final int blockx; + protected final int blockz; + protected final int area; + + public SelectionPoint2DEvent(int id, Vector2D pos, int area) { + this.id = id; + this.blockx = pos.getBlockX(); + this.blockz = pos.getBlockZ(); + this.area = area; + } + + public SelectionPoint2DEvent(int id, Vector pos, int area) { + this.id = id; + this.blockx = pos.getBlockX(); + this.blockz = pos.getBlockZ(); + this.area = area; + } + + public String getTypeId() { + return "p2"; + } + + public String[] getParameters() { + return new String[] { + String.valueOf(id), + String.valueOf(blockx), + String.valueOf(blockz), + String.valueOf(area) + }; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/cui/SelectionPointEvent.java b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/cui/SelectionPointEvent.java rename to src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java index b19833174..e4fb436f1 100644 --- a/src/main/java/com/sk89q/worldedit/cui/SelectionPointEvent.java +++ b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java @@ -1,50 +1,50 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.cui; - -import com.sk89q.worldedit.Vector; - -public class SelectionPointEvent implements CUIEvent { - - protected final int id; - protected final Vector pos; - protected final int area; - - public SelectionPointEvent(int id, Vector pos, int area) { - this.id = id; - this.pos = pos; - this.area = area; - } - - public String getTypeId() { - return "p"; - } - - public String[] getParameters() { - return new String[] { - String.valueOf(id), - String.valueOf(pos.getBlockX()), - String.valueOf(pos.getBlockY()), - String.valueOf(pos.getBlockZ()), - String.valueOf(area) - }; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.cui; + +import com.sk89q.worldedit.Vector; + +public class SelectionPointEvent implements CUIEvent { + + protected final int id; + protected final Vector pos; + protected final int area; + + public SelectionPointEvent(int id, Vector pos, int area) { + this.id = id; + this.pos = pos; + this.area = area; + } + + public String getTypeId() { + return "p"; + } + + public String[] getParameters() { + return new String[] { + String.valueOf(id), + String.valueOf(pos.getBlockX()), + String.valueOf(pos.getBlockY()), + String.valueOf(pos.getBlockZ()), + String.valueOf(area) + }; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/cui/SelectionPolygonEvent.java b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPolygonEvent.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/cui/SelectionPolygonEvent.java rename to src/main/java/com/sk89q/worldedit/internal/cui/SelectionPolygonEvent.java index cea73b392..3655be75d 100644 --- a/src/main/java/com/sk89q/worldedit/cui/SelectionPolygonEvent.java +++ b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPolygonEvent.java @@ -1,42 +1,42 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.sk89q.worldedit.cui; - -public class SelectionPolygonEvent implements CUIEvent { - protected final int[] vertices; - - public SelectionPolygonEvent(int... vertices) { - this.vertices = vertices; - } - - public String getTypeId() { - return "poly"; - } - - public String[] getParameters() { - final String[] ret = new String[vertices.length]; - - int i = 0; - for (int vertex : vertices) { - ret[i++] = String.valueOf(vertex); - } - - return ret; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.sk89q.worldedit.internal.cui; + +public class SelectionPolygonEvent implements CUIEvent { + protected final int[] vertices; + + public SelectionPolygonEvent(int... vertices) { + this.vertices = vertices; + } + + public String getTypeId() { + return "poly"; + } + + public String[] getParameters() { + final String[] ret = new String[vertices.length]; + + int i = 0; + for (int vertex : vertices) { + ret[i++] = String.valueOf(vertex); + } + + return ret; + } +} diff --git a/src/main/java/com/sk89q/worldedit/cui/SelectionShapeEvent.java b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionShapeEvent.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/cui/SelectionShapeEvent.java rename to src/main/java/com/sk89q/worldedit/internal/cui/SelectionShapeEvent.java index f37175cda..715bbd273 100644 --- a/src/main/java/com/sk89q/worldedit/cui/SelectionShapeEvent.java +++ b/src/main/java/com/sk89q/worldedit/internal/cui/SelectionShapeEvent.java @@ -1,38 +1,38 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.cui; - -public class SelectionShapeEvent implements CUIEvent { - - protected final String shapeName; - - public SelectionShapeEvent(String shapeName) { - this.shapeName = shapeName; - } - - public String getTypeId() { - return "s"; - } - - public String[] getParameters() { - return new String[] { shapeName }; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.cui; + +public class SelectionShapeEvent implements CUIEvent { + + protected final String shapeName; + + public SelectionShapeEvent(String shapeName) { + this.shapeName = shapeName; + } + + public String getTypeId() { + return "s"; + } + + public String[] getParameters() { + return new String[] { shapeName }; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/expression/Expression.java b/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java similarity index 86% rename from src/main/java/com/sk89q/worldedit/expression/Expression.java rename to src/main/java/com/sk89q/worldedit/internal/expression/Expression.java index f78ab76b3..a26051672 100644 --- a/src/main/java/com/sk89q/worldedit/expression/Expression.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java @@ -1,172 +1,170 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; - -import com.sk89q.worldedit.BlockVector; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.expression.lexer.Lexer; -import com.sk89q.worldedit.expression.lexer.tokens.Token; -import com.sk89q.worldedit.expression.parser.Parser; -import com.sk89q.worldedit.expression.runtime.ExpressionEnvironment; -import com.sk89q.worldedit.expression.runtime.Constant; -import com.sk89q.worldedit.expression.runtime.EvaluationException; -import com.sk89q.worldedit.expression.runtime.Functions; -import com.sk89q.worldedit.expression.runtime.RValue; -import com.sk89q.worldedit.expression.runtime.ReturnException; -import com.sk89q.worldedit.expression.runtime.Variable; - -/** - * Compiles and evaluates expressions. - * - * Supported operators: - * Logical: &&, ||, ! (unary) - * Bitwise: ~ (unary), >>, << - * Arithmetic: +, -, *, /, % (modulo), ^ (power), - (unary), --, ++ (prefix only) - * Comparison: <=, >=, >, <, ==, !=, ~= (near) - * - * Supported functions: abs, acos, asin, atan, atan2, cbrt, ceil, cos, cosh, exp, floor, ln, log, log10, max, max, min, min, rint, round, sin, sinh, sqrt, tan, tanh and more. (See the Functions class or the wiki) - * - * Constants: e, pi - * - * To compile an equation, run Expression.compile("expression here", "var1", "var2"...) - * If you wish to run the equation multiple times, you can then optimize it, by calling myExpression.optimize(); - * You can then run the equation as many times as you want by calling myExpression.evaluate(var1, var2...) - * You do not need to pass values for all variables specified while compiling. - * To query variables after evaluation, you can use myExpression.getVariable("variable name"). - * To get a value out of these, use myVariable.getValue() - * - * Variables are also supported and can be set either by passing values to evaluate - * - * @author TomyLobo - */ -public class Expression { - private static final ThreadLocal> instance = new ThreadLocal>(); - - private final Map variables = new HashMap(); - private final String[] variableNames; - private RValue root; - private final Functions functions = new Functions(); - private ExpressionEnvironment environment; - - public static Expression compile(String expression, String... variableNames) throws ExpressionException { - return new Expression(expression, variableNames); - } - - private Expression(String expression, String... variableNames) throws ExpressionException { - this(Lexer.tokenize(expression), variableNames); - } - - private Expression(List tokens, String... variableNames) throws ExpressionException { - this.variableNames = variableNames; - - variables.put("e", new Constant(-1, Math.E)); - variables.put("pi", new Constant(-1, Math.PI)); - variables.put("true", new Constant(-1, 1)); - variables.put("false", new Constant(-1, 0)); - - for (String variableName : variableNames) { - if (variables.containsKey(variableName)) { - throw new ExpressionException(-1, "Tried to overwrite identifier '" + variableName + "'"); - } - variables.put(variableName, new Variable(0)); - } - - root = Parser.parse(tokens, this); - } - - public double evaluate(double... values) throws EvaluationException { - for (int i = 0; i < values.length; ++i) { - final String variableName = variableNames[i]; - final RValue invokable = variables.get(variableName); - if (!(invokable instanceof Variable)) { - throw new EvaluationException(invokable.getPosition(), "Tried to assign constant " + variableName + "."); - } - - ((Variable) invokable).value = values[i]; - } - - pushInstance(); - try { - return root.getValue(); - } catch (ReturnException e) { - return e.getValue(); - } finally { - popInstance(); - } - } - - public void optimize() throws EvaluationException { - root = root.optimize(); - } - - @Override - public String toString() { - return root.toString(); - } - - public RValue getVariable(String name, boolean create) { - RValue variable = variables.get(name); - if (variable == null && create) { - variables.put(name, variable = new Variable(0)); - } - - return variable; - } - - public static Expression getInstance() { - return instance.get().peek(); - } - - private void pushInstance() { - Stack foo = instance.get(); - if (foo == null) { - instance.set(foo = new Stack()); - } - - foo.push(this); - } - - private void popInstance() { - Stack foo = instance.get(); - - foo.pop(); - - if (foo.isEmpty()) { - instance.set(null); - } - } - - public Functions getFunctions() { - return functions; - } - - public ExpressionEnvironment getEnvironment() { - return environment; - } - - public void setEnvironment(ExpressionEnvironment environment) { - this.environment = environment; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import com.sk89q.worldedit.internal.expression.lexer.Lexer; +import com.sk89q.worldedit.internal.expression.lexer.tokens.Token; +import com.sk89q.worldedit.internal.expression.parser.Parser; +import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment; +import com.sk89q.worldedit.internal.expression.runtime.Constant; +import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; +import com.sk89q.worldedit.internal.expression.runtime.Functions; +import com.sk89q.worldedit.internal.expression.runtime.RValue; +import com.sk89q.worldedit.internal.expression.runtime.ReturnException; +import com.sk89q.worldedit.internal.expression.runtime.Variable; + +/** + * Compiles and evaluates expressions. + * + * Supported operators: + * Logical: &&, ||, ! (unary) + * Bitwise: ~ (unary), >>, << + * Arithmetic: +, -, *, /, % (modulo), ^ (power), - (unary), --, ++ (prefix only) + * Comparison: <=, >=, >, <, ==, !=, ~= (near) + * + * Supported functions: abs, acos, asin, atan, atan2, cbrt, ceil, cos, cosh, exp, floor, ln, log, log10, max, max, min, min, rint, round, sin, sinh, sqrt, tan, tanh and more. (See the Functions class or the wiki) + * + * Constants: e, pi + * + * To compile an equation, run Expression.compile("expression here", "var1", "var2"...) + * If you wish to run the equation multiple times, you can then optimize it, by calling myExpression.optimize(); + * You can then run the equation as many times as you want by calling myExpression.evaluate(var1, var2...) + * You do not need to pass values for all variables specified while compiling. + * To query variables after evaluation, you can use myExpression.getVariable("variable name"). + * To get a value out of these, use myVariable.getValue() + * + * Variables are also supported and can be set either by passing values to evaluate + * + * @author TomyLobo + */ +public class Expression { + private static final ThreadLocal> instance = new ThreadLocal>(); + + private final Map variables = new HashMap(); + private final String[] variableNames; + private RValue root; + private final Functions functions = new Functions(); + private ExpressionEnvironment environment; + + public static Expression compile(String expression, String... variableNames) throws ExpressionException { + return new Expression(expression, variableNames); + } + + private Expression(String expression, String... variableNames) throws ExpressionException { + this(Lexer.tokenize(expression), variableNames); + } + + private Expression(List tokens, String... variableNames) throws ExpressionException { + this.variableNames = variableNames; + + variables.put("e", new Constant(-1, Math.E)); + variables.put("pi", new Constant(-1, Math.PI)); + variables.put("true", new Constant(-1, 1)); + variables.put("false", new Constant(-1, 0)); + + for (String variableName : variableNames) { + if (variables.containsKey(variableName)) { + throw new ExpressionException(-1, "Tried to overwrite identifier '" + variableName + "'"); + } + variables.put(variableName, new Variable(0)); + } + + root = Parser.parse(tokens, this); + } + + public double evaluate(double... values) throws EvaluationException { + for (int i = 0; i < values.length; ++i) { + final String variableName = variableNames[i]; + final RValue invokable = variables.get(variableName); + if (!(invokable instanceof Variable)) { + throw new EvaluationException(invokable.getPosition(), "Tried to assign constant " + variableName + "."); + } + + ((Variable) invokable).value = values[i]; + } + + pushInstance(); + try { + return root.getValue(); + } catch (ReturnException e) { + return e.getValue(); + } finally { + popInstance(); + } + } + + public void optimize() throws EvaluationException { + root = root.optimize(); + } + + @Override + public String toString() { + return root.toString(); + } + + public RValue getVariable(String name, boolean create) { + RValue variable = variables.get(name); + if (variable == null && create) { + variables.put(name, variable = new Variable(0)); + } + + return variable; + } + + public static Expression getInstance() { + return instance.get().peek(); + } + + private void pushInstance() { + Stack foo = instance.get(); + if (foo == null) { + instance.set(foo = new Stack()); + } + + foo.push(this); + } + + private void popInstance() { + Stack foo = instance.get(); + + foo.pop(); + + if (foo.isEmpty()) { + instance.set(null); + } + } + + public Functions getFunctions() { + return functions; + } + + public ExpressionEnvironment getEnvironment() { + return environment; + } + + public void setEnvironment(ExpressionEnvironment environment) { + this.environment = environment; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/ExpressionException.java b/src/main/java/com/sk89q/worldedit/internal/expression/ExpressionException.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/expression/ExpressionException.java rename to src/main/java/com/sk89q/worldedit/internal/expression/ExpressionException.java index 6bd1597ac..4188dfdab 100644 --- a/src/main/java/com/sk89q/worldedit/expression/ExpressionException.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/ExpressionException.java @@ -1,54 +1,54 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression; - -/** - * Thrown when there's a problem during any stage of the expression compilation or evaluation. - * - * @author TomyLobo - */ -public class ExpressionException extends Exception { - private static final long serialVersionUID = 1L; - - private final int position; - - public ExpressionException(int position) { - this.position = position; - } - - public ExpressionException(int position, String message, Throwable cause) { - super(message, cause); - this.position = position; - } - - public ExpressionException(int position, String message) { - super(message); - this.position = position; - } - - public ExpressionException(int position, Throwable cause) { - super(cause); - this.position = position; - } - - public int getPosition() { - return position; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression; + +/** + * Thrown when there's a problem during any stage of the expression compilation or evaluation. + * + * @author TomyLobo + */ +public class ExpressionException extends Exception { + private static final long serialVersionUID = 1L; + + private final int position; + + public ExpressionException(int position) { + this.position = position; + } + + public ExpressionException(int position, String message, Throwable cause) { + super(message, cause); + this.position = position; + } + + public ExpressionException(int position, String message) { + super(message); + this.position = position; + } + + public ExpressionException(int position, Throwable cause) { + super(cause); + this.position = position; + } + + public int getPosition() { + return position; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/Identifiable.java b/src/main/java/com/sk89q/worldedit/internal/expression/Identifiable.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/expression/Identifiable.java rename to src/main/java/com/sk89q/worldedit/internal/expression/Identifiable.java index 5ce398a27..17086c325 100644 --- a/src/main/java/com/sk89q/worldedit/expression/Identifiable.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/Identifiable.java @@ -1,61 +1,61 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression; - -/** - * A common superinterface for everything passed to parser processors. - * - * @author TomyLobo - */ -public interface Identifiable { - /** - * Returns a character that helps identify the token, pseudo-token or invokable in question. - * - *
-     * Tokens:
-     * i - IdentifierToken
-     * 0 - NumberToken
-     * o - OperatorToken
-     * \0 - NullToken
-     * CharacterTokens are returned literally
-     *
-     * PseudoTokens:
-     * p - UnaryOperator
-     * V - UnboundVariable
-     *
-     * Nodes:
-     * c - Constant
-     * v - Variable
-     * f - Function
-     * l - LValueFunction
-     * s - Sequence
-     * I - Conditional
-     * w - While
-     * F - For
-     * r - Return
-     * b - Break (includes continue)
-     * S - SimpleFor
-     * C - Switch
-     * 
- */ - public abstract char id(); - - public int getPosition(); -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression; + +/** + * A common superinterface for everything passed to parser processors. + * + * @author TomyLobo + */ +public interface Identifiable { + /** + * Returns a character that helps identify the token, pseudo-token or invokable in question. + * + *
+     * Tokens:
+     * i - IdentifierToken
+     * 0 - NumberToken
+     * o - OperatorToken
+     * \0 - NullToken
+     * CharacterTokens are returned literally
+     *
+     * PseudoTokens:
+     * p - UnaryOperator
+     * V - UnboundVariable
+     *
+     * Nodes:
+     * c - Constant
+     * v - Variable
+     * f - Function
+     * l - LValueFunction
+     * s - Sequence
+     * I - Conditional
+     * w - While
+     * F - For
+     * r - Return
+     * b - Break (includes continue)
+     * S - SimpleFor
+     * C - Switch
+     * 
+ */ + public abstract char id(); + + public int getPosition(); +} diff --git a/src/main/java/com/sk89q/worldedit/expression/lexer/Lexer.java b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/Lexer.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/expression/lexer/Lexer.java rename to src/main/java/com/sk89q/worldedit/internal/expression/lexer/Lexer.java index bfce6fb0a..bcced9640 100644 --- a/src/main/java/com/sk89q/worldedit/expression/lexer/Lexer.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/Lexer.java @@ -1,233 +1,233 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.lexer; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.sk89q.worldedit.expression.lexer.tokens.*; - -/** - * Processes a string into a list of tokens. - * - * Tokens can be numbers, identifiers, operators and assorted other characters. - * - * @author TomyLobo - */ -public class Lexer { - private final String expression; - private int position = 0; - - private Lexer(String expression) { - this.expression = expression; - } - - public static final List tokenize(String expression) throws LexerException { - return new Lexer(expression).tokenize(); - } - - private final DecisionTree operatorTree = new DecisionTree(null, - '+', new DecisionTree("+", - '=', new DecisionTree("+="), - '+', new DecisionTree("++") - ), - '-', new DecisionTree("-", - '=', new DecisionTree("-="), - '-', new DecisionTree("--") - ), - '*', new DecisionTree("*", - '=', new DecisionTree("*="), - '*', new DecisionTree("**") - ), - '/', new DecisionTree("/", - '=', new DecisionTree("/=") - ), - '%', new DecisionTree("%", - '=', new DecisionTree("%=") - ), - '^', new DecisionTree("^", - '=', new DecisionTree("^=") - ), - '=', new DecisionTree("=", - '=', new DecisionTree("==") - ), - '!', new DecisionTree("!", - '=', new DecisionTree("!=") - ), - '<', new DecisionTree("<", - '<', new DecisionTree("<<"), - '=', new DecisionTree("<=") - ), - '>', new DecisionTree(">", - '>', new DecisionTree(">>"), - '=', new DecisionTree(">=") - ), - '&', new DecisionTree(null, // not implemented - '&', new DecisionTree("&&") - ), - '|', new DecisionTree(null, // not implemented - '|', new DecisionTree("||") - ), - '~', new DecisionTree("~", - '=', new DecisionTree("~=") - ) - ); - - private static final Set characterTokens = new HashSet(); - static { - characterTokens.add(','); - characterTokens.add('('); - characterTokens.add(')'); - characterTokens.add('{'); - characterTokens.add('}'); - characterTokens.add(';'); - characterTokens.add('?'); - characterTokens.add(':'); - } - - private static final Set keywords = new HashSet(Arrays.asList("if", "else", "while", "do", "for", "break", "continue", "return", "switch", "case", "default")); - - private static final Pattern numberPattern = Pattern.compile("^([0-9]*(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?)"); - private static final Pattern identifierPattern = Pattern.compile("^([A-Za-z][0-9A-Za-z_]*)"); - - private final List tokenize() throws LexerException { - List tokens = new ArrayList(); - - do { - skipWhitespace(); - if (position >= expression.length()) { - break; - } - - Token token = operatorTree.evaluate(position); - if (token != null) { - tokens.add(token); - continue; - } - - final char ch = peek(); - - if (characterTokens.contains(ch)) { - tokens.add(new CharacterToken(position++, ch)); - continue; - } - - final Matcher numberMatcher = numberPattern.matcher(expression.substring(position)); - if (numberMatcher.lookingAt()) { - String numberPart = numberMatcher.group(1); - if (numberPart.length() > 0) { - try { - tokens.add(new NumberToken(position, Double.parseDouble(numberPart))); - } catch (NumberFormatException e) { - throw new LexerException(position, "Number parsing failed", e); - } - - position += numberPart.length(); - continue; - } - } - - final Matcher identifierMatcher = identifierPattern.matcher(expression.substring(position)); - if (identifierMatcher.lookingAt()) { - String identifierPart = identifierMatcher.group(1); - if (identifierPart.length() > 0) { - if (keywords.contains(identifierPart)) { - tokens.add(new KeywordToken(position, identifierPart)); - } else { - tokens.add(new IdentifierToken(position, identifierPart)); - } - - position += identifierPart.length(); - continue; - } - } - - throw new LexerException(position, "Unknown character '" + ch + "'"); - } while (position < expression.length()); - - return tokens; - } - - private char peek() { - return expression.charAt(position); - } - - private final void skipWhitespace() { - while (position < expression.length() && Character.isWhitespace(peek())) { - ++position; - } - } - - public class DecisionTree { - private final String tokenName; - private final Map subTrees = new HashMap(); - - private DecisionTree(String tokenName, Object... args) { - this.tokenName = tokenName; - - if (args.length % 2 != 0) { - throw new UnsupportedOperationException("You need to pass an even number of arguments."); - } - - for (int i = 0; i < args.length; i += 2) { - if (!(args[i] instanceof Character)) { - throw new UnsupportedOperationException("Argument #" + i + " expected to be 'Character', not '" + args[i].getClass().getName() + "'."); - } - if (!(args[i + 1] instanceof DecisionTree)) { - throw new UnsupportedOperationException("Argument #" + (i + 1) + " expected to be 'DecisionTree', not '" + args[i + 1].getClass().getName() + "'."); - } - - Character next = (Character) args[i]; - DecisionTree subTree = (DecisionTree) args[i + 1]; - - subTrees.put(next, subTree); - } - } - - private Token evaluate(int startPosition) throws LexerException { - if (position < expression.length()) { - final char next = peek(); - - final DecisionTree subTree = subTrees.get(next); - if (subTree != null) { - ++position; - final Token subTreeResult = subTree.evaluate(startPosition); - if (subTreeResult != null) { - return subTreeResult; - } - --position; - } - } - - if (tokenName == null) { - return null; - } - - return new OperatorToken(startPosition, tokenName); - } - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.lexer; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.sk89q.worldedit.internal.expression.lexer.tokens.*; + +/** + * Processes a string into a list of tokens. + * + * Tokens can be numbers, identifiers, operators and assorted other characters. + * + * @author TomyLobo + */ +public class Lexer { + private final String expression; + private int position = 0; + + private Lexer(String expression) { + this.expression = expression; + } + + public static final List tokenize(String expression) throws LexerException { + return new Lexer(expression).tokenize(); + } + + private final DecisionTree operatorTree = new DecisionTree(null, + '+', new DecisionTree("+", + '=', new DecisionTree("+="), + '+', new DecisionTree("++") + ), + '-', new DecisionTree("-", + '=', new DecisionTree("-="), + '-', new DecisionTree("--") + ), + '*', new DecisionTree("*", + '=', new DecisionTree("*="), + '*', new DecisionTree("**") + ), + '/', new DecisionTree("/", + '=', new DecisionTree("/=") + ), + '%', new DecisionTree("%", + '=', new DecisionTree("%=") + ), + '^', new DecisionTree("^", + '=', new DecisionTree("^=") + ), + '=', new DecisionTree("=", + '=', new DecisionTree("==") + ), + '!', new DecisionTree("!", + '=', new DecisionTree("!=") + ), + '<', new DecisionTree("<", + '<', new DecisionTree("<<"), + '=', new DecisionTree("<=") + ), + '>', new DecisionTree(">", + '>', new DecisionTree(">>"), + '=', new DecisionTree(">=") + ), + '&', new DecisionTree(null, // not implemented + '&', new DecisionTree("&&") + ), + '|', new DecisionTree(null, // not implemented + '|', new DecisionTree("||") + ), + '~', new DecisionTree("~", + '=', new DecisionTree("~=") + ) + ); + + private static final Set characterTokens = new HashSet(); + static { + characterTokens.add(','); + characterTokens.add('('); + characterTokens.add(')'); + characterTokens.add('{'); + characterTokens.add('}'); + characterTokens.add(';'); + characterTokens.add('?'); + characterTokens.add(':'); + } + + private static final Set keywords = new HashSet(Arrays.asList("if", "else", "while", "do", "for", "break", "continue", "return", "switch", "case", "default")); + + private static final Pattern numberPattern = Pattern.compile("^([0-9]*(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?)"); + private static final Pattern identifierPattern = Pattern.compile("^([A-Za-z][0-9A-Za-z_]*)"); + + private final List tokenize() throws LexerException { + List tokens = new ArrayList(); + + do { + skipWhitespace(); + if (position >= expression.length()) { + break; + } + + Token token = operatorTree.evaluate(position); + if (token != null) { + tokens.add(token); + continue; + } + + final char ch = peek(); + + if (characterTokens.contains(ch)) { + tokens.add(new CharacterToken(position++, ch)); + continue; + } + + final Matcher numberMatcher = numberPattern.matcher(expression.substring(position)); + if (numberMatcher.lookingAt()) { + String numberPart = numberMatcher.group(1); + if (numberPart.length() > 0) { + try { + tokens.add(new NumberToken(position, Double.parseDouble(numberPart))); + } catch (NumberFormatException e) { + throw new LexerException(position, "Number parsing failed", e); + } + + position += numberPart.length(); + continue; + } + } + + final Matcher identifierMatcher = identifierPattern.matcher(expression.substring(position)); + if (identifierMatcher.lookingAt()) { + String identifierPart = identifierMatcher.group(1); + if (identifierPart.length() > 0) { + if (keywords.contains(identifierPart)) { + tokens.add(new KeywordToken(position, identifierPart)); + } else { + tokens.add(new IdentifierToken(position, identifierPart)); + } + + position += identifierPart.length(); + continue; + } + } + + throw new LexerException(position, "Unknown character '" + ch + "'"); + } while (position < expression.length()); + + return tokens; + } + + private char peek() { + return expression.charAt(position); + } + + private final void skipWhitespace() { + while (position < expression.length() && Character.isWhitespace(peek())) { + ++position; + } + } + + public class DecisionTree { + private final String tokenName; + private final Map subTrees = new HashMap(); + + private DecisionTree(String tokenName, Object... args) { + this.tokenName = tokenName; + + if (args.length % 2 != 0) { + throw new UnsupportedOperationException("You need to pass an even number of arguments."); + } + + for (int i = 0; i < args.length; i += 2) { + if (!(args[i] instanceof Character)) { + throw new UnsupportedOperationException("Argument #" + i + " expected to be 'Character', not '" + args[i].getClass().getName() + "'."); + } + if (!(args[i + 1] instanceof DecisionTree)) { + throw new UnsupportedOperationException("Argument #" + (i + 1) + " expected to be 'DecisionTree', not '" + args[i + 1].getClass().getName() + "'."); + } + + Character next = (Character) args[i]; + DecisionTree subTree = (DecisionTree) args[i + 1]; + + subTrees.put(next, subTree); + } + } + + private Token evaluate(int startPosition) throws LexerException { + if (position < expression.length()) { + final char next = peek(); + + final DecisionTree subTree = subTrees.get(next); + if (subTree != null) { + ++position; + final Token subTreeResult = subTree.evaluate(startPosition); + if (subTreeResult != null) { + return subTreeResult; + } + --position; + } + } + + if (tokenName == null) { + return null; + } + + return new OperatorToken(startPosition, tokenName); + } + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/lexer/LexerException.java b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/LexerException.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/expression/lexer/LexerException.java rename to src/main/java/com/sk89q/worldedit/internal/expression/lexer/LexerException.java index c854b8360..292eac5de 100644 --- a/src/main/java/com/sk89q/worldedit/expression/lexer/LexerException.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/LexerException.java @@ -1,51 +1,51 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.lexer; - -import com.sk89q.worldedit.expression.ExpressionException; - -/** - * Thrown when the lexer encounters a problem. - * - * @author TomyLobo - */ -public class LexerException extends ExpressionException { - private static final long serialVersionUID = 1L; - - public LexerException(int position) { - super(position, getPrefix(position)); - } - - public LexerException(int position, String message, Throwable cause) { - super(position, getPrefix(position) + ": " + message, cause); - } - - public LexerException(int position, String message) { - super(position, getPrefix(position) + ": " + message); - } - - public LexerException(int position, Throwable cause) { - super(position, getPrefix(position), cause); - } - - private static String getPrefix(int position) { - return position < 0 ? "Lexer error" : ("Lexer error at " + (position + 1)); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.lexer; + +import com.sk89q.worldedit.internal.expression.ExpressionException; + +/** + * Thrown when the lexer encounters a problem. + * + * @author TomyLobo + */ +public class LexerException extends ExpressionException { + private static final long serialVersionUID = 1L; + + public LexerException(int position) { + super(position, getPrefix(position)); + } + + public LexerException(int position, String message, Throwable cause) { + super(position, getPrefix(position) + ": " + message, cause); + } + + public LexerException(int position, String message) { + super(position, getPrefix(position) + ": " + message); + } + + public LexerException(int position, Throwable cause) { + super(position, getPrefix(position), cause); + } + + private static String getPrefix(int position) { + return position < 0 ? "Lexer error" : ("Lexer error at " + (position + 1)); + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/CharacterToken.java b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/CharacterToken.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/expression/lexer/tokens/CharacterToken.java rename to src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/CharacterToken.java index 1757ae2b5..fc399db83 100644 --- a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/CharacterToken.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/CharacterToken.java @@ -1,44 +1,44 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.lexer.tokens; - -/** - * A single character that doesn't fit any of the other token categories. - * - * @author TomyLobo - */ -public class CharacterToken extends Token { - public final char character; - - public CharacterToken(int position, char character) { - super(position); - this.character = character; - } - - @Override - public char id() { - return character; - } - - @Override - public String toString() { - return "CharacterToken(" + character + ")"; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.lexer.tokens; + +/** + * A single character that doesn't fit any of the other token categories. + * + * @author TomyLobo + */ +public class CharacterToken extends Token { + public final char character; + + public CharacterToken(int position, char character) { + super(position); + this.character = character; + } + + @Override + public char id() { + return character; + } + + @Override + public String toString() { + return "CharacterToken(" + character + ")"; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/IdentifierToken.java b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/IdentifierToken.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/expression/lexer/tokens/IdentifierToken.java rename to src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/IdentifierToken.java index b4dab7f11..352ceb168 100644 --- a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/IdentifierToken.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/IdentifierToken.java @@ -1,44 +1,44 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.lexer.tokens; - -/** - * An identifier - * - * @author TomyLobo - */ -public class IdentifierToken extends Token { - public final String value; - - public IdentifierToken(int position, String value) { - super(position); - this.value = value; - } - - @Override - public char id() { - return 'i'; - } - - @Override - public String toString() { - return "IdentifierToken(" + value + ")"; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.lexer.tokens; + +/** + * An identifier + * + * @author TomyLobo + */ +public class IdentifierToken extends Token { + public final String value; + + public IdentifierToken(int position, String value) { + super(position); + this.value = value; + } + + @Override + public char id() { + return 'i'; + } + + @Override + public String toString() { + return "IdentifierToken(" + value + ")"; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/KeywordToken.java b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/KeywordToken.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/expression/lexer/tokens/KeywordToken.java rename to src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/KeywordToken.java index d2f7c755b..bdbe706c9 100644 --- a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/KeywordToken.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/KeywordToken.java @@ -1,44 +1,44 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.lexer.tokens; - -/** - * A keyword - * - * @author TomyLobo - */ -public class KeywordToken extends Token { - public final String value; - - public KeywordToken(int position, String value) { - super(position); - this.value = value; - } - - @Override - public char id() { - return 'k'; - } - - @Override - public String toString() { - return "KeywordToken(" + value + ")"; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.lexer.tokens; + +/** + * A keyword + * + * @author TomyLobo + */ +public class KeywordToken extends Token { + public final String value; + + public KeywordToken(int position, String value) { + super(position); + this.value = value; + } + + @Override + public char id() { + return 'k'; + } + + @Override + public String toString() { + return "KeywordToken(" + value + ")"; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/NumberToken.java b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/NumberToken.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/expression/lexer/tokens/NumberToken.java rename to src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/NumberToken.java index 77ebaa743..f4176748e 100644 --- a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/NumberToken.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/NumberToken.java @@ -1,44 +1,44 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.lexer.tokens; - -/** - * A number - * - * @author TomyLobo - */ -public class NumberToken extends Token { - public final double value; - - public NumberToken(int position, double value) { - super(position); - this.value = value; - } - - @Override - public char id() { - return '0'; - } - - @Override - public String toString() { - return "NumberToken(" + value + ")"; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.lexer.tokens; + +/** + * A number + * + * @author TomyLobo + */ +public class NumberToken extends Token { + public final double value; + + public NumberToken(int position, double value) { + super(position); + this.value = value; + } + + @Override + public char id() { + return '0'; + } + + @Override + public String toString() { + return "NumberToken(" + value + ")"; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/OperatorToken.java b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/OperatorToken.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/expression/lexer/tokens/OperatorToken.java rename to src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/OperatorToken.java index 169fc0d7a..d1aa1c71a 100644 --- a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/OperatorToken.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/OperatorToken.java @@ -1,44 +1,44 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.lexer.tokens; - -/** - * A unary or binary operator. - * - * @author TomyLobo - */ -public class OperatorToken extends Token { - public final String operator; - - public OperatorToken(int position, String operator) { - super(position); - this.operator = operator; - } - - @Override - public char id() { - return 'o'; - } - - @Override - public String toString() { - return "OperatorToken(" + operator + ")"; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.lexer.tokens; + +/** + * A unary or binary operator. + * + * @author TomyLobo + */ +public class OperatorToken extends Token { + public final String operator; + + public OperatorToken(int position, String operator) { + super(position); + this.operator = operator; + } + + @Override + public char id() { + return 'o'; + } + + @Override + public String toString() { + return "OperatorToken(" + operator + ")"; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/Token.java b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/Token.java similarity index 88% rename from src/main/java/com/sk89q/worldedit/expression/lexer/tokens/Token.java rename to src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/Token.java index 80e199884..83da0953b 100644 --- a/src/main/java/com/sk89q/worldedit/expression/lexer/tokens/Token.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/lexer/tokens/Token.java @@ -1,40 +1,40 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.lexer.tokens; - -import com.sk89q.worldedit.expression.Identifiable; - -/** - * A token. The lexer generates these to make the parser's job easier. - * - * @author TomyLobo - */ -public abstract class Token implements Identifiable { - private final int position; - - public Token(int position) { - this.position = position; - } - - @Override - public int getPosition() { - return position; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.lexer.tokens; + +import com.sk89q.worldedit.internal.expression.Identifiable; + +/** + * A token. The lexer generates these to make the parser's job easier. + * + * @author TomyLobo + */ +public abstract class Token implements Identifiable { + private final int position; + + public Token(int position) { + this.position = position; + } + + @Override + public int getPosition() { + return position; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/parser/Parser.java b/src/main/java/com/sk89q/worldedit/internal/expression/parser/Parser.java similarity index 90% rename from src/main/java/com/sk89q/worldedit/expression/parser/Parser.java rename to src/main/java/com/sk89q/worldedit/internal/expression/parser/Parser.java index 9ebb71a0d..fbb425155 100644 --- a/src/main/java/com/sk89q/worldedit/expression/parser/Parser.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/parser/Parser.java @@ -1,466 +1,466 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.parser; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.Identifiable; -import com.sk89q.worldedit.expression.lexer.tokens.IdentifierToken; -import com.sk89q.worldedit.expression.lexer.tokens.KeywordToken; -import com.sk89q.worldedit.expression.lexer.tokens.NumberToken; -import com.sk89q.worldedit.expression.lexer.tokens.OperatorToken; -import com.sk89q.worldedit.expression.lexer.tokens.Token; -import com.sk89q.worldedit.expression.runtime.Break; -import com.sk89q.worldedit.expression.runtime.Conditional; -import com.sk89q.worldedit.expression.runtime.Constant; -import com.sk89q.worldedit.expression.runtime.For; -import com.sk89q.worldedit.expression.runtime.Function; -import com.sk89q.worldedit.expression.runtime.Functions; -import com.sk89q.worldedit.expression.runtime.LValue; -import com.sk89q.worldedit.expression.runtime.RValue; -import com.sk89q.worldedit.expression.runtime.Return; -import com.sk89q.worldedit.expression.runtime.Sequence; -import com.sk89q.worldedit.expression.runtime.SimpleFor; -import com.sk89q.worldedit.expression.runtime.Switch; -import com.sk89q.worldedit.expression.runtime.While; - -/** - * Processes a list of tokens into an executable tree. - * - * Tokens can be numbers, identifiers, operators and assorted other characters. - * - * @author TomyLobo - */ -public class Parser { - private final class NullToken extends Token { - private NullToken(int position) { - super(position); - } - - public char id() { - return '\0'; - } - - @Override - public String toString() { - return "NullToken"; - } - } - - private final List tokens; - private int position = 0; - private Expression expression; - - private Parser(List tokens, Expression expression) { - this.tokens = tokens; - this.expression = expression; - } - - public static final RValue parse(List tokens, Expression expression) throws ParserException { - return new Parser(tokens, expression).parse(); - } - - private RValue parse() throws ParserException { - final RValue ret = parseStatements(false); - if (position < tokens.size()) { - final Token token = peek(); - throw new ParserException(token.getPosition(), "Extra token at the end of the input: " + token); - } - - ret.bindVariables(expression, false); - - return ret; - } - - private RValue parseStatements(boolean singleStatement) throws ParserException { - List statements = new ArrayList(); - loop: while (position < tokens.size()) { - boolean expectSemicolon = false; - - final Token current = peek(); - switch (current.id()) { - case '{': - consumeCharacter('{'); - - statements.add(parseStatements(false)); - - consumeCharacter('}'); - - break; - - case '}': - break loop; - - case 'k': - final String keyword = ((KeywordToken) current).value; - switch (keyword.charAt(0)) { - case 'i': { // if - ++position; - final RValue condition = parseBracket(); - final RValue truePart = parseStatements(true); - final RValue falsePart; - - if (hasKeyword("else")) { - ++position; - falsePart = parseStatements(true); - } else { - falsePart = null; - } - - statements.add(new Conditional(current.getPosition(), condition, truePart, falsePart)); - break; - } - - case 'w': { // while - ++position; - final RValue condition = parseBracket(); - final RValue body = parseStatements(true); - - statements.add(new While(current.getPosition(), condition, body, false)); - break; - } - - case 'd': { // do/default - if (hasKeyword("default")) { - break loop; - } - - ++position; - final RValue body = parseStatements(true); - - consumeKeyword("while"); - - final RValue condition = parseBracket(); - - statements.add(new While(current.getPosition(), condition, body, true)); - - expectSemicolon = true; - break; - } - - case 'f': { // for - ++position; - consumeCharacter('('); - int oldPosition = position; - final RValue init = parseExpression(true); - //if ((init instanceof LValue) && ) - if (peek().id() == ';') { - ++position; - final RValue condition = parseExpression(true); - consumeCharacter(';'); - final RValue increment = parseExpression(true); - consumeCharacter(')'); - final RValue body = parseStatements(true); - - statements.add(new For(current.getPosition(), init, condition, increment, body)); - } else { - position = oldPosition; - - final Token variableToken = peek(); - if (!(variableToken instanceof IdentifierToken)) { - throw new ParserException(variableToken.getPosition(), "Expected identifier"); - } - - RValue variable = expression.getVariable(((IdentifierToken) variableToken).value, true); - if (!(variable instanceof LValue)) { - throw new ParserException(variableToken.getPosition(), "Expected variable"); - } - ++position; - - final Token equalsToken = peek(); - if (!(equalsToken instanceof OperatorToken) || !((OperatorToken) equalsToken).operator.equals("=")) { - throw new ParserException(variableToken.getPosition(), "Expected '=' or a term and ';'"); - } - ++position; - - final RValue first = parseExpression(true); - consumeCharacter(','); - final RValue last = parseExpression(true); - consumeCharacter(')'); - final RValue body = parseStatements(true); - - statements.add(new SimpleFor(current.getPosition(), (LValue) variable, first, last, body)); - } // switch (keyword.charAt(0)) - break; - } - - case 'b': // break - ++position; - statements.add(new Break(current.getPosition(), false)); - break; - - case 'c': // continue/case - if (hasKeyword("case")) { - break loop; - } - - ++position; - statements.add(new Break(current.getPosition(), true)); - break; - - case 'r': // return - ++position; - statements.add(new Return(current.getPosition(), parseExpression(true))); - - expectSemicolon = true; - break; - - case 's': // switch - ++position; - final RValue parameter = parseBracket(); - final List values = new ArrayList(); - final List caseStatements = new ArrayList(); - RValue defaultCase = null; - - consumeCharacter('{'); - while (peek().id() != '}') { - if (position >= tokens.size()) { - throw new ParserException(current.getPosition(), "Expected '}' instead of EOF"); - } - if (defaultCase != null) { - throw new ParserException(current.getPosition(), "Expected '}' instead of " + peek()); - } - - if (hasKeyword("case")) { - ++position; - - final Token valueToken = peek(); - if (!(valueToken instanceof NumberToken)) { - throw new ParserException(current.getPosition(), "Expected number instead of " + peek()); - } - - ++position; - - values.add(((NumberToken) valueToken).value); - - consumeCharacter(':'); - caseStatements.add(parseStatements(false)); - } else if (hasKeyword("default")) { - ++position; - - consumeCharacter(':'); - defaultCase = parseStatements(false); - } else { - throw new ParserException(current.getPosition(), "Expected 'case' or 'default' instead of " + peek()); - } - } - consumeCharacter('}'); - - statements.add(new Switch(current.getPosition(), parameter, values, caseStatements, defaultCase)); - break; - - default: - throw new ParserException(current.getPosition(), "Unexpected keyword '" + keyword + "'"); - } - - break; - - default: - statements.add(parseExpression(true)); - - expectSemicolon = true; - } // switch (current.id()) - - if (expectSemicolon) { - if (peek().id() == ';') { - ++position; - } else { - break; - } - } - - if (singleStatement) { - break; - } - } // while (position < tokens.size()) - - switch (statements.size()) { - case 0: - if (singleStatement) { - throw new ParserException(peek().getPosition(), "Statement expected."); - } - - return new Sequence(peek().getPosition()); - - case 1: - return statements.get(0); - - default: - return new Sequence(peek().getPosition(), statements.toArray(new RValue[statements.size()])); - } - } - - private final RValue parseExpression(boolean canBeEmpty) throws ParserException { - LinkedList halfProcessed = new LinkedList(); - - // process brackets, numbers, functions, variables and detect prefix operators - boolean expressionStart = true; - loop: while (position < tokens.size()) { - final Token current = peek(); - - switch (current.id()) { - case '0': - halfProcessed.add(new Constant(current.getPosition(), ((NumberToken) current).value)); - ++position; - expressionStart = false; - break; - - case 'i': - final IdentifierToken identifierToken = (IdentifierToken) current; - ++position; - - final Token next = peek(); - if (next.id() == '(') { - halfProcessed.add(parseFunctionCall(identifierToken)); - } else { - final RValue variable = expression.getVariable(identifierToken.value, false); - if (variable == null) { - halfProcessed.add(new UnboundVariable(identifierToken.getPosition(), identifierToken.value)); - } else { - halfProcessed.add(variable); - } - } - expressionStart = false; - break; - - case '(': - halfProcessed.add(parseBracket()); - expressionStart = false; - break; - - case ',': - case ')': - case '}': - case ';': - break loop; - - case 'o': - if (expressionStart) { - // Preprocess prefix operators into unary operators - halfProcessed.add(new UnaryOperator((OperatorToken) current)); - } else { - halfProcessed.add(current); - } - ++position; - expressionStart = true; - break; - - default: - halfProcessed.add(current); - ++position; - expressionStart = false; - break; - } - } - - if (halfProcessed.isEmpty() && canBeEmpty) { - return new Sequence(peek().getPosition()); - } - - return ParserProcessors.processExpression(halfProcessed); - } - - - private Token peek() { - if (position >= tokens.size()) { - return new NullToken(tokens.get(tokens.size() - 1).getPosition() + 1); - } - - return tokens.get(position); - } - - private Function parseFunctionCall(IdentifierToken identifierToken) throws ParserException { - consumeCharacter('('); - - try { - if (peek().id() == ')') { - ++position; - return Functions.getFunction(identifierToken.getPosition(), identifierToken.value); - } - - List args = new ArrayList(); - - loop: while (true) { - args.add(parseExpression(false)); - - final Token current = peek(); - ++position; - - switch (current.id()) { - case ',': - continue; - - case ')': - break loop; - - default: - throw new ParserException(current.getPosition(), "Unmatched opening bracket"); - } - } - - return Functions.getFunction(identifierToken.getPosition(), identifierToken.value, args.toArray(new RValue[args.size()])); - } catch (NoSuchMethodException e) { - throw new ParserException(identifierToken.getPosition(), "Function '" + identifierToken.value + "' not found", e); - } - } - - private final RValue parseBracket() throws ParserException { - consumeCharacter('('); - - final RValue ret = parseExpression(false); - - consumeCharacter(')'); - - return ret; - } - - private boolean hasKeyword(String keyword) { - final Token next = peek(); - if (!(next instanceof KeywordToken)) { - return false; - } - return ((KeywordToken) next).value.equals(keyword); - } - - private void assertCharacter(char character) throws ParserException { - final Token next = peek(); - if (next.id() != character) { - throw new ParserException(next.getPosition(), "Expected '" + character + "'"); - } - } - - private void assertKeyword(String keyword) throws ParserException { - if (!hasKeyword(keyword)) { - throw new ParserException(peek().getPosition(), "Expected '" + keyword + "'"); - } - } - - private void consumeCharacter(char character) throws ParserException { - assertCharacter(character); - ++position; - } - - private void consumeKeyword(String keyword) throws ParserException { - assertKeyword(keyword); - ++position; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.parser; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.Identifiable; +import com.sk89q.worldedit.internal.expression.lexer.tokens.IdentifierToken; +import com.sk89q.worldedit.internal.expression.lexer.tokens.KeywordToken; +import com.sk89q.worldedit.internal.expression.lexer.tokens.NumberToken; +import com.sk89q.worldedit.internal.expression.lexer.tokens.OperatorToken; +import com.sk89q.worldedit.internal.expression.lexer.tokens.Token; +import com.sk89q.worldedit.internal.expression.runtime.Break; +import com.sk89q.worldedit.internal.expression.runtime.Conditional; +import com.sk89q.worldedit.internal.expression.runtime.Constant; +import com.sk89q.worldedit.internal.expression.runtime.For; +import com.sk89q.worldedit.internal.expression.runtime.Function; +import com.sk89q.worldedit.internal.expression.runtime.Functions; +import com.sk89q.worldedit.internal.expression.runtime.LValue; +import com.sk89q.worldedit.internal.expression.runtime.RValue; +import com.sk89q.worldedit.internal.expression.runtime.Return; +import com.sk89q.worldedit.internal.expression.runtime.Sequence; +import com.sk89q.worldedit.internal.expression.runtime.SimpleFor; +import com.sk89q.worldedit.internal.expression.runtime.Switch; +import com.sk89q.worldedit.internal.expression.runtime.While; + +/** + * Processes a list of tokens into an executable tree. + * + * Tokens can be numbers, identifiers, operators and assorted other characters. + * + * @author TomyLobo + */ +public class Parser { + private final class NullToken extends Token { + private NullToken(int position) { + super(position); + } + + public char id() { + return '\0'; + } + + @Override + public String toString() { + return "NullToken"; + } + } + + private final List tokens; + private int position = 0; + private Expression expression; + + private Parser(List tokens, Expression expression) { + this.tokens = tokens; + this.expression = expression; + } + + public static final RValue parse(List tokens, Expression expression) throws ParserException { + return new Parser(tokens, expression).parse(); + } + + private RValue parse() throws ParserException { + final RValue ret = parseStatements(false); + if (position < tokens.size()) { + final Token token = peek(); + throw new ParserException(token.getPosition(), "Extra token at the end of the input: " + token); + } + + ret.bindVariables(expression, false); + + return ret; + } + + private RValue parseStatements(boolean singleStatement) throws ParserException { + List statements = new ArrayList(); + loop: while (position < tokens.size()) { + boolean expectSemicolon = false; + + final Token current = peek(); + switch (current.id()) { + case '{': + consumeCharacter('{'); + + statements.add(parseStatements(false)); + + consumeCharacter('}'); + + break; + + case '}': + break loop; + + case 'k': + final String keyword = ((KeywordToken) current).value; + switch (keyword.charAt(0)) { + case 'i': { // if + ++position; + final RValue condition = parseBracket(); + final RValue truePart = parseStatements(true); + final RValue falsePart; + + if (hasKeyword("else")) { + ++position; + falsePart = parseStatements(true); + } else { + falsePart = null; + } + + statements.add(new Conditional(current.getPosition(), condition, truePart, falsePart)); + break; + } + + case 'w': { // while + ++position; + final RValue condition = parseBracket(); + final RValue body = parseStatements(true); + + statements.add(new While(current.getPosition(), condition, body, false)); + break; + } + + case 'd': { // do/default + if (hasKeyword("default")) { + break loop; + } + + ++position; + final RValue body = parseStatements(true); + + consumeKeyword("while"); + + final RValue condition = parseBracket(); + + statements.add(new While(current.getPosition(), condition, body, true)); + + expectSemicolon = true; + break; + } + + case 'f': { // for + ++position; + consumeCharacter('('); + int oldPosition = position; + final RValue init = parseExpression(true); + //if ((init instanceof LValue) && ) + if (peek().id() == ';') { + ++position; + final RValue condition = parseExpression(true); + consumeCharacter(';'); + final RValue increment = parseExpression(true); + consumeCharacter(')'); + final RValue body = parseStatements(true); + + statements.add(new For(current.getPosition(), init, condition, increment, body)); + } else { + position = oldPosition; + + final Token variableToken = peek(); + if (!(variableToken instanceof IdentifierToken)) { + throw new ParserException(variableToken.getPosition(), "Expected identifier"); + } + + RValue variable = expression.getVariable(((IdentifierToken) variableToken).value, true); + if (!(variable instanceof LValue)) { + throw new ParserException(variableToken.getPosition(), "Expected variable"); + } + ++position; + + final Token equalsToken = peek(); + if (!(equalsToken instanceof OperatorToken) || !((OperatorToken) equalsToken).operator.equals("=")) { + throw new ParserException(variableToken.getPosition(), "Expected '=' or a term and ';'"); + } + ++position; + + final RValue first = parseExpression(true); + consumeCharacter(','); + final RValue last = parseExpression(true); + consumeCharacter(')'); + final RValue body = parseStatements(true); + + statements.add(new SimpleFor(current.getPosition(), (LValue) variable, first, last, body)); + } // switch (keyword.charAt(0)) + break; + } + + case 'b': // break + ++position; + statements.add(new Break(current.getPosition(), false)); + break; + + case 'c': // continue/case + if (hasKeyword("case")) { + break loop; + } + + ++position; + statements.add(new Break(current.getPosition(), true)); + break; + + case 'r': // return + ++position; + statements.add(new Return(current.getPosition(), parseExpression(true))); + + expectSemicolon = true; + break; + + case 's': // switch + ++position; + final RValue parameter = parseBracket(); + final List values = new ArrayList(); + final List caseStatements = new ArrayList(); + RValue defaultCase = null; + + consumeCharacter('{'); + while (peek().id() != '}') { + if (position >= tokens.size()) { + throw new ParserException(current.getPosition(), "Expected '}' instead of EOF"); + } + if (defaultCase != null) { + throw new ParserException(current.getPosition(), "Expected '}' instead of " + peek()); + } + + if (hasKeyword("case")) { + ++position; + + final Token valueToken = peek(); + if (!(valueToken instanceof NumberToken)) { + throw new ParserException(current.getPosition(), "Expected number instead of " + peek()); + } + + ++position; + + values.add(((NumberToken) valueToken).value); + + consumeCharacter(':'); + caseStatements.add(parseStatements(false)); + } else if (hasKeyword("default")) { + ++position; + + consumeCharacter(':'); + defaultCase = parseStatements(false); + } else { + throw new ParserException(current.getPosition(), "Expected 'case' or 'default' instead of " + peek()); + } + } + consumeCharacter('}'); + + statements.add(new Switch(current.getPosition(), parameter, values, caseStatements, defaultCase)); + break; + + default: + throw new ParserException(current.getPosition(), "Unexpected keyword '" + keyword + "'"); + } + + break; + + default: + statements.add(parseExpression(true)); + + expectSemicolon = true; + } // switch (current.id()) + + if (expectSemicolon) { + if (peek().id() == ';') { + ++position; + } else { + break; + } + } + + if (singleStatement) { + break; + } + } // while (position < tokens.size()) + + switch (statements.size()) { + case 0: + if (singleStatement) { + throw new ParserException(peek().getPosition(), "Statement expected."); + } + + return new Sequence(peek().getPosition()); + + case 1: + return statements.get(0); + + default: + return new Sequence(peek().getPosition(), statements.toArray(new RValue[statements.size()])); + } + } + + private final RValue parseExpression(boolean canBeEmpty) throws ParserException { + LinkedList halfProcessed = new LinkedList(); + + // process brackets, numbers, functions, variables and detect prefix operators + boolean expressionStart = true; + loop: while (position < tokens.size()) { + final Token current = peek(); + + switch (current.id()) { + case '0': + halfProcessed.add(new Constant(current.getPosition(), ((NumberToken) current).value)); + ++position; + expressionStart = false; + break; + + case 'i': + final IdentifierToken identifierToken = (IdentifierToken) current; + ++position; + + final Token next = peek(); + if (next.id() == '(') { + halfProcessed.add(parseFunctionCall(identifierToken)); + } else { + final RValue variable = expression.getVariable(identifierToken.value, false); + if (variable == null) { + halfProcessed.add(new UnboundVariable(identifierToken.getPosition(), identifierToken.value)); + } else { + halfProcessed.add(variable); + } + } + expressionStart = false; + break; + + case '(': + halfProcessed.add(parseBracket()); + expressionStart = false; + break; + + case ',': + case ')': + case '}': + case ';': + break loop; + + case 'o': + if (expressionStart) { + // Preprocess prefix operators into unary operators + halfProcessed.add(new UnaryOperator((OperatorToken) current)); + } else { + halfProcessed.add(current); + } + ++position; + expressionStart = true; + break; + + default: + halfProcessed.add(current); + ++position; + expressionStart = false; + break; + } + } + + if (halfProcessed.isEmpty() && canBeEmpty) { + return new Sequence(peek().getPosition()); + } + + return ParserProcessors.processExpression(halfProcessed); + } + + + private Token peek() { + if (position >= tokens.size()) { + return new NullToken(tokens.get(tokens.size() - 1).getPosition() + 1); + } + + return tokens.get(position); + } + + private Function parseFunctionCall(IdentifierToken identifierToken) throws ParserException { + consumeCharacter('('); + + try { + if (peek().id() == ')') { + ++position; + return Functions.getFunction(identifierToken.getPosition(), identifierToken.value); + } + + List args = new ArrayList(); + + loop: while (true) { + args.add(parseExpression(false)); + + final Token current = peek(); + ++position; + + switch (current.id()) { + case ',': + continue; + + case ')': + break loop; + + default: + throw new ParserException(current.getPosition(), "Unmatched opening bracket"); + } + } + + return Functions.getFunction(identifierToken.getPosition(), identifierToken.value, args.toArray(new RValue[args.size()])); + } catch (NoSuchMethodException e) { + throw new ParserException(identifierToken.getPosition(), "Function '" + identifierToken.value + "' not found", e); + } + } + + private final RValue parseBracket() throws ParserException { + consumeCharacter('('); + + final RValue ret = parseExpression(false); + + consumeCharacter(')'); + + return ret; + } + + private boolean hasKeyword(String keyword) { + final Token next = peek(); + if (!(next instanceof KeywordToken)) { + return false; + } + return ((KeywordToken) next).value.equals(keyword); + } + + private void assertCharacter(char character) throws ParserException { + final Token next = peek(); + if (next.id() != character) { + throw new ParserException(next.getPosition(), "Expected '" + character + "'"); + } + } + + private void assertKeyword(String keyword) throws ParserException { + if (!hasKeyword(keyword)) { + throw new ParserException(peek().getPosition(), "Expected '" + keyword + "'"); + } + } + + private void consumeCharacter(char character) throws ParserException { + assertCharacter(character); + ++position; + } + + private void consumeKeyword(String keyword) throws ParserException { + assertKeyword(keyword); + ++position; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/parser/ParserException.java b/src/main/java/com/sk89q/worldedit/internal/expression/parser/ParserException.java similarity index 90% rename from src/main/java/com/sk89q/worldedit/expression/parser/ParserException.java rename to src/main/java/com/sk89q/worldedit/internal/expression/parser/ParserException.java index 6a97b6f8d..46af70bc5 100644 --- a/src/main/java/com/sk89q/worldedit/expression/parser/ParserException.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/parser/ParserException.java @@ -1,51 +1,51 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.parser; - -import com.sk89q.worldedit.expression.ExpressionException; - -/** - * Thrown when the parser encounters a problem. - * - * @author TomyLobo - */ -public class ParserException extends ExpressionException { - private static final long serialVersionUID = 1L; - - public ParserException(int position) { - super(position, getPrefix(position)); - } - - public ParserException(int position, String message, Throwable cause) { - super(position, getPrefix(position) + ": " + message, cause); - } - - public ParserException(int position, String message) { - super(position, getPrefix(position) + ": " + message); - } - - public ParserException(int position, Throwable cause) { - super(position, getPrefix(position), cause); - } - - private static String getPrefix(int position) { - return position < 0 ? "Parser error" : ("Parser error at " + (position + 1)); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.parser; + +import com.sk89q.worldedit.internal.expression.ExpressionException; + +/** + * Thrown when the parser encounters a problem. + * + * @author TomyLobo + */ +public class ParserException extends ExpressionException { + private static final long serialVersionUID = 1L; + + public ParserException(int position) { + super(position, getPrefix(position)); + } + + public ParserException(int position, String message, Throwable cause) { + super(position, getPrefix(position) + ": " + message, cause); + } + + public ParserException(int position, String message) { + super(position, getPrefix(position) + ": " + message); + } + + public ParserException(int position, Throwable cause) { + super(position, getPrefix(position), cause); + } + + private static String getPrefix(int position) { + return position < 0 ? "Parser error" : ("Parser error at " + (position + 1)); + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/parser/ParserProcessors.java b/src/main/java/com/sk89q/worldedit/internal/expression/parser/ParserProcessors.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/expression/parser/ParserProcessors.java rename to src/main/java/com/sk89q/worldedit/internal/expression/parser/ParserProcessors.java index 63b1a059e..7dfee6a38 100644 --- a/src/main/java/com/sk89q/worldedit/expression/parser/ParserProcessors.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/parser/ParserProcessors.java @@ -1,351 +1,351 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.parser; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; - -import com.sk89q.worldedit.expression.Identifiable; -import com.sk89q.worldedit.expression.lexer.tokens.OperatorToken; -import com.sk89q.worldedit.expression.lexer.tokens.Token; -import com.sk89q.worldedit.expression.runtime.Conditional; -import com.sk89q.worldedit.expression.runtime.RValue; -import com.sk89q.worldedit.expression.runtime.Operators; - -/** - * Helper classfor Parser. Contains processors for statements and operators. - * - * @author TomyLobo - */ -public final class ParserProcessors { - private static final Map unaryOpMap = new HashMap(); - - private static final Map[] binaryOpMapsLA; - private static final Map[] binaryOpMapsRA; - - static { - unaryOpMap.put("-", "neg"); - unaryOpMap.put("!", "not"); - unaryOpMap.put("~", "inv"); - unaryOpMap.put("++", "inc"); - unaryOpMap.put("--", "dec"); - unaryOpMap.put("x++", "postinc"); - unaryOpMap.put("x--", "postdec"); - unaryOpMap.put("x!", "fac"); - - final Object[][][] binaryOpsLA = { - { - { "^", "pow" }, - { "**", "pow" }, - }, - { - { "*", "mul" }, - { "/", "div" }, - { "%", "mod" }, - }, - { - { "+", "add" }, - { "-", "sub" }, - }, - { - { "<<", "shl" }, - { ">>", "shr" }, - }, - { - { "<", "lth" }, - { ">", "gth" }, - { "<=", "leq" }, - { ">=", "geq" }, - }, - { - { "==", "equ" }, - { "!=", "neq" }, - { "~=", "near" }, - }, - { - { "&&", "and" }, - }, - { - { "||", "or" }, - }, - }; - final Object[][][] binaryOpsRA = { - { - { "=", "ass" }, - { "+=", "aadd" }, - { "-=", "asub" }, - { "*=", "amul" }, - { "/=", "adiv" }, - { "%=", "amod" }, - { "^=", "aexp" }, - }, - }; - - @SuppressWarnings("unchecked") - final Map[] lBinaryOpMapsLA = binaryOpMapsLA = new Map[binaryOpsLA.length]; - for (int i = 0; i < binaryOpsLA.length; ++i) { - final Object[][] a = binaryOpsLA[i]; - switch (a.length) { - case 0: - lBinaryOpMapsLA[i] = Collections.emptyMap(); - break; - - case 1: - final Object[] first = a[0]; - lBinaryOpMapsLA[i] = Collections.singletonMap((String) first[0], (String) first[1]); - break; - - default: - Map m = lBinaryOpMapsLA[i] = new HashMap(); - for (int j = 0; j < a.length; ++j) { - final Object[] element = a[j]; - m.put((String) element[0], (String) element[1]); - } - } - } - - @SuppressWarnings("unchecked") - final Map[] lBinaryOpMapsRA = binaryOpMapsRA = new Map[binaryOpsRA.length]; - for (int i = 0; i < binaryOpsRA.length; ++i) { - final Object[][] a = binaryOpsRA[i]; - switch (a.length) { - case 0: - lBinaryOpMapsRA[i] = Collections.emptyMap(); - break; - - case 1: - final Object[] first = a[0]; - lBinaryOpMapsRA[i] = Collections.singletonMap((String) first[0], (String) first[1]); - break; - - default: - Map m = lBinaryOpMapsRA[i] = new HashMap(); - for (int j = 0; j < a.length; ++j) { - final Object[] element = a[j]; - m.put((String) element[0], (String) element[1]); - } - } - } - } - - static RValue processExpression(LinkedList input) throws ParserException { - return processBinaryOpsRA(input, binaryOpMapsRA.length - 1); - } - - private static RValue processBinaryOpsLA(LinkedList input, int level) throws ParserException { - if (level < 0) { - return processUnaryOps(input); - } - - LinkedList lhs = new LinkedList(); - LinkedList rhs = new LinkedList(); - String operator = null; - - for (Iterator it = input.descendingIterator(); it.hasNext();) { - Identifiable identifiable = it.next(); - if (operator == null) { - rhs.addFirst(identifiable); - - if (!(identifiable instanceof OperatorToken)) { - continue; - } - - operator = binaryOpMapsLA[level].get(((OperatorToken) identifiable).operator); - if (operator == null) { - continue; - } - - rhs.removeFirst(); - } else { - lhs.addFirst(identifiable); - } - } - - RValue rhsInvokable = processBinaryOpsLA(rhs, level - 1); - if (operator == null) return rhsInvokable; - - RValue lhsInvokable = processBinaryOpsLA(lhs, level); - - try { - return Operators.getOperator(input.get(0).getPosition(), operator, lhsInvokable, rhsInvokable); - } catch (NoSuchMethodException e) { - final Token operatorToken = (Token) input.get(lhs.size()); - throw new ParserException(operatorToken.getPosition(), "Couldn't find operator '" + operator + "'"); - } - } - - private static RValue processBinaryOpsRA(LinkedList input, int level) throws ParserException { - if (level < 0) { - return processTernaryOps(input); - } - - LinkedList lhs = new LinkedList(); - LinkedList rhs = new LinkedList(); - String operator = null; - - for (Identifiable identifiable : input) { - if (operator == null) { - lhs.addLast(identifiable); - - if (!(identifiable instanceof OperatorToken)) { - continue; - } - - operator = binaryOpMapsRA[level].get(((OperatorToken) identifiable).operator); - if (operator == null) { - continue; - } - - lhs.removeLast(); - } else { - rhs.addLast(identifiable); - } - } - - RValue lhsInvokable = processBinaryOpsRA(lhs, level - 1); - if (operator == null) return lhsInvokable; - - RValue rhsInvokable = processBinaryOpsRA(rhs, level); - - try { - return Operators.getOperator(input.get(0).getPosition(), operator, lhsInvokable, rhsInvokable); - } catch (NoSuchMethodException e) { - final Token operatorToken = (Token) input.get(lhs.size()); - throw new ParserException(operatorToken.getPosition(), "Couldn't find operator '" + operator + "'"); - } - } - - private static RValue processTernaryOps(LinkedList input) throws ParserException { - LinkedList lhs = new LinkedList(); - LinkedList mhs = new LinkedList(); - LinkedList rhs = new LinkedList(); - - int partsFound = 0; - int conditionalsFound = 0; - - for (Identifiable identifiable : input) { - final char character = identifiable.id(); - switch (character) { - case '?': - ++conditionalsFound; - break; - case ':': - --conditionalsFound; - break; - } - - if (conditionalsFound < 0) { - throw new ParserException(identifiable.getPosition(), "Unexpected ':'"); - } - - switch (partsFound) { - case 0: - if (character == '?') { - partsFound = 1; - } else { - lhs.addLast(identifiable); - } - break; - - case 1: - if (conditionalsFound == 0 && character == ':') { - partsFound = 2; - } else { - mhs.addLast(identifiable); - } - break; - - case 2: - rhs.addLast(identifiable); - } - } - - if (partsFound < 2) { - return processBinaryOpsLA(input, binaryOpMapsLA.length - 1); - } - - RValue lhsInvokable = processBinaryOpsLA(lhs, binaryOpMapsLA.length - 1); - RValue mhsInvokable = processTernaryOps(mhs); - RValue rhsInvokable = processTernaryOps(rhs); - - return new Conditional(input.get(lhs.size()).getPosition(), lhsInvokable, mhsInvokable, rhsInvokable); - } - - private static RValue processUnaryOps(LinkedList input) throws ParserException { - // Preprocess postfix operators into unary operators - final Identifiable center; - LinkedList postfixes = new LinkedList(); - do { - if (input.isEmpty()) { - throw new ParserException(-1, "Expression missing."); - } - - final Identifiable last = input.removeLast(); - if (last instanceof OperatorToken) { - postfixes.addLast(new UnaryOperator(last.getPosition(), "x" + ((OperatorToken) last).operator)); - } else if (last instanceof UnaryOperator) { - postfixes.addLast(new UnaryOperator(last.getPosition(), "x" + ((UnaryOperator) last).operator)); - } else { - center = last; - break; - } - } while (true); - - if (!(center instanceof RValue)) { - throw new ParserException(center.getPosition(), "Expected expression, found " + center); - } - - input.addAll(postfixes); - - RValue ret = (RValue) center; - while (!input.isEmpty()) { - final Identifiable last = input.removeLast(); - final int lastPosition = last.getPosition(); - if (last instanceof UnaryOperator) { - final String operator = ((UnaryOperator) last).operator; - if (operator.equals("+")) { - continue; - } - - String opName = unaryOpMap.get(operator); - if (opName != null) { - try { - ret = Operators.getOperator(lastPosition, opName, ret); - continue; - } catch (NoSuchMethodException e) { - throw new ParserException(lastPosition, "No such prefix operator: " + operator); - } - } - } - - if (last instanceof Token) { - throw new ParserException(lastPosition, "Extra token found in expression: " + last); - } else if (last instanceof RValue) { - throw new ParserException(lastPosition, "Extra expression found: " + last); - } else { - throw new ParserException(lastPosition, "Extra element found: " + last); - } - } - return ret; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.parser; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; + +import com.sk89q.worldedit.internal.expression.Identifiable; +import com.sk89q.worldedit.internal.expression.lexer.tokens.OperatorToken; +import com.sk89q.worldedit.internal.expression.lexer.tokens.Token; +import com.sk89q.worldedit.internal.expression.runtime.Conditional; +import com.sk89q.worldedit.internal.expression.runtime.RValue; +import com.sk89q.worldedit.internal.expression.runtime.Operators; + +/** + * Helper classfor Parser. Contains processors for statements and operators. + * + * @author TomyLobo + */ +public final class ParserProcessors { + private static final Map unaryOpMap = new HashMap(); + + private static final Map[] binaryOpMapsLA; + private static final Map[] binaryOpMapsRA; + + static { + unaryOpMap.put("-", "neg"); + unaryOpMap.put("!", "not"); + unaryOpMap.put("~", "inv"); + unaryOpMap.put("++", "inc"); + unaryOpMap.put("--", "dec"); + unaryOpMap.put("x++", "postinc"); + unaryOpMap.put("x--", "postdec"); + unaryOpMap.put("x!", "fac"); + + final Object[][][] binaryOpsLA = { + { + { "^", "pow" }, + { "**", "pow" }, + }, + { + { "*", "mul" }, + { "/", "div" }, + { "%", "mod" }, + }, + { + { "+", "add" }, + { "-", "sub" }, + }, + { + { "<<", "shl" }, + { ">>", "shr" }, + }, + { + { "<", "lth" }, + { ">", "gth" }, + { "<=", "leq" }, + { ">=", "geq" }, + }, + { + { "==", "equ" }, + { "!=", "neq" }, + { "~=", "near" }, + }, + { + { "&&", "and" }, + }, + { + { "||", "or" }, + }, + }; + final Object[][][] binaryOpsRA = { + { + { "=", "ass" }, + { "+=", "aadd" }, + { "-=", "asub" }, + { "*=", "amul" }, + { "/=", "adiv" }, + { "%=", "amod" }, + { "^=", "aexp" }, + }, + }; + + @SuppressWarnings("unchecked") + final Map[] lBinaryOpMapsLA = binaryOpMapsLA = new Map[binaryOpsLA.length]; + for (int i = 0; i < binaryOpsLA.length; ++i) { + final Object[][] a = binaryOpsLA[i]; + switch (a.length) { + case 0: + lBinaryOpMapsLA[i] = Collections.emptyMap(); + break; + + case 1: + final Object[] first = a[0]; + lBinaryOpMapsLA[i] = Collections.singletonMap((String) first[0], (String) first[1]); + break; + + default: + Map m = lBinaryOpMapsLA[i] = new HashMap(); + for (int j = 0; j < a.length; ++j) { + final Object[] element = a[j]; + m.put((String) element[0], (String) element[1]); + } + } + } + + @SuppressWarnings("unchecked") + final Map[] lBinaryOpMapsRA = binaryOpMapsRA = new Map[binaryOpsRA.length]; + for (int i = 0; i < binaryOpsRA.length; ++i) { + final Object[][] a = binaryOpsRA[i]; + switch (a.length) { + case 0: + lBinaryOpMapsRA[i] = Collections.emptyMap(); + break; + + case 1: + final Object[] first = a[0]; + lBinaryOpMapsRA[i] = Collections.singletonMap((String) first[0], (String) first[1]); + break; + + default: + Map m = lBinaryOpMapsRA[i] = new HashMap(); + for (int j = 0; j < a.length; ++j) { + final Object[] element = a[j]; + m.put((String) element[0], (String) element[1]); + } + } + } + } + + static RValue processExpression(LinkedList input) throws ParserException { + return processBinaryOpsRA(input, binaryOpMapsRA.length - 1); + } + + private static RValue processBinaryOpsLA(LinkedList input, int level) throws ParserException { + if (level < 0) { + return processUnaryOps(input); + } + + LinkedList lhs = new LinkedList(); + LinkedList rhs = new LinkedList(); + String operator = null; + + for (Iterator it = input.descendingIterator(); it.hasNext();) { + Identifiable identifiable = it.next(); + if (operator == null) { + rhs.addFirst(identifiable); + + if (!(identifiable instanceof OperatorToken)) { + continue; + } + + operator = binaryOpMapsLA[level].get(((OperatorToken) identifiable).operator); + if (operator == null) { + continue; + } + + rhs.removeFirst(); + } else { + lhs.addFirst(identifiable); + } + } + + RValue rhsInvokable = processBinaryOpsLA(rhs, level - 1); + if (operator == null) return rhsInvokable; + + RValue lhsInvokable = processBinaryOpsLA(lhs, level); + + try { + return Operators.getOperator(input.get(0).getPosition(), operator, lhsInvokable, rhsInvokable); + } catch (NoSuchMethodException e) { + final Token operatorToken = (Token) input.get(lhs.size()); + throw new ParserException(operatorToken.getPosition(), "Couldn't find operator '" + operator + "'"); + } + } + + private static RValue processBinaryOpsRA(LinkedList input, int level) throws ParserException { + if (level < 0) { + return processTernaryOps(input); + } + + LinkedList lhs = new LinkedList(); + LinkedList rhs = new LinkedList(); + String operator = null; + + for (Identifiable identifiable : input) { + if (operator == null) { + lhs.addLast(identifiable); + + if (!(identifiable instanceof OperatorToken)) { + continue; + } + + operator = binaryOpMapsRA[level].get(((OperatorToken) identifiable).operator); + if (operator == null) { + continue; + } + + lhs.removeLast(); + } else { + rhs.addLast(identifiable); + } + } + + RValue lhsInvokable = processBinaryOpsRA(lhs, level - 1); + if (operator == null) return lhsInvokable; + + RValue rhsInvokable = processBinaryOpsRA(rhs, level); + + try { + return Operators.getOperator(input.get(0).getPosition(), operator, lhsInvokable, rhsInvokable); + } catch (NoSuchMethodException e) { + final Token operatorToken = (Token) input.get(lhs.size()); + throw new ParserException(operatorToken.getPosition(), "Couldn't find operator '" + operator + "'"); + } + } + + private static RValue processTernaryOps(LinkedList input) throws ParserException { + LinkedList lhs = new LinkedList(); + LinkedList mhs = new LinkedList(); + LinkedList rhs = new LinkedList(); + + int partsFound = 0; + int conditionalsFound = 0; + + for (Identifiable identifiable : input) { + final char character = identifiable.id(); + switch (character) { + case '?': + ++conditionalsFound; + break; + case ':': + --conditionalsFound; + break; + } + + if (conditionalsFound < 0) { + throw new ParserException(identifiable.getPosition(), "Unexpected ':'"); + } + + switch (partsFound) { + case 0: + if (character == '?') { + partsFound = 1; + } else { + lhs.addLast(identifiable); + } + break; + + case 1: + if (conditionalsFound == 0 && character == ':') { + partsFound = 2; + } else { + mhs.addLast(identifiable); + } + break; + + case 2: + rhs.addLast(identifiable); + } + } + + if (partsFound < 2) { + return processBinaryOpsLA(input, binaryOpMapsLA.length - 1); + } + + RValue lhsInvokable = processBinaryOpsLA(lhs, binaryOpMapsLA.length - 1); + RValue mhsInvokable = processTernaryOps(mhs); + RValue rhsInvokable = processTernaryOps(rhs); + + return new Conditional(input.get(lhs.size()).getPosition(), lhsInvokable, mhsInvokable, rhsInvokable); + } + + private static RValue processUnaryOps(LinkedList input) throws ParserException { + // Preprocess postfix operators into unary operators + final Identifiable center; + LinkedList postfixes = new LinkedList(); + do { + if (input.isEmpty()) { + throw new ParserException(-1, "Expression missing."); + } + + final Identifiable last = input.removeLast(); + if (last instanceof OperatorToken) { + postfixes.addLast(new UnaryOperator(last.getPosition(), "x" + ((OperatorToken) last).operator)); + } else if (last instanceof UnaryOperator) { + postfixes.addLast(new UnaryOperator(last.getPosition(), "x" + ((UnaryOperator) last).operator)); + } else { + center = last; + break; + } + } while (true); + + if (!(center instanceof RValue)) { + throw new ParserException(center.getPosition(), "Expected expression, found " + center); + } + + input.addAll(postfixes); + + RValue ret = (RValue) center; + while (!input.isEmpty()) { + final Identifiable last = input.removeLast(); + final int lastPosition = last.getPosition(); + if (last instanceof UnaryOperator) { + final String operator = ((UnaryOperator) last).operator; + if (operator.equals("+")) { + continue; + } + + String opName = unaryOpMap.get(operator); + if (opName != null) { + try { + ret = Operators.getOperator(lastPosition, opName, ret); + continue; + } catch (NoSuchMethodException e) { + throw new ParserException(lastPosition, "No such prefix operator: " + operator); + } + } + } + + if (last instanceof Token) { + throw new ParserException(lastPosition, "Extra token found in expression: " + last); + } else if (last instanceof RValue) { + throw new ParserException(lastPosition, "Extra expression found: " + last); + } else { + throw new ParserException(lastPosition, "Extra element found: " + last); + } + } + return ret; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/parser/PseudoToken.java b/src/main/java/com/sk89q/worldedit/internal/expression/parser/PseudoToken.java similarity index 88% rename from src/main/java/com/sk89q/worldedit/expression/parser/PseudoToken.java rename to src/main/java/com/sk89q/worldedit/internal/expression/parser/PseudoToken.java index 69a176fab..b1de364a3 100644 --- a/src/main/java/com/sk89q/worldedit/expression/parser/PseudoToken.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/parser/PseudoToken.java @@ -1,43 +1,43 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.parser; - -import com.sk89q.worldedit.expression.Identifiable; - -/** - * A pseudo-token, inserted by the parser instead of the lexer. - * - * @author TomyLobo - */ -public abstract class PseudoToken implements Identifiable { - private final int position; - - public PseudoToken(int position) { - this.position = position; - } - - @Override - public abstract char id(); - - @Override - public int getPosition() { - return position; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.parser; + +import com.sk89q.worldedit.internal.expression.Identifiable; + +/** + * A pseudo-token, inserted by the parser instead of the lexer. + * + * @author TomyLobo + */ +public abstract class PseudoToken implements Identifiable { + private final int position; + + public PseudoToken(int position) { + this.position = position; + } + + @Override + public abstract char id(); + + @Override + public int getPosition() { + return position; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/parser/UnaryOperator.java b/src/main/java/com/sk89q/worldedit/internal/expression/parser/UnaryOperator.java similarity index 89% rename from src/main/java/com/sk89q/worldedit/expression/parser/UnaryOperator.java rename to src/main/java/com/sk89q/worldedit/internal/expression/parser/UnaryOperator.java index 8ab81853b..8c2c8ed0a 100644 --- a/src/main/java/com/sk89q/worldedit/expression/parser/UnaryOperator.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/parser/UnaryOperator.java @@ -1,50 +1,50 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.parser; - -import com.sk89q.worldedit.expression.lexer.tokens.OperatorToken; - -/** - * The parser uses this pseudo-token to mark operators as unary operators. - * - * @author TomyLobo - */ -public class UnaryOperator extends PseudoToken { - final String operator; - - public UnaryOperator(OperatorToken operatorToken) { - this(operatorToken.getPosition(), operatorToken.operator); - } - - public UnaryOperator(int position, String operator) { - super(position); - this.operator = operator; - } - - @Override - public char id() { - return 'p'; - } - - @Override - public String toString() { - return "UnaryOperator(" + operator + ")"; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.parser; + +import com.sk89q.worldedit.internal.expression.lexer.tokens.OperatorToken; + +/** + * The parser uses this pseudo-token to mark operators as unary operators. + * + * @author TomyLobo + */ +public class UnaryOperator extends PseudoToken { + final String operator; + + public UnaryOperator(OperatorToken operatorToken) { + this(operatorToken.getPosition(), operatorToken.operator); + } + + public UnaryOperator(int position, String operator) { + super(position); + this.operator = operator; + } + + @Override + public char id() { + return 'p'; + } + + @Override + public String toString() { + return "UnaryOperator(" + operator + ")"; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/parser/UnboundVariable.java b/src/main/java/com/sk89q/worldedit/internal/expression/parser/UnboundVariable.java similarity index 83% rename from src/main/java/com/sk89q/worldedit/expression/parser/UnboundVariable.java rename to src/main/java/com/sk89q/worldedit/internal/expression/parser/UnboundVariable.java index 13495c3f5..5a096dd23 100644 --- a/src/main/java/com/sk89q/worldedit/expression/parser/UnboundVariable.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/parser/UnboundVariable.java @@ -1,61 +1,61 @@ -package com.sk89q.worldedit.expression.parser; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.runtime.EvaluationException; -import com.sk89q.worldedit.expression.runtime.LValue; -import com.sk89q.worldedit.expression.runtime.RValue; - -public class UnboundVariable extends PseudoToken implements LValue { - public final String name; - - public UnboundVariable(int position, String name) { - super(position); - this.name = name; - // TODO Auto-generated constructor stub - } - - @Override - public char id() { - // TODO Auto-generated method stub - return 'V'; - } - - @Override - public String toString() { - return "UnboundVariable(" + name + ")"; - } - - @Override - public double getValue() throws EvaluationException { - throw new EvaluationException(getPosition(), "Tried to evaluate unbound variable!"); - } - - @Override - public LValue optimize() throws EvaluationException { - throw new EvaluationException(getPosition(), "Tried to optimize unbound variable!"); - } - - @Override - public double assign(double value) throws EvaluationException { - throw new EvaluationException(getPosition(), "Tried to assign unbound variable!"); - } - - public RValue bind(Expression expression, boolean isLValue) throws ParserException { - final RValue variable = expression.getVariable(name, isLValue); - if (variable == null) { - throw new ParserException(getPosition(), "Variable '" + name + "' not found"); - } - - return variable; - } - - @Override - public LValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - final RValue variable = expression.getVariable(name, preferLValue); - if (variable == null) { - throw new ParserException(getPosition(), "Variable '" + name + "' not found"); - } - - return (LValue) variable; - } -} +package com.sk89q.worldedit.internal.expression.parser; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; +import com.sk89q.worldedit.internal.expression.runtime.LValue; +import com.sk89q.worldedit.internal.expression.runtime.RValue; + +public class UnboundVariable extends PseudoToken implements LValue { + public final String name; + + public UnboundVariable(int position, String name) { + super(position); + this.name = name; + // TODO Auto-generated constructor stub + } + + @Override + public char id() { + // TODO Auto-generated method stub + return 'V'; + } + + @Override + public String toString() { + return "UnboundVariable(" + name + ")"; + } + + @Override + public double getValue() throws EvaluationException { + throw new EvaluationException(getPosition(), "Tried to evaluate unbound variable!"); + } + + @Override + public LValue optimize() throws EvaluationException { + throw new EvaluationException(getPosition(), "Tried to optimize unbound variable!"); + } + + @Override + public double assign(double value) throws EvaluationException { + throw new EvaluationException(getPosition(), "Tried to assign unbound variable!"); + } + + public RValue bind(Expression expression, boolean isLValue) throws ParserException { + final RValue variable = expression.getVariable(name, isLValue); + if (variable == null) { + throw new ParserException(getPosition(), "Variable '" + name + "' not found"); + } + + return variable; + } + + @Override + public LValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + final RValue variable = expression.getVariable(name, preferLValue); + if (variable == null) { + throw new ParserException(getPosition(), "Variable '" + name + "' not found"); + } + + return (LValue) variable; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Break.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Break.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Break.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Break.java index 2bbfba89e..77c333cf5 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Break.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Break.java @@ -1,50 +1,50 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -/** - * A break or continue statement. - * - * @author TomyLobo - */ -public class Break extends Node { - boolean doContinue; - - public Break(int position, boolean doContinue) { - super(position); - - this.doContinue = doContinue; - } - - @Override - public double getValue() throws EvaluationException { - throw new BreakException(doContinue); - } - - @Override - public char id() { - return 'b'; - } - - @Override - public String toString() { - return doContinue ? "continue" : "break"; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +/** + * A break or continue statement. + * + * @author TomyLobo + */ +public class Break extends Node { + boolean doContinue; + + public Break(int position, boolean doContinue) { + super(position); + + this.doContinue = doContinue; + } + + @Override + public double getValue() throws EvaluationException { + throw new BreakException(doContinue); + } + + @Override + public char id() { + return 'b'; + } + + @Override + public String toString() { + return doContinue ? "continue" : "break"; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/BreakException.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/BreakException.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/expression/runtime/BreakException.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/BreakException.java index b96ec907d..cc7fe5554 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/BreakException.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/BreakException.java @@ -1,38 +1,38 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -/** - * Thrown when a break or continue is encountered. - * Loop constructs catch this exception. - * - * @author TomyLobo - */ -public class BreakException extends EvaluationException { - private static final long serialVersionUID = 1L; - - final boolean doContinue; - - public BreakException(boolean doContinue) { - super(-1, doContinue ? "'continue' encountered outside a loop" : "'break' encountered outside a loop"); - - this.doContinue = doContinue; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +/** + * Thrown when a break or continue is encountered. + * Loop constructs catch this exception. + * + * @author TomyLobo + */ +public class BreakException extends EvaluationException { + private static final long serialVersionUID = 1L; + + final boolean doContinue; + + public BreakException(boolean doContinue) { + super(-1, doContinue ? "'continue' encountered outside a loop" : "'break' encountered outside a loop"); + + this.doContinue = doContinue; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Conditional.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Conditional.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Conditional.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Conditional.java index 89c13d3de..b2a723b9b 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Conditional.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Conditional.java @@ -1,93 +1,93 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * An if/else statement or a ternary operator. - * - * @author TomyLobo - */ -public class Conditional extends Node { - private RValue condition; - private RValue truePart; - private RValue falsePart; - - public Conditional(int position, RValue condition, RValue truePart, RValue falsePart) { - super(position); - - this.condition = condition; - this.truePart = truePart; - this.falsePart = falsePart; - } - - @Override - public double getValue() throws EvaluationException { - if (condition.getValue() > 0.0) { - return truePart.getValue(); - } else { - return falsePart == null ? 0.0 : falsePart.getValue(); - } - } - - @Override - public char id() { - return 'I'; - } - - @Override - public String toString() { - if (falsePart == null) { - return "if (" + condition + ") { " + truePart + " }"; - } else if (truePart instanceof Sequence || falsePart instanceof Sequence) { - return "if (" + condition + ") { " + truePart + " } else { " + falsePart + " }"; - } else { - return "(" + condition + ") ? (" + truePart + ") : (" + falsePart + ")"; - } - } - - @Override - public RValue optimize() throws EvaluationException { - final RValue newCondition = condition.optimize(); - - if (newCondition instanceof Constant) { - if (newCondition.getValue() > 0) { - return truePart.optimize(); - } else { - return falsePart == null ? new Constant(getPosition(), 0.0) : falsePart.optimize(); - } - } - - return new Conditional(getPosition(), newCondition, truePart.optimize(), falsePart == null ? null : falsePart.optimize()); - } - - @Override - public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - condition = condition.bindVariables(expression, false); - truePart = truePart.bindVariables(expression, false); - if (falsePart != null) { - falsePart = falsePart.bindVariables(expression, false); - } - - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * An if/else statement or a ternary operator. + * + * @author TomyLobo + */ +public class Conditional extends Node { + private RValue condition; + private RValue truePart; + private RValue falsePart; + + public Conditional(int position, RValue condition, RValue truePart, RValue falsePart) { + super(position); + + this.condition = condition; + this.truePart = truePart; + this.falsePart = falsePart; + } + + @Override + public double getValue() throws EvaluationException { + if (condition.getValue() > 0.0) { + return truePart.getValue(); + } else { + return falsePart == null ? 0.0 : falsePart.getValue(); + } + } + + @Override + public char id() { + return 'I'; + } + + @Override + public String toString() { + if (falsePart == null) { + return "if (" + condition + ") { " + truePart + " }"; + } else if (truePart instanceof Sequence || falsePart instanceof Sequence) { + return "if (" + condition + ") { " + truePart + " } else { " + falsePart + " }"; + } else { + return "(" + condition + ") ? (" + truePart + ") : (" + falsePart + ")"; + } + } + + @Override + public RValue optimize() throws EvaluationException { + final RValue newCondition = condition.optimize(); + + if (newCondition instanceof Constant) { + if (newCondition.getValue() > 0) { + return truePart.optimize(); + } else { + return falsePart == null ? new Constant(getPosition(), 0.0) : falsePart.optimize(); + } + } + + return new Conditional(getPosition(), newCondition, truePart.optimize(), falsePart == null ? null : falsePart.optimize()); + } + + @Override + public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + condition = condition.bindVariables(expression, false); + truePart = truePart.bindVariables(expression, false); + if (falsePart != null) { + falsePart = falsePart.bindVariables(expression, false); + } + + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Constant.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Constant.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Constant.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Constant.java index c351008d3..2de11f076 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Constant.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Constant.java @@ -1,49 +1,49 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -/** - * A constant. - * - * @author TomyLobo - */ -public final class Constant extends Node { - private final double value; - - public Constant(int position, double value) { - super(position); - this.value = value; - } - - @Override - public double getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - @Override - public char id() { - return 'c'; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +/** + * A constant. + * + * @author TomyLobo + */ +public final class Constant extends Node { + private final double value; + + public Constant(int position, double value) { + super(position); + this.value = value; + } + + @Override + public double getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @Override + public char id() { + return 'c'; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/EvaluationException.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/EvaluationException.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/expression/runtime/EvaluationException.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/EvaluationException.java index 22b4aab04..d5c125fb9 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/EvaluationException.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/EvaluationException.java @@ -1,51 +1,51 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.expression.ExpressionException; - -/** - * Thrown when there's a problem during expression evaluation. - * - * @author TomyLobo - */ -public class EvaluationException extends ExpressionException { - private static final long serialVersionUID = 1L; - - public EvaluationException(int position) { - super(position, getPrefix(position)); - } - - public EvaluationException(int position, String message, Throwable cause) { - super(position, getPrefix(position) + ": " + message, cause); - } - - public EvaluationException(int position, String message) { - super(position, getPrefix(position) + ": " + message); - } - - public EvaluationException(int position, Throwable cause) { - super(position, getPrefix(position), cause); - } - - private static String getPrefix(int position) { - return position < 0 ? "Evaluation error" : ("Evaluation error at " + (position + 1)); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import com.sk89q.worldedit.internal.expression.ExpressionException; + +/** + * Thrown when there's a problem during expression evaluation. + * + * @author TomyLobo + */ +public class EvaluationException extends ExpressionException { + private static final long serialVersionUID = 1L; + + public EvaluationException(int position) { + super(position, getPrefix(position)); + } + + public EvaluationException(int position, String message, Throwable cause) { + super(position, getPrefix(position) + ": " + message, cause); + } + + public EvaluationException(int position, String message) { + super(position, getPrefix(position) + ": " + message); + } + + public EvaluationException(int position, Throwable cause) { + super(position, getPrefix(position), cause); + } + + private static String getPrefix(int position) { + return position < 0 ? "Evaluation error" : ("Evaluation error at " + (position + 1)); + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/ExpressionEnvironment.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ExpressionEnvironment.java similarity index 76% rename from src/main/java/com/sk89q/worldedit/expression/runtime/ExpressionEnvironment.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/ExpressionEnvironment.java index 5ac316834..4e7348d01 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/ExpressionEnvironment.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ExpressionEnvironment.java @@ -1,16 +1,13 @@ -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.BlockVector; -import com.sk89q.worldedit.Vector; - -/** - * Represents a way to access blocks in a world. Has to accept non-rounded coordinates. - */ -public interface ExpressionEnvironment { - int getBlockType(double x, double y, double z); - int getBlockData(double x, double y, double z); - int getBlockTypeAbs(double x, double y, double z); - int getBlockDataAbs(double x, double y, double z); - int getBlockTypeRel(double x, double y, double z); - int getBlockDataRel(double x, double y, double z); -} +package com.sk89q.worldedit.internal.expression.runtime; + +/** + * Represents a way to access blocks in a world. Has to accept non-rounded coordinates. + */ +public interface ExpressionEnvironment { + int getBlockType(double x, double y, double z); + int getBlockData(double x, double y, double z); + int getBlockTypeAbs(double x, double y, double z); + int getBlockDataAbs(double x, double y, double z); + int getBlockTypeRel(double x, double y, double z); + int getBlockDataRel(double x, double y, double z); +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/For.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/For.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/expression/runtime/For.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/For.java index 4164fd3a3..3257bf3de 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/For.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/For.java @@ -1,104 +1,104 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * A Java/C-style for loop. - * - * @author TomyLobo - */ -public class For extends Node { - RValue init; - RValue condition; - RValue increment; - RValue body; - - public For(int position, RValue init, RValue condition, RValue increment, RValue body) { - super(position); - - this.init = init; - this.condition = condition; - this.increment = increment; - this.body = body; - } - - @Override - public double getValue() throws EvaluationException { - int iterations = 0; - double ret = 0.0; - - for (init.getValue(); condition.getValue() > 0; increment.getValue()) { - if (iterations > 256) { - throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations."); - } - ++iterations; - - try { - ret = body.getValue(); - } catch (BreakException e) { - if (e.doContinue) { - //noinspection UnnecessaryContinue - continue; - } else { - break; - } - } - } - - return ret; - } - - @Override - public char id() { - return 'F'; - } - - @Override - public String toString() { - return "for (" + init + "; " + condition + "; " + increment + ") { " + body + " }"; - } - - @Override - public RValue optimize() throws EvaluationException { - final RValue newCondition = condition.optimize(); - - if (newCondition instanceof Constant && newCondition.getValue() <= 0) { - // If the condition is always false, the loop can be flattened. - // So we run the init part and then return 0.0. - return new Sequence(getPosition(), init, new Constant(getPosition(), 0.0)).optimize(); - } - - //return new Sequence(getPosition(), init.optimize(), new While(getPosition(), condition, new Sequence(getPosition(), body, increment), false)).optimize(); - return new For(getPosition(), init.optimize(), newCondition, increment.optimize(), body.optimize()); - } - - @Override - public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - init = init.bindVariables(expression, false); - condition = condition.bindVariables(expression, false); - increment = increment.bindVariables(expression, false); - body = body.bindVariables(expression, false); - - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * A Java/C-style for loop. + * + * @author TomyLobo + */ +public class For extends Node { + RValue init; + RValue condition; + RValue increment; + RValue body; + + public For(int position, RValue init, RValue condition, RValue increment, RValue body) { + super(position); + + this.init = init; + this.condition = condition; + this.increment = increment; + this.body = body; + } + + @Override + public double getValue() throws EvaluationException { + int iterations = 0; + double ret = 0.0; + + for (init.getValue(); condition.getValue() > 0; increment.getValue()) { + if (iterations > 256) { + throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations."); + } + ++iterations; + + try { + ret = body.getValue(); + } catch (BreakException e) { + if (e.doContinue) { + //noinspection UnnecessaryContinue + continue; + } else { + break; + } + } + } + + return ret; + } + + @Override + public char id() { + return 'F'; + } + + @Override + public String toString() { + return "for (" + init + "; " + condition + "; " + increment + ") { " + body + " }"; + } + + @Override + public RValue optimize() throws EvaluationException { + final RValue newCondition = condition.optimize(); + + if (newCondition instanceof Constant && newCondition.getValue() <= 0) { + // If the condition is always false, the loop can be flattened. + // So we run the init part and then return 0.0. + return new Sequence(getPosition(), init, new Constant(getPosition(), 0.0)).optimize(); + } + + //return new Sequence(getPosition(), init.optimize(), new While(getPosition(), condition, new Sequence(getPosition(), body, increment), false)).optimize(); + return new For(getPosition(), init.optimize(), newCondition, increment.optimize(), body.optimize()); + } + + @Override + public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + init = init.bindVariables(expression, false); + condition = condition.bindVariables(expression, false); + increment = increment.bindVariables(expression, false); + body = body.bindVariables(expression, false); + + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Function.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Function.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Function.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Function.java index f4cb56719..ab656e5fd 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Function.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Function.java @@ -1,123 +1,123 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * Wrapper for a Java method and its arguments (other Nodes) - * - * @author TomyLobo - */ -public class Function extends Node { - /** - * Add this annotation on functions that don't always return the same value - * for the same inputs and on functions with side-effects. - */ - @Retention(RetentionPolicy.RUNTIME) - public @interface Dynamic { } - - final Method method; - final RValue[] args; - - Function(int position, Method method, RValue... args) { - super(position); - this.method = method; - this.args = args; - } - - @Override - public final double getValue() throws EvaluationException { - return invokeMethod(method, args); - } - - protected static final double invokeMethod(Method method, Object[] args) throws EvaluationException { - try { - return (Double) method.invoke(null, args); - } catch (InvocationTargetException e) { - if (e.getTargetException() instanceof EvaluationException) { - throw (EvaluationException) e.getTargetException(); - } - throw new EvaluationException(-1, "Exception caught while evaluating expression", e.getTargetException()); - } catch (IllegalAccessException e) { - throw new EvaluationException(-1, "Internal error while evaluating expression", e); - } - } - - @Override - public String toString() { - final StringBuilder ret = new StringBuilder(method.getName()).append('('); - boolean first = true; - for (Object obj : args) { - if (!first) { - ret.append(", "); - } - first = false; - ret.append(obj); - } - return ret.append(')').toString(); - } - - @Override - public char id() { - return 'f'; - } - - @Override - public RValue optimize() throws EvaluationException { - final RValue[] optimizedArgs = new RValue[args.length]; - boolean optimizable = !method.isAnnotationPresent(Dynamic.class); - int position = getPosition(); - for (int i = 0; i < args.length; ++i) { - final RValue optimized = optimizedArgs[i] = args[i].optimize(); - - if (!(optimized instanceof Constant)) { - optimizable = false; - } - - if (optimized.getPosition() < position) { - position = optimized.getPosition(); - } - } - - if (optimizable) { - return new Constant(position, invokeMethod(method, optimizedArgs)); - } else { - return new Function(position, method, optimizedArgs); - } - } - - @Override - public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - final Class[] parameters = method.getParameterTypes(); - for (int i = 0; i < args.length; ++i) { - final boolean argumentPrefersLValue = LValue.class.isAssignableFrom(parameters[i]); - args[i] = args[i].bindVariables(expression, argumentPrefersLValue); - } - - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * Wrapper for a Java method and its arguments (other Nodes) + * + * @author TomyLobo + */ +public class Function extends Node { + /** + * Add this annotation on functions that don't always return the same value + * for the same inputs and on functions with side-effects. + */ + @Retention(RetentionPolicy.RUNTIME) + public @interface Dynamic { } + + final Method method; + final RValue[] args; + + Function(int position, Method method, RValue... args) { + super(position); + this.method = method; + this.args = args; + } + + @Override + public final double getValue() throws EvaluationException { + return invokeMethod(method, args); + } + + protected static final double invokeMethod(Method method, Object[] args) throws EvaluationException { + try { + return (Double) method.invoke(null, args); + } catch (InvocationTargetException e) { + if (e.getTargetException() instanceof EvaluationException) { + throw (EvaluationException) e.getTargetException(); + } + throw new EvaluationException(-1, "Exception caught while evaluating expression", e.getTargetException()); + } catch (IllegalAccessException e) { + throw new EvaluationException(-1, "Internal error while evaluating expression", e); + } + } + + @Override + public String toString() { + final StringBuilder ret = new StringBuilder(method.getName()).append('('); + boolean first = true; + for (Object obj : args) { + if (!first) { + ret.append(", "); + } + first = false; + ret.append(obj); + } + return ret.append(')').toString(); + } + + @Override + public char id() { + return 'f'; + } + + @Override + public RValue optimize() throws EvaluationException { + final RValue[] optimizedArgs = new RValue[args.length]; + boolean optimizable = !method.isAnnotationPresent(Dynamic.class); + int position = getPosition(); + for (int i = 0; i < args.length; ++i) { + final RValue optimized = optimizedArgs[i] = args[i].optimize(); + + if (!(optimized instanceof Constant)) { + optimizable = false; + } + + if (optimized.getPosition() < position) { + position = optimized.getPosition(); + } + } + + if (optimizable) { + return new Constant(position, invokeMethod(method, optimizedArgs)); + } else { + return new Function(position, method, optimizedArgs); + } + } + + @Override + public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + final Class[] parameters = method.getParameterTypes(); + for (int i = 0; i < args.length; ++i) { + final boolean argumentPrefersLValue = LValue.class.isAssignableFrom(parameters[i]); + args[i] = args[i].bindVariables(expression, argumentPrefersLValue); + } + + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Functions.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Functions.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Functions.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Functions.java index 51d1a2f36..637d2a2d5 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Functions.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Functions.java @@ -1,439 +1,439 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.runtime.Function.Dynamic; - -/** - * Contains all functions that can be used in expressions. - * - * @author TomyLobo - */ -@SuppressWarnings("UnusedDeclaration") -public final class Functions { - private static class Overload { - private final Method method; - private final int mask; - private final boolean isSetter; - - public Overload(Method method) throws IllegalArgumentException { - this.method = method; - - boolean isSetter = false; - int accum = 0; - Class[] parameters = method.getParameterTypes(); - for (Class parameter : parameters) { - if (isSetter) { - throw new IllegalArgumentException("Method takes arguments that can't be cast to RValue."); - } - - if (double.class.equals(parameter)) { - isSetter = true; - continue; - } - - if (!RValue.class.isAssignableFrom(parameter)) { - throw new IllegalArgumentException("Method takes arguments that can't be cast to RValue."); - } - - accum <<= 2; - - if (LValue.class.isAssignableFrom(parameter)) { - accum |= 3; - } else { - accum |= 1; - } - } - mask = accum; - this.isSetter = isSetter; - } - - public boolean matches(boolean isSetter, RValue... args) { - if (this.isSetter != isSetter) { - return false; - } - - if (this.method.getParameterTypes().length != args.length) { // TODO: optimize - return false; - } - - int accum = 0; - for (RValue argument : args) { - accum <<= 2; - - if (argument instanceof LValue) { - accum |= 3; - } else { - accum |= 1; - } - } - - return (accum & mask) == mask; - } - } - - public static Function getFunction(int position, String name, RValue... args) throws NoSuchMethodException { - final Method getter = getMethod(name, false, args); - try { - Method setter = getMethod(name, true, args); - return new LValueFunction(position, getter, setter, args); - } catch (NoSuchMethodException e) { - return new Function(position, getter, args); - } - } - - private static Method getMethod(String name, boolean isSetter, RValue... args) throws NoSuchMethodException { - final List overloads = functions.get(name); - if (overloads != null) { - for (Overload overload : overloads) { - if (overload.matches(isSetter, args)) { - return overload.method; - } - } - } - - throw new NoSuchMethodException(); // TODO: return null (check for side-effects first) - } - - private static final Map> functions = new HashMap>(); - static { - for (Method method : Functions.class.getMethods()) { - try { - addFunction(method); - } catch (IllegalArgumentException ignored) { } - } - } - - - public static void addFunction(Method method) throws IllegalArgumentException { - final String methodName = method.getName(); - - Overload overload = new Overload(method); - - List overloads = functions.get(methodName); - if (overloads == null) { - functions.put(methodName, overloads = new ArrayList()); - } - - overloads.add(overload); - } - - - public static double sin(RValue x) throws EvaluationException { - return Math.sin(x.getValue()); - } - - public static double cos(RValue x) throws EvaluationException { - return Math.cos(x.getValue()); - } - - public static double tan(RValue x) throws EvaluationException { - return Math.tan(x.getValue()); - } - - - public static double asin(RValue x) throws EvaluationException { - return Math.asin(x.getValue()); - } - - public static double acos(RValue x) throws EvaluationException { - return Math.acos(x.getValue()); - } - - public static double atan(RValue x) throws EvaluationException { - return Math.atan(x.getValue()); - } - - public static double atan2(RValue y, RValue x) throws EvaluationException { - return Math.atan2(y.getValue(), x.getValue()); - } - - - public static double sinh(RValue x) throws EvaluationException { - return Math.sinh(x.getValue()); - } - - public static double cosh(RValue x) throws EvaluationException { - return Math.cosh(x.getValue()); - } - - public static double tanh(RValue x) throws EvaluationException { - return Math.tanh(x.getValue()); - } - - - public static double sqrt(RValue x) throws EvaluationException { - return Math.sqrt(x.getValue()); - } - - public static double cbrt(RValue x) throws EvaluationException { - return Math.cbrt(x.getValue()); - } - - - public static double abs(RValue x) throws EvaluationException { - return Math.abs(x.getValue()); - } - - public static double min(RValue a, RValue b) throws EvaluationException { - return Math.min(a.getValue(), b.getValue()); - } - - public static double min(RValue a, RValue b, RValue c) throws EvaluationException { - return Math.min(a.getValue(), Math.min(b.getValue(), c.getValue())); - } - - public static double max(RValue a, RValue b) throws EvaluationException { - return Math.max(a.getValue(), b.getValue()); - } - - public static double max(RValue a, RValue b, RValue c) throws EvaluationException { - return Math.max(a.getValue(), Math.max(b.getValue(), c.getValue())); - } - - - public static double ceil(RValue x) throws EvaluationException { - return Math.ceil(x.getValue()); - } - - public static double floor(RValue x) throws EvaluationException { - return Math.floor(x.getValue()); - } - - public static double rint(RValue x) throws EvaluationException { - return Math.rint(x.getValue()); - } - - public static double round(RValue x) throws EvaluationException { - return Math.round(x.getValue()); - } - - - public static double exp(RValue x) throws EvaluationException { - return Math.exp(x.getValue()); - } - - public static double ln(RValue x) throws EvaluationException { - return Math.log(x.getValue()); - } - - public static double log(RValue x) throws EvaluationException { - return Math.log(x.getValue()); - } - - public static double log10(RValue x) throws EvaluationException { - return Math.log10(x.getValue()); - } - - - public static double rotate(LValue x, LValue y, RValue angle) throws EvaluationException { - final double f = angle.getValue(); - - final double cosF = Math.cos(f); - final double sinF = Math.sin(f); - - final double xOld = x.getValue(); - final double yOld = y.getValue(); - - x.assign(xOld * cosF - yOld * sinF); - y.assign(xOld * sinF + yOld * cosF); - - return 0.0; - } - - public static double swap(LValue x, LValue y) throws EvaluationException { - final double tmp = x.getValue(); - - x.assign(y.getValue()); - y.assign(tmp); - - return 0.0; - } - - - private static final Map gmegabuf = new HashMap(); - private final Map megabuf = new HashMap(); - - private static double[] getSubBuffer(Map megabuf, Integer key) { - double[] ret = megabuf.get(key); - if (ret == null) { - megabuf.put(key, ret = new double[1024]); - } - return ret; - } - - private static double getBufferItem(final Map megabuf, final int index) { - return getSubBuffer(megabuf, index & ~1023)[index & 1023]; - } - - private static double setBufferItem(final Map megabuf, final int index, double value) { - return getSubBuffer(megabuf, index & ~1023)[index & 1023] = value; - } - - @Dynamic - public static double gmegabuf(RValue index) throws EvaluationException { - return getBufferItem(gmegabuf, (int) index.getValue()); - } - - @Dynamic - public static double gmegabuf(RValue index, double value) throws EvaluationException { - return setBufferItem(gmegabuf, (int) index.getValue(), value); - } - - @Dynamic - public static double megabuf(RValue index) throws EvaluationException { - return getBufferItem(Expression.getInstance().getFunctions().megabuf, (int) index.getValue()); - } - - @Dynamic - public static double megabuf(RValue index, double value) throws EvaluationException { - return setBufferItem(Expression.getInstance().getFunctions().megabuf, (int) index.getValue(), value); - } - - @Dynamic - public static double closest(RValue x, RValue y, RValue z, RValue index, RValue count, RValue stride) throws EvaluationException { - return findClosest( - Expression.getInstance().getFunctions().megabuf, - x.getValue(), - y.getValue(), - z.getValue(), - (int) index.getValue(), - (int) count.getValue(), - (int) stride.getValue() - ); - } - - @Dynamic - public static double gclosest(RValue x, RValue y, RValue z, RValue index, RValue count, RValue stride) throws EvaluationException { - return findClosest( - gmegabuf, - x.getValue(), - y.getValue(), - z.getValue(), - (int) index.getValue(), - (int) count.getValue(), - (int) stride.getValue() - ); - } - - private static double findClosest(Map megabuf, double x, double y, double z, int index, int count, int stride) { - int closestIndex = -1; - double minDistanceSquared = Double.MAX_VALUE; - - for (int i = 0; i < count; ++i) { - double currentX = getBufferItem(megabuf, index+0) - x; - double currentY = getBufferItem(megabuf, index+1) - y; - double currentZ = getBufferItem(megabuf, index+2) - z; - - double currentDistanceSquared = currentX*currentX + currentY*currentY + currentZ*currentZ; - - if (currentDistanceSquared < minDistanceSquared) { - minDistanceSquared = currentDistanceSquared; - closestIndex = index; - } - - index += stride; - } - - return closestIndex; - } - - - private static final Random random = new Random(); - - @Dynamic - public static double random() { - return random.nextDouble(); - } - - @Dynamic - public static double randint(RValue max) throws EvaluationException { - return random.nextInt((int) Math.floor(max.getValue())); - } - - - private static double queryInternal(RValue type, RValue data, double typeId, double dataValue) throws EvaluationException { - // Compare to input values and determine return value - final double ret = (typeId == type.getValue() && dataValue == data.getValue()) ? 1.0 : 0.0; - - if (type instanceof LValue) { - ((LValue) type).assign(typeId); - } - - if (data instanceof LValue) { - ((LValue) data).assign(dataValue); - } - - return ret; - } - - @Dynamic - public static double query(RValue x, RValue y, RValue z, RValue type, RValue data) throws EvaluationException { - final double xp = x.getValue(); - final double yp = y.getValue(); - final double zp = z.getValue(); - - final ExpressionEnvironment environment = Expression.getInstance().getEnvironment(); - - // Read values from world - final double typeId = environment.getBlockType(xp, yp, zp); - final double dataValue = environment.getBlockData(xp, yp, zp); - - return queryInternal(type, data, typeId, dataValue); - } - - @Dynamic - public static double queryAbs(RValue x, RValue y, RValue z, RValue type, RValue data) throws EvaluationException { - final double xp = x.getValue(); - final double yp = y.getValue(); - final double zp = z.getValue(); - - final ExpressionEnvironment environment = Expression.getInstance().getEnvironment(); - - // Read values from world - final double typeId = environment.getBlockTypeAbs(xp, yp, zp); - final double dataValue = environment.getBlockDataAbs(xp, yp, zp); - - return queryInternal(type, data, typeId, dataValue); - } - - @Dynamic - public static double queryRel(RValue x, RValue y, RValue z, RValue type, RValue data) throws EvaluationException { - final double xp = x.getValue(); - final double yp = y.getValue(); - final double zp = z.getValue(); - - final ExpressionEnvironment environment = Expression.getInstance().getEnvironment(); - - // Read values from world - final double typeId = environment.getBlockTypeRel(xp, yp, zp); - final double dataValue = environment.getBlockDataRel(xp, yp, zp); - - return queryInternal(type, data, typeId, dataValue); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.runtime.Function.Dynamic; + +/** + * Contains all functions that can be used in expressions. + * + * @author TomyLobo + */ +@SuppressWarnings("UnusedDeclaration") +public final class Functions { + private static class Overload { + private final Method method; + private final int mask; + private final boolean isSetter; + + public Overload(Method method) throws IllegalArgumentException { + this.method = method; + + boolean isSetter = false; + int accum = 0; + Class[] parameters = method.getParameterTypes(); + for (Class parameter : parameters) { + if (isSetter) { + throw new IllegalArgumentException("Method takes arguments that can't be cast to RValue."); + } + + if (double.class.equals(parameter)) { + isSetter = true; + continue; + } + + if (!RValue.class.isAssignableFrom(parameter)) { + throw new IllegalArgumentException("Method takes arguments that can't be cast to RValue."); + } + + accum <<= 2; + + if (LValue.class.isAssignableFrom(parameter)) { + accum |= 3; + } else { + accum |= 1; + } + } + mask = accum; + this.isSetter = isSetter; + } + + public boolean matches(boolean isSetter, RValue... args) { + if (this.isSetter != isSetter) { + return false; + } + + if (this.method.getParameterTypes().length != args.length) { // TODO: optimize + return false; + } + + int accum = 0; + for (RValue argument : args) { + accum <<= 2; + + if (argument instanceof LValue) { + accum |= 3; + } else { + accum |= 1; + } + } + + return (accum & mask) == mask; + } + } + + public static Function getFunction(int position, String name, RValue... args) throws NoSuchMethodException { + final Method getter = getMethod(name, false, args); + try { + Method setter = getMethod(name, true, args); + return new LValueFunction(position, getter, setter, args); + } catch (NoSuchMethodException e) { + return new Function(position, getter, args); + } + } + + private static Method getMethod(String name, boolean isSetter, RValue... args) throws NoSuchMethodException { + final List overloads = functions.get(name); + if (overloads != null) { + for (Overload overload : overloads) { + if (overload.matches(isSetter, args)) { + return overload.method; + } + } + } + + throw new NoSuchMethodException(); // TODO: return null (check for side-effects first) + } + + private static final Map> functions = new HashMap>(); + static { + for (Method method : Functions.class.getMethods()) { + try { + addFunction(method); + } catch (IllegalArgumentException ignored) { } + } + } + + + public static void addFunction(Method method) throws IllegalArgumentException { + final String methodName = method.getName(); + + Overload overload = new Overload(method); + + List overloads = functions.get(methodName); + if (overloads == null) { + functions.put(methodName, overloads = new ArrayList()); + } + + overloads.add(overload); + } + + + public static double sin(RValue x) throws EvaluationException { + return Math.sin(x.getValue()); + } + + public static double cos(RValue x) throws EvaluationException { + return Math.cos(x.getValue()); + } + + public static double tan(RValue x) throws EvaluationException { + return Math.tan(x.getValue()); + } + + + public static double asin(RValue x) throws EvaluationException { + return Math.asin(x.getValue()); + } + + public static double acos(RValue x) throws EvaluationException { + return Math.acos(x.getValue()); + } + + public static double atan(RValue x) throws EvaluationException { + return Math.atan(x.getValue()); + } + + public static double atan2(RValue y, RValue x) throws EvaluationException { + return Math.atan2(y.getValue(), x.getValue()); + } + + + public static double sinh(RValue x) throws EvaluationException { + return Math.sinh(x.getValue()); + } + + public static double cosh(RValue x) throws EvaluationException { + return Math.cosh(x.getValue()); + } + + public static double tanh(RValue x) throws EvaluationException { + return Math.tanh(x.getValue()); + } + + + public static double sqrt(RValue x) throws EvaluationException { + return Math.sqrt(x.getValue()); + } + + public static double cbrt(RValue x) throws EvaluationException { + return Math.cbrt(x.getValue()); + } + + + public static double abs(RValue x) throws EvaluationException { + return Math.abs(x.getValue()); + } + + public static double min(RValue a, RValue b) throws EvaluationException { + return Math.min(a.getValue(), b.getValue()); + } + + public static double min(RValue a, RValue b, RValue c) throws EvaluationException { + return Math.min(a.getValue(), Math.min(b.getValue(), c.getValue())); + } + + public static double max(RValue a, RValue b) throws EvaluationException { + return Math.max(a.getValue(), b.getValue()); + } + + public static double max(RValue a, RValue b, RValue c) throws EvaluationException { + return Math.max(a.getValue(), Math.max(b.getValue(), c.getValue())); + } + + + public static double ceil(RValue x) throws EvaluationException { + return Math.ceil(x.getValue()); + } + + public static double floor(RValue x) throws EvaluationException { + return Math.floor(x.getValue()); + } + + public static double rint(RValue x) throws EvaluationException { + return Math.rint(x.getValue()); + } + + public static double round(RValue x) throws EvaluationException { + return Math.round(x.getValue()); + } + + + public static double exp(RValue x) throws EvaluationException { + return Math.exp(x.getValue()); + } + + public static double ln(RValue x) throws EvaluationException { + return Math.log(x.getValue()); + } + + public static double log(RValue x) throws EvaluationException { + return Math.log(x.getValue()); + } + + public static double log10(RValue x) throws EvaluationException { + return Math.log10(x.getValue()); + } + + + public static double rotate(LValue x, LValue y, RValue angle) throws EvaluationException { + final double f = angle.getValue(); + + final double cosF = Math.cos(f); + final double sinF = Math.sin(f); + + final double xOld = x.getValue(); + final double yOld = y.getValue(); + + x.assign(xOld * cosF - yOld * sinF); + y.assign(xOld * sinF + yOld * cosF); + + return 0.0; + } + + public static double swap(LValue x, LValue y) throws EvaluationException { + final double tmp = x.getValue(); + + x.assign(y.getValue()); + y.assign(tmp); + + return 0.0; + } + + + private static final Map gmegabuf = new HashMap(); + private final Map megabuf = new HashMap(); + + private static double[] getSubBuffer(Map megabuf, Integer key) { + double[] ret = megabuf.get(key); + if (ret == null) { + megabuf.put(key, ret = new double[1024]); + } + return ret; + } + + private static double getBufferItem(final Map megabuf, final int index) { + return getSubBuffer(megabuf, index & ~1023)[index & 1023]; + } + + private static double setBufferItem(final Map megabuf, final int index, double value) { + return getSubBuffer(megabuf, index & ~1023)[index & 1023] = value; + } + + @Dynamic + public static double gmegabuf(RValue index) throws EvaluationException { + return getBufferItem(gmegabuf, (int) index.getValue()); + } + + @Dynamic + public static double gmegabuf(RValue index, double value) throws EvaluationException { + return setBufferItem(gmegabuf, (int) index.getValue(), value); + } + + @Dynamic + public static double megabuf(RValue index) throws EvaluationException { + return getBufferItem(Expression.getInstance().getFunctions().megabuf, (int) index.getValue()); + } + + @Dynamic + public static double megabuf(RValue index, double value) throws EvaluationException { + return setBufferItem(Expression.getInstance().getFunctions().megabuf, (int) index.getValue(), value); + } + + @Dynamic + public static double closest(RValue x, RValue y, RValue z, RValue index, RValue count, RValue stride) throws EvaluationException { + return findClosest( + Expression.getInstance().getFunctions().megabuf, + x.getValue(), + y.getValue(), + z.getValue(), + (int) index.getValue(), + (int) count.getValue(), + (int) stride.getValue() + ); + } + + @Dynamic + public static double gclosest(RValue x, RValue y, RValue z, RValue index, RValue count, RValue stride) throws EvaluationException { + return findClosest( + gmegabuf, + x.getValue(), + y.getValue(), + z.getValue(), + (int) index.getValue(), + (int) count.getValue(), + (int) stride.getValue() + ); + } + + private static double findClosest(Map megabuf, double x, double y, double z, int index, int count, int stride) { + int closestIndex = -1; + double minDistanceSquared = Double.MAX_VALUE; + + for (int i = 0; i < count; ++i) { + double currentX = getBufferItem(megabuf, index+0) - x; + double currentY = getBufferItem(megabuf, index+1) - y; + double currentZ = getBufferItem(megabuf, index+2) - z; + + double currentDistanceSquared = currentX*currentX + currentY*currentY + currentZ*currentZ; + + if (currentDistanceSquared < minDistanceSquared) { + minDistanceSquared = currentDistanceSquared; + closestIndex = index; + } + + index += stride; + } + + return closestIndex; + } + + + private static final Random random = new Random(); + + @Dynamic + public static double random() { + return random.nextDouble(); + } + + @Dynamic + public static double randint(RValue max) throws EvaluationException { + return random.nextInt((int) Math.floor(max.getValue())); + } + + + private static double queryInternal(RValue type, RValue data, double typeId, double dataValue) throws EvaluationException { + // Compare to input values and determine return value + final double ret = (typeId == type.getValue() && dataValue == data.getValue()) ? 1.0 : 0.0; + + if (type instanceof LValue) { + ((LValue) type).assign(typeId); + } + + if (data instanceof LValue) { + ((LValue) data).assign(dataValue); + } + + return ret; + } + + @Dynamic + public static double query(RValue x, RValue y, RValue z, RValue type, RValue data) throws EvaluationException { + final double xp = x.getValue(); + final double yp = y.getValue(); + final double zp = z.getValue(); + + final ExpressionEnvironment environment = Expression.getInstance().getEnvironment(); + + // Read values from world + final double typeId = environment.getBlockType(xp, yp, zp); + final double dataValue = environment.getBlockData(xp, yp, zp); + + return queryInternal(type, data, typeId, dataValue); + } + + @Dynamic + public static double queryAbs(RValue x, RValue y, RValue z, RValue type, RValue data) throws EvaluationException { + final double xp = x.getValue(); + final double yp = y.getValue(); + final double zp = z.getValue(); + + final ExpressionEnvironment environment = Expression.getInstance().getEnvironment(); + + // Read values from world + final double typeId = environment.getBlockTypeAbs(xp, yp, zp); + final double dataValue = environment.getBlockDataAbs(xp, yp, zp); + + return queryInternal(type, data, typeId, dataValue); + } + + @Dynamic + public static double queryRel(RValue x, RValue y, RValue z, RValue type, RValue data) throws EvaluationException { + final double xp = x.getValue(); + final double yp = y.getValue(); + final double zp = z.getValue(); + + final ExpressionEnvironment environment = Expression.getInstance().getEnvironment(); + + // Read values from world + final double typeId = environment.getBlockTypeRel(xp, yp, zp); + final double dataValue = environment.getBlockDataRel(xp, yp, zp); + + return queryInternal(type, data, typeId, dataValue); + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/LValue.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/LValue.java similarity index 85% rename from src/main/java/com/sk89q/worldedit/expression/runtime/LValue.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/LValue.java index d909e7fb4..53adcc9f4 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/LValue.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/LValue.java @@ -1,36 +1,36 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * A value that can be used on the left side of an assignment. - * - * @author TomyLobo - */ -public interface LValue extends RValue { - public double assign(double value) throws EvaluationException; - - public LValue optimize() throws EvaluationException; - - public LValue bindVariables(Expression expression, boolean preferLValue) throws ParserException; -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * A value that can be used on the left side of an assignment. + * + * @author TomyLobo + */ +public interface LValue extends RValue { + public double assign(double value) throws EvaluationException; + + public LValue optimize() throws EvaluationException; + + public LValue bindVariables(Expression expression, boolean preferLValue) throws ParserException; +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/LValueFunction.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/LValueFunction.java similarity index 90% rename from src/main/java/com/sk89q/worldedit/expression/runtime/LValueFunction.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/LValueFunction.java index ce13fea7f..a9f678b2f 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/LValueFunction.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/LValueFunction.java @@ -1,76 +1,76 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import java.lang.reflect.Method; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * Wrapper for a pair of Java methods and their arguments (other Nodes), forming an LValue - * - * @author TomyLobo - */ -public class LValueFunction extends Function implements LValue { - private final Object[] setterArgs; - private final Method setter; - - LValueFunction(int position, Method getter, Method setter, RValue... args) { - super(position, getter, args); - assert (getter.isAnnotationPresent(Dynamic.class)); - - setterArgs = new Object[args.length + 1]; - System.arraycopy(args, 0, setterArgs, 0, args.length); - this.setter = setter; - } - - @Override - public char id() { - return 'l'; - } - - @Override - public double assign(double value) throws EvaluationException { - setterArgs[setterArgs.length - 1] = value; - return invokeMethod(setter, setterArgs); - } - - @Override - public LValue optimize() throws EvaluationException { - final RValue optimized = super.optimize(); - if (optimized == this) { - return this; - } - - if (optimized instanceof Function) { - return new LValueFunction(optimized.getPosition(), method, setter, ((Function) optimized).args); - } - - return (LValue) optimized; - } - - @Override - public LValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - super.bindVariables(expression, preferLValue); - - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import java.lang.reflect.Method; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * Wrapper for a pair of Java methods and their arguments (other Nodes), forming an LValue + * + * @author TomyLobo + */ +public class LValueFunction extends Function implements LValue { + private final Object[] setterArgs; + private final Method setter; + + LValueFunction(int position, Method getter, Method setter, RValue... args) { + super(position, getter, args); + assert (getter.isAnnotationPresent(Dynamic.class)); + + setterArgs = new Object[args.length + 1]; + System.arraycopy(args, 0, setterArgs, 0, args.length); + this.setter = setter; + } + + @Override + public char id() { + return 'l'; + } + + @Override + public double assign(double value) throws EvaluationException { + setterArgs[setterArgs.length - 1] = value; + return invokeMethod(setter, setterArgs); + } + + @Override + public LValue optimize() throws EvaluationException { + final RValue optimized = super.optimize(); + if (optimized == this) { + return this; + } + + if (optimized instanceof Function) { + return new LValueFunction(optimized.getPosition(), method, setter, ((Function) optimized).args); + } + + return (LValue) optimized; + } + + @Override + public LValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + super.bindVariables(expression, preferLValue); + + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Node.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Node.java similarity index 86% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Node.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Node.java index e0c7d184a..dd280756a 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Node.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Node.java @@ -1,53 +1,53 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * A node in the execution tree of an expression. - * - * @author TomyLobo - */ -public abstract class Node implements RValue { - private final int position; - - public Node(int position) { - this.position = position; - } - - @Override - public abstract String toString(); - - public RValue optimize() throws EvaluationException { - return this; - } - - @Override - public final int getPosition() { - return position; - } - - @Override - public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * A node in the execution tree of an expression. + * + * @author TomyLobo + */ +public abstract class Node implements RValue { + private final int position; + + public Node(int position) { + this.position = position; + } + + @Override + public abstract String toString(); + + public RValue optimize() throws EvaluationException { + return this; + } + + @Override + public final int getPosition() { + return position; + } + + @Override + public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Operators.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Operators.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Operators.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Operators.java index 3b3556d77..e8739043b 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Operators.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Operators.java @@ -1,225 +1,225 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -/** - * Contains all unary and binary operators. - * - * @author TomyLobo - */ -@SuppressWarnings("UnusedDeclaration") -public final class Operators { - public static Function getOperator(int position, String name, RValue lhs, RValue rhs) throws NoSuchMethodException { - if (lhs instanceof LValue) { - try { - return new Function(position, Operators.class.getMethod(name, LValue.class, RValue.class), lhs, rhs); - } catch (NoSuchMethodException ignored) { } - } - return new Function(position, Operators.class.getMethod(name, RValue.class, RValue.class), lhs, rhs); - } - - public static Function getOperator(int position, String name, RValue argument) throws NoSuchMethodException { - if (argument instanceof LValue) { - try { - return new Function(position, Operators.class.getMethod(name, LValue.class), argument); - } catch (NoSuchMethodException ignored) { } - } - return new Function(position, Operators.class.getMethod(name, RValue.class), argument); - } - - - public static double add(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() + rhs.getValue(); - } - - public static double sub(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() - rhs.getValue(); - } - - public static double mul(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() * rhs.getValue(); - } - - public static double div(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() / rhs.getValue(); - } - - public static double mod(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() % rhs.getValue(); - } - - public static double pow(RValue lhs, RValue rhs) throws EvaluationException { - return Math.pow(lhs.getValue(), rhs.getValue()); - } - - - public static double neg(RValue x) throws EvaluationException { - return -x.getValue(); - } - - public static double not(RValue x) throws EvaluationException { - return x.getValue() > 0.0 ? 0.0 : 1.0; - } - - public static double inv(RValue x) throws EvaluationException { - return ~(long) x.getValue(); - } - - - public static double lth(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() < rhs.getValue() ? 1.0 : 0.0; - } - - public static double gth(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() > rhs.getValue() ? 1.0 : 0.0; - } - - public static double leq(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() <= rhs.getValue() ? 1.0 : 0.0; - } - - public static double geq(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() >= rhs.getValue() ? 1.0 : 0.0; - } - - - public static double equ(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() == rhs.getValue() ? 1.0 : 0.0; - } - - public static double neq(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() != rhs.getValue() ? 1.0 : 0.0; - } - - public static double near(RValue lhs, RValue rhs) throws EvaluationException { - return almostEqual2sComplement(lhs.getValue(), rhs.getValue(), 450359963L) ? 1.0 : 0.0; - //return Math.abs(lhs.invoke() - rhs.invoke()) < 1e-7 ? 1.0 : 0.0; - } - - - public static double or(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() > 0.0 || rhs.getValue() > 0.0 ? 1.0 : 0.0; - } - - public static double and(RValue lhs, RValue rhs) throws EvaluationException { - return lhs.getValue() > 0.0 && rhs.getValue() > 0.0 ? 1.0 : 0.0; - } - - - public static double shl(RValue lhs, RValue rhs) throws EvaluationException { - return (long) lhs.getValue() << (long) rhs.getValue(); - } - - public static double shr(RValue lhs, RValue rhs) throws EvaluationException { - return (long) lhs.getValue() >> (long) rhs.getValue(); - } - - - public static double ass(LValue lhs, RValue rhs) throws EvaluationException { - return lhs.assign(rhs.getValue()); - } - - public static double aadd(LValue lhs, RValue rhs) throws EvaluationException { - return lhs.assign(lhs.getValue() + rhs.getValue()); - } - - public static double asub(LValue lhs, RValue rhs) throws EvaluationException { - return lhs.assign(lhs.getValue() - rhs.getValue()); - } - - public static double amul(LValue lhs, RValue rhs) throws EvaluationException { - return lhs.assign(lhs.getValue() * rhs.getValue()); - } - - public static double adiv(LValue lhs, RValue rhs) throws EvaluationException { - return lhs.assign(lhs.getValue() / rhs.getValue()); - } - - public static double amod(LValue lhs, RValue rhs) throws EvaluationException { - return lhs.assign(lhs.getValue() % rhs.getValue()); - } - - public static double aexp(LValue lhs, RValue rhs) throws EvaluationException { - return lhs.assign(Math.pow(lhs.getValue(), rhs.getValue())); - } - - - public static double inc(LValue x) throws EvaluationException { - return x.assign(x.getValue() + 1); - } - - public static double dec(LValue x) throws EvaluationException { - return x.assign(x.getValue() - 1); - } - - public static double postinc(LValue x) throws EvaluationException { - final double oldValue = x.getValue(); - x.assign(oldValue + 1); - return oldValue; - } - - public static double postdec(LValue x) throws EvaluationException { - final double oldValue = x.getValue(); - x.assign(oldValue - 1); - return oldValue; - } - - - private static final double[] factorials = new double[171]; - static { - double accum = 1; - factorials[0] = 1; - for (int i = 1; i < factorials.length; ++i) { - factorials[i] = accum *= i; - } - } - - public static double fac(RValue x) throws EvaluationException { - final int n = (int) x.getValue(); - - if (n < 0) { - return 0; - } - - if (n >= factorials.length) { - return Double.POSITIVE_INFINITY; - } - - return factorials[n]; - } - - // Usable AlmostEqual function, based on http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm - private static boolean almostEqual2sComplement(double A, double B, long maxUlps) { - // Make sure maxUlps is non-negative and small enough that the - // default NAN won't compare as equal to anything. - //assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); // this is for floats, not doubles - - long aLong = Double.doubleToRawLongBits(A); - // Make aLong lexicographically ordered as a twos-complement long - if (aLong < 0) aLong = 0x8000000000000000L - aLong; - - long bLong = Double.doubleToRawLongBits(B); - // Make bLong lexicographically ordered as a twos-complement long - if (bLong < 0) bLong = 0x8000000000000000L - bLong; - - final long longDiff = Math.abs(aLong - bLong); - return longDiff <= maxUlps; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +/** + * Contains all unary and binary operators. + * + * @author TomyLobo + */ +@SuppressWarnings("UnusedDeclaration") +public final class Operators { + public static Function getOperator(int position, String name, RValue lhs, RValue rhs) throws NoSuchMethodException { + if (lhs instanceof LValue) { + try { + return new Function(position, Operators.class.getMethod(name, LValue.class, RValue.class), lhs, rhs); + } catch (NoSuchMethodException ignored) { } + } + return new Function(position, Operators.class.getMethod(name, RValue.class, RValue.class), lhs, rhs); + } + + public static Function getOperator(int position, String name, RValue argument) throws NoSuchMethodException { + if (argument instanceof LValue) { + try { + return new Function(position, Operators.class.getMethod(name, LValue.class), argument); + } catch (NoSuchMethodException ignored) { } + } + return new Function(position, Operators.class.getMethod(name, RValue.class), argument); + } + + + public static double add(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() + rhs.getValue(); + } + + public static double sub(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() - rhs.getValue(); + } + + public static double mul(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() * rhs.getValue(); + } + + public static double div(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() / rhs.getValue(); + } + + public static double mod(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() % rhs.getValue(); + } + + public static double pow(RValue lhs, RValue rhs) throws EvaluationException { + return Math.pow(lhs.getValue(), rhs.getValue()); + } + + + public static double neg(RValue x) throws EvaluationException { + return -x.getValue(); + } + + public static double not(RValue x) throws EvaluationException { + return x.getValue() > 0.0 ? 0.0 : 1.0; + } + + public static double inv(RValue x) throws EvaluationException { + return ~(long) x.getValue(); + } + + + public static double lth(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() < rhs.getValue() ? 1.0 : 0.0; + } + + public static double gth(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() > rhs.getValue() ? 1.0 : 0.0; + } + + public static double leq(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() <= rhs.getValue() ? 1.0 : 0.0; + } + + public static double geq(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() >= rhs.getValue() ? 1.0 : 0.0; + } + + + public static double equ(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() == rhs.getValue() ? 1.0 : 0.0; + } + + public static double neq(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() != rhs.getValue() ? 1.0 : 0.0; + } + + public static double near(RValue lhs, RValue rhs) throws EvaluationException { + return almostEqual2sComplement(lhs.getValue(), rhs.getValue(), 450359963L) ? 1.0 : 0.0; + //return Math.abs(lhs.invoke() - rhs.invoke()) < 1e-7 ? 1.0 : 0.0; + } + + + public static double or(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() > 0.0 || rhs.getValue() > 0.0 ? 1.0 : 0.0; + } + + public static double and(RValue lhs, RValue rhs) throws EvaluationException { + return lhs.getValue() > 0.0 && rhs.getValue() > 0.0 ? 1.0 : 0.0; + } + + + public static double shl(RValue lhs, RValue rhs) throws EvaluationException { + return (long) lhs.getValue() << (long) rhs.getValue(); + } + + public static double shr(RValue lhs, RValue rhs) throws EvaluationException { + return (long) lhs.getValue() >> (long) rhs.getValue(); + } + + + public static double ass(LValue lhs, RValue rhs) throws EvaluationException { + return lhs.assign(rhs.getValue()); + } + + public static double aadd(LValue lhs, RValue rhs) throws EvaluationException { + return lhs.assign(lhs.getValue() + rhs.getValue()); + } + + public static double asub(LValue lhs, RValue rhs) throws EvaluationException { + return lhs.assign(lhs.getValue() - rhs.getValue()); + } + + public static double amul(LValue lhs, RValue rhs) throws EvaluationException { + return lhs.assign(lhs.getValue() * rhs.getValue()); + } + + public static double adiv(LValue lhs, RValue rhs) throws EvaluationException { + return lhs.assign(lhs.getValue() / rhs.getValue()); + } + + public static double amod(LValue lhs, RValue rhs) throws EvaluationException { + return lhs.assign(lhs.getValue() % rhs.getValue()); + } + + public static double aexp(LValue lhs, RValue rhs) throws EvaluationException { + return lhs.assign(Math.pow(lhs.getValue(), rhs.getValue())); + } + + + public static double inc(LValue x) throws EvaluationException { + return x.assign(x.getValue() + 1); + } + + public static double dec(LValue x) throws EvaluationException { + return x.assign(x.getValue() - 1); + } + + public static double postinc(LValue x) throws EvaluationException { + final double oldValue = x.getValue(); + x.assign(oldValue + 1); + return oldValue; + } + + public static double postdec(LValue x) throws EvaluationException { + final double oldValue = x.getValue(); + x.assign(oldValue - 1); + return oldValue; + } + + + private static final double[] factorials = new double[171]; + static { + double accum = 1; + factorials[0] = 1; + for (int i = 1; i < factorials.length; ++i) { + factorials[i] = accum *= i; + } + } + + public static double fac(RValue x) throws EvaluationException { + final int n = (int) x.getValue(); + + if (n < 0) { + return 0; + } + + if (n >= factorials.length) { + return Double.POSITIVE_INFINITY; + } + + return factorials[n]; + } + + // Usable AlmostEqual function, based on http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm + private static boolean almostEqual2sComplement(double A, double B, long maxUlps) { + // Make sure maxUlps is non-negative and small enough that the + // default NAN won't compare as equal to anything. + //assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); // this is for floats, not doubles + + long aLong = Double.doubleToRawLongBits(A); + // Make aLong lexicographically ordered as a twos-complement long + if (aLong < 0) aLong = 0x8000000000000000L - aLong; + + long bLong = Double.doubleToRawLongBits(B); + // Make bLong lexicographically ordered as a twos-complement long + if (bLong < 0) bLong = 0x8000000000000000L - bLong; + + final long longDiff = Math.abs(aLong - bLong); + return longDiff <= maxUlps; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/RValue.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/RValue.java similarity index 81% rename from src/main/java/com/sk89q/worldedit/expression/runtime/RValue.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/RValue.java index 863577d5b..83077162e 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/RValue.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/RValue.java @@ -1,37 +1,37 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.Identifiable; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * A value that can be used on the right side of an assignment. - * - * @author TomyLobo - */ -public interface RValue extends Identifiable { - public double getValue() throws EvaluationException; - - public RValue optimize() throws EvaluationException; - - public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException; -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.Identifiable; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * A value that can be used on the right side of an assignment. + * + * @author TomyLobo + */ +public interface RValue extends Identifiable { + public double getValue() throws EvaluationException; + + public RValue optimize() throws EvaluationException; + + public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException; +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Return.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Return.java similarity index 86% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Return.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Return.java index fb3e42336..d02fc2488 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Return.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Return.java @@ -1,60 +1,60 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * A return statement. - * - * @author TomyLobo - */ -public class Return extends Node { - RValue value; - - public Return(int position, RValue value) { - super(position); - - this.value = value; - } - - @Override - public double getValue() throws EvaluationException { - throw new ReturnException(value.getValue()); - } - - @Override - public char id() { - return 'r'; - } - - @Override - public String toString() { - return "return " + value; - } - - @Override - public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - value = value.bindVariables(expression, false); - - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * A return statement. + * + * @author TomyLobo + */ +public class Return extends Node { + RValue value; + + public Return(int position, RValue value) { + super(position); + + this.value = value; + } + + @Override + public double getValue() throws EvaluationException { + throw new ReturnException(value.getValue()); + } + + @Override + public char id() { + return 'r'; + } + + @Override + public String toString() { + return "return " + value; + } + + @Override + public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + value = value.bindVariables(expression, false); + + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/ReturnException.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ReturnException.java similarity index 84% rename from src/main/java/com/sk89q/worldedit/expression/runtime/ReturnException.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/ReturnException.java index 7f91a430e..2635ad619 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/ReturnException.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ReturnException.java @@ -1,42 +1,42 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -/** - * Thrown when a return statement is encountered. - * {@link com.sk89q.worldedit.expression.Expression#evaluate} catches this exception and returns the enclosed value. - * - * @author TomyLobo - */ -public class ReturnException extends EvaluationException { - private static final long serialVersionUID = 1L; - - final double value; - - public ReturnException(double value) { - super(-1); - - this.value = value; - } - - public double getValue() { - return value; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +/** + * Thrown when a return statement is encountered. + * {@link com.sk89q.worldedit.internal.expression.Expression#evaluate} catches this exception and returns the enclosed value. + * + * @author TomyLobo + */ +public class ReturnException extends EvaluationException { + private static final long serialVersionUID = 1L; + + final double value; + + public ReturnException(double value) { + super(-1); + + this.value = value; + } + + public double getValue() { + return value; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Sequence.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Sequence.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Sequence.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Sequence.java index 88edf50c2..a8f06d178 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Sequence.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Sequence.java @@ -1,109 +1,109 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import java.util.ArrayList; -import java.util.List; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * A sequence of operations, usually separated by semicolons in the input stream. - * - * @author TomyLobo - */ -public class Sequence extends Node { - final RValue[] sequence; - - public Sequence(int position, RValue... sequence) { - super(position); - - this.sequence = sequence; - } - - @Override - public char id() { - return 's'; - } - - @Override - public double getValue() throws EvaluationException { - double ret = 0; - for (RValue invokable : sequence) { - ret = invokable.getValue(); - } - return ret; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("seq("); - boolean first = true; - for (RValue invokable : sequence) { - if (!first) { - sb.append(", "); - } - sb.append(invokable); - first = false; - } - - return sb.append(')').toString(); - } - - @Override - public RValue optimize() throws EvaluationException { - final List newSequence = new ArrayList(); - - RValue droppedLast = null; - for (RValue invokable : sequence) { - droppedLast = null; - invokable = invokable.optimize(); - if (invokable instanceof Sequence) { - for (RValue subInvokable : ((Sequence) invokable).sequence) { - newSequence.add(subInvokable); - } - } else if (invokable instanceof Constant) { - droppedLast = invokable; - } else { - newSequence.add(invokable); - } - } - - if (droppedLast != null) { - newSequence.add(droppedLast); - } - - if (newSequence.size() == 1) { - return newSequence.get(0); - } - - return new Sequence(getPosition(), newSequence.toArray(new RValue[newSequence.size()])); - } - - @Override - public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - for (int i = 0; i < sequence.length; ++i) { - sequence[i] = sequence[i].bindVariables(expression, false); - } - - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import java.util.ArrayList; +import java.util.List; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * A sequence of operations, usually separated by semicolons in the input stream. + * + * @author TomyLobo + */ +public class Sequence extends Node { + final RValue[] sequence; + + public Sequence(int position, RValue... sequence) { + super(position); + + this.sequence = sequence; + } + + @Override + public char id() { + return 's'; + } + + @Override + public double getValue() throws EvaluationException { + double ret = 0; + for (RValue invokable : sequence) { + ret = invokable.getValue(); + } + return ret; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("seq("); + boolean first = true; + for (RValue invokable : sequence) { + if (!first) { + sb.append(", "); + } + sb.append(invokable); + first = false; + } + + return sb.append(')').toString(); + } + + @Override + public RValue optimize() throws EvaluationException { + final List newSequence = new ArrayList(); + + RValue droppedLast = null; + for (RValue invokable : sequence) { + droppedLast = null; + invokable = invokable.optimize(); + if (invokable instanceof Sequence) { + for (RValue subInvokable : ((Sequence) invokable).sequence) { + newSequence.add(subInvokable); + } + } else if (invokable instanceof Constant) { + droppedLast = invokable; + } else { + newSequence.add(invokable); + } + } + + if (droppedLast != null) { + newSequence.add(droppedLast); + } + + if (newSequence.size() == 1) { + return newSequence.get(0); + } + + return new Sequence(getPosition(), newSequence.toArray(new RValue[newSequence.size()])); + } + + @Override + public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + for (int i = 0; i < sequence.length; ++i) { + sequence[i] = sequence[i].bindVariables(expression, false); + } + + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/SimpleFor.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/SimpleFor.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/expression/runtime/SimpleFor.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/SimpleFor.java index 801e9709d..51eadc06e 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/SimpleFor.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/SimpleFor.java @@ -1,101 +1,101 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * A simple-style for loop. - * - * @author TomyLobo - */ -public class SimpleFor extends Node { - LValue counter; - RValue first; - RValue last; - RValue body; - - public SimpleFor(int position, LValue counter, RValue first, RValue last, RValue body) { - super(position); - - this.counter = counter; - this.first = first; - this.last = last; - this.body = body; - } - - @Override - public double getValue() throws EvaluationException { - int iterations = 0; - double ret = 0.0; - - double firstValue = first.getValue(); - double lastValue = last.getValue(); - - for (double i = firstValue; i <= lastValue; ++i) { - if (iterations > 256) { - throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations."); - } - ++iterations; - - try { - counter.assign(i); - ret = body.getValue(); - } catch (BreakException e) { - if (e.doContinue) { - //noinspection UnnecessaryContinue - continue; - } else { - break; - } - } - } - - return ret; - } - - @Override - public char id() { - return 'S'; - } - - @Override - public String toString() { - return "for (" + counter + " = " + first + ", " + last + ") { " + body + " }"; - } - - @Override - public RValue optimize() throws EvaluationException { - // TODO: unroll small loops into Sequences - - return new SimpleFor(getPosition(), (LValue) counter.optimize(), first.optimize(), last.optimize(), body.optimize()); - } - - @Override - public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - counter = counter.bindVariables(expression, true); - first = first.bindVariables(expression, false); - last = last.bindVariables(expression, false); - body = body.bindVariables(expression, false); - - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * A simple-style for loop. + * + * @author TomyLobo + */ +public class SimpleFor extends Node { + LValue counter; + RValue first; + RValue last; + RValue body; + + public SimpleFor(int position, LValue counter, RValue first, RValue last, RValue body) { + super(position); + + this.counter = counter; + this.first = first; + this.last = last; + this.body = body; + } + + @Override + public double getValue() throws EvaluationException { + int iterations = 0; + double ret = 0.0; + + double firstValue = first.getValue(); + double lastValue = last.getValue(); + + for (double i = firstValue; i <= lastValue; ++i) { + if (iterations > 256) { + throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations."); + } + ++iterations; + + try { + counter.assign(i); + ret = body.getValue(); + } catch (BreakException e) { + if (e.doContinue) { + //noinspection UnnecessaryContinue + continue; + } else { + break; + } + } + } + + return ret; + } + + @Override + public char id() { + return 'S'; + } + + @Override + public String toString() { + return "for (" + counter + " = " + first + ", " + last + ") { " + body + " }"; + } + + @Override + public RValue optimize() throws EvaluationException { + // TODO: unroll small loops into Sequences + + return new SimpleFor(getPosition(), (LValue) counter.optimize(), first.optimize(), last.optimize(), body.optimize()); + } + + @Override + public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + counter = counter.bindVariables(expression, true); + first = first.bindVariables(expression, false); + last = last.bindVariables(expression, false); + body = body.bindVariables(expression, false); + + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Switch.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Switch.java index cdf259038..f7b8a3393 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Switch.java @@ -1,208 +1,208 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * A switch/case construct. - * - * @author TomyLobo - */ -public class Switch extends Node implements RValue { - private RValue parameter; - private final Map valueMap; - private final RValue[] caseStatements; - private RValue defaultCase; - - public Switch(int position, RValue parameter, List values, List caseStatements, RValue defaultCase) { - this(position, parameter, invertList(values), caseStatements, defaultCase); - - } - - private static Map invertList(List values) { - Map valueMap = new HashMap(); - for (int i = 0; i < values.size(); ++i) { - valueMap.put(values.get(i), i); - } - return valueMap; - } - - private Switch(int position, RValue parameter, Map valueMap, List caseStatements, RValue defaultCase) { - super(position); - - this.parameter = parameter; - this.valueMap = valueMap; - this.caseStatements = caseStatements.toArray(new RValue[caseStatements.size()]); - this.defaultCase = defaultCase; - } - - @Override - public char id() { - return 'W'; - } - - @Override - public double getValue() throws EvaluationException { - final double parameter = this.parameter.getValue(); - - try { - double ret = 0.0; - - final Integer index = valueMap.get(parameter); - if (index != null) { - for (int i = index; i < caseStatements.length; ++i) { - ret = caseStatements[i].getValue(); - } - } - - return defaultCase == null ? ret : defaultCase.getValue(); - } catch (BreakException e) { - if (e.doContinue) throw e; - - return 0.0; - } - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - - sb.append("switch ("); - sb.append(parameter); - sb.append(") { "); - - for (int i = 0; i < caseStatements.length; ++i) { - RValue caseStatement = caseStatements[i]; - sb.append("case "); - for (Entry entry : valueMap.entrySet()) { - if (entry.getValue() == i) { - sb.append(entry.getKey()); - break; - } - } - sb.append(": "); - sb.append(caseStatement); - sb.append(' '); - } - - if (defaultCase != null) { - sb.append("default: "); - sb.append(defaultCase); - sb.append(' '); - } - - sb.append("}"); - - return sb.toString(); - } - - @Override - public RValue optimize() throws EvaluationException { - final RValue optimizedParameter = parameter.optimize(); - final List newSequence = new ArrayList(); - - if (optimizedParameter instanceof Constant) { - final double parameter = optimizedParameter.getValue(); - - final Integer index = valueMap.get(parameter); - if (index == null) { - return defaultCase == null ? new Constant(getPosition(), 0.0) : defaultCase.optimize(); - } - - boolean breakDetected = false; - for (int i = index; i < caseStatements.length && !breakDetected ; ++i) { - final RValue invokable = caseStatements[i].optimize(); - - if (invokable instanceof Sequence) { - for (RValue subInvokable : ((Sequence) invokable).sequence) { - if (subInvokable instanceof Break) { - breakDetected = true; - break; - } - - newSequence.add(subInvokable); - } - } else { - newSequence.add(invokable); - } - } - - if (defaultCase != null && !breakDetected) { - final RValue invokable = defaultCase.optimize(); - - if (invokable instanceof Sequence) { - Collections.addAll(newSequence, ((Sequence) invokable).sequence); - } else { - newSequence.add(invokable); - } - } - - return new Switch(getPosition(), optimizedParameter, Collections.singletonMap(parameter, 0), newSequence, null); - } - - final Map newValueMap = new HashMap(); - - Map backMap = new HashMap(); - for (Entry entry : valueMap.entrySet()) { - backMap.put(entry.getValue(), entry.getKey()); - } - - for (int i = 0; i < caseStatements.length; ++i) { - final RValue invokable = caseStatements[i].optimize(); - - final Double caseValue = backMap.get(i); - if (caseValue != null) { - newValueMap.put(caseValue, newSequence.size()); - } - - if (invokable instanceof Sequence) { - for (RValue subInvokable : ((Sequence) invokable).sequence) { - newSequence.add(subInvokable); - } - } else { - newSequence.add(invokable); - } - } - - return new Switch(getPosition(), optimizedParameter, newValueMap, newSequence, defaultCase.optimize()); - } - - @Override - public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - parameter = parameter.bindVariables(expression, false); - - for (int i = 0; i < caseStatements.length; ++i) { - caseStatements[i] = caseStatements[i].bindVariables(expression, false); - } - - defaultCase = defaultCase.bindVariables(expression, false); - - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * A switch/case construct. + * + * @author TomyLobo + */ +public class Switch extends Node implements RValue { + private RValue parameter; + private final Map valueMap; + private final RValue[] caseStatements; + private RValue defaultCase; + + public Switch(int position, RValue parameter, List values, List caseStatements, RValue defaultCase) { + this(position, parameter, invertList(values), caseStatements, defaultCase); + + } + + private static Map invertList(List values) { + Map valueMap = new HashMap(); + for (int i = 0; i < values.size(); ++i) { + valueMap.put(values.get(i), i); + } + return valueMap; + } + + private Switch(int position, RValue parameter, Map valueMap, List caseStatements, RValue defaultCase) { + super(position); + + this.parameter = parameter; + this.valueMap = valueMap; + this.caseStatements = caseStatements.toArray(new RValue[caseStatements.size()]); + this.defaultCase = defaultCase; + } + + @Override + public char id() { + return 'W'; + } + + @Override + public double getValue() throws EvaluationException { + final double parameter = this.parameter.getValue(); + + try { + double ret = 0.0; + + final Integer index = valueMap.get(parameter); + if (index != null) { + for (int i = index; i < caseStatements.length; ++i) { + ret = caseStatements[i].getValue(); + } + } + + return defaultCase == null ? ret : defaultCase.getValue(); + } catch (BreakException e) { + if (e.doContinue) throw e; + + return 0.0; + } + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + + sb.append("switch ("); + sb.append(parameter); + sb.append(") { "); + + for (int i = 0; i < caseStatements.length; ++i) { + RValue caseStatement = caseStatements[i]; + sb.append("case "); + for (Entry entry : valueMap.entrySet()) { + if (entry.getValue() == i) { + sb.append(entry.getKey()); + break; + } + } + sb.append(": "); + sb.append(caseStatement); + sb.append(' '); + } + + if (defaultCase != null) { + sb.append("default: "); + sb.append(defaultCase); + sb.append(' '); + } + + sb.append("}"); + + return sb.toString(); + } + + @Override + public RValue optimize() throws EvaluationException { + final RValue optimizedParameter = parameter.optimize(); + final List newSequence = new ArrayList(); + + if (optimizedParameter instanceof Constant) { + final double parameter = optimizedParameter.getValue(); + + final Integer index = valueMap.get(parameter); + if (index == null) { + return defaultCase == null ? new Constant(getPosition(), 0.0) : defaultCase.optimize(); + } + + boolean breakDetected = false; + for (int i = index; i < caseStatements.length && !breakDetected ; ++i) { + final RValue invokable = caseStatements[i].optimize(); + + if (invokable instanceof Sequence) { + for (RValue subInvokable : ((Sequence) invokable).sequence) { + if (subInvokable instanceof Break) { + breakDetected = true; + break; + } + + newSequence.add(subInvokable); + } + } else { + newSequence.add(invokable); + } + } + + if (defaultCase != null && !breakDetected) { + final RValue invokable = defaultCase.optimize(); + + if (invokable instanceof Sequence) { + Collections.addAll(newSequence, ((Sequence) invokable).sequence); + } else { + newSequence.add(invokable); + } + } + + return new Switch(getPosition(), optimizedParameter, Collections.singletonMap(parameter, 0), newSequence, null); + } + + final Map newValueMap = new HashMap(); + + Map backMap = new HashMap(); + for (Entry entry : valueMap.entrySet()) { + backMap.put(entry.getValue(), entry.getKey()); + } + + for (int i = 0; i < caseStatements.length; ++i) { + final RValue invokable = caseStatements[i].optimize(); + + final Double caseValue = backMap.get(i); + if (caseValue != null) { + newValueMap.put(caseValue, newSequence.size()); + } + + if (invokable instanceof Sequence) { + for (RValue subInvokable : ((Sequence) invokable).sequence) { + newSequence.add(subInvokable); + } + } else { + newSequence.add(invokable); + } + } + + return new Switch(getPosition(), optimizedParameter, newValueMap, newSequence, defaultCase.optimize()); + } + + @Override + public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + parameter = parameter.bindVariables(expression, false); + + for (int i = 0; i < caseStatements.length; ++i) { + caseStatements[i] = caseStatements[i].bindVariables(expression, false); + } + + defaultCase = defaultCase.bindVariables(expression, false); + + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Variable.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Variable.java similarity index 87% rename from src/main/java/com/sk89q/worldedit/expression/runtime/Variable.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/Variable.java index 22477fdeb..da405d769 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Variable.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/Variable.java @@ -1,67 +1,67 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * A variable. - * - * @author TomyLobo - */ -public final class Variable extends Node implements LValue { - public double value; - - public Variable(double value) { - super(-1); - this.value = value; - } - - @Override - public double getValue() { - return value; - } - - @Override - public String toString() { - return "var"; - } - - @Override - public char id() { - return 'v'; - } - - @Override - public double assign(double value) { - return this.value = value; - } - - @Override - public LValue optimize() throws EvaluationException { - return this; - } - - @Override - public LValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * A variable. + * + * @author TomyLobo + */ +public final class Variable extends Node implements LValue { + public double value; + + public Variable(double value) { + super(-1); + this.value = value; + } + + @Override + public double getValue() { + return value; + } + + @Override + public String toString() { + return "var"; + } + + @Override + public char id() { + return 'v'; + } + + @Override + public double assign(double value) { + return this.value = value; + } + + @Override + public LValue optimize() throws EvaluationException { + return this; + } + + @Override + public LValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/While.java b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/While.java similarity index 92% rename from src/main/java/com/sk89q/worldedit/expression/runtime/While.java rename to src/main/java/com/sk89q/worldedit/internal/expression/runtime/While.java index f68dcb660..592a56067 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/While.java +++ b/src/main/java/com/sk89q/worldedit/internal/expression/runtime/While.java @@ -1,127 +1,127 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.expression.runtime; - -import com.sk89q.worldedit.expression.Expression; -import com.sk89q.worldedit.expression.parser.ParserException; - -/** - * A while loop. - * - * @author TomyLobo - */ -public class While extends Node { - RValue condition; - RValue body; - boolean footChecked; - - public While(int position, RValue condition, RValue body, boolean footChecked) { - super(position); - - this.condition = condition; - this.body = body; - this.footChecked = footChecked; - } - - @Override - public double getValue() throws EvaluationException { - int iterations = 0; - double ret = 0.0; - - if (footChecked) { - do { - if (iterations > 256) { - throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations."); - } - ++iterations; - - try { - ret = body.getValue(); - } catch (BreakException e) { - if (e.doContinue) { - continue; - } else { - break; - } - } - } while (condition.getValue() > 0.0); - } else { - while (condition.getValue() > 0.0) { - if (iterations > 256) { - throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations."); - } - ++iterations; - - try { - ret = body.getValue(); - } catch (BreakException e) { - if (e.doContinue) { - //noinspection UnnecessaryContinue - continue; - } else { - break; - } - } - } - } - - return ret; - } - - @Override - public char id() { - return 'w'; - } - - @Override - public String toString() { - if (footChecked) { - return "do { " + body + " } while (" + condition + ")"; - } else { - return "while (" + condition + ") { " + body + " }"; - } - } - - @Override - public RValue optimize() throws EvaluationException { - final RValue newCondition = condition.optimize(); - - if (newCondition instanceof Constant && newCondition.getValue() <= 0) { - // If the condition is always false, the loop can be flattened. - if (footChecked) { - // Foot-checked loops run at least once. - return body.optimize(); - } else { - // Loops that never run always return 0.0. - return new Constant(getPosition(), 0.0); - } - } - - return new While(getPosition(), newCondition, body.optimize(), footChecked); - } - - @Override - public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { - condition = condition.bindVariables(expression, false); - body = body.bindVariables(expression, false); - - return this; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.internal.expression.runtime; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.parser.ParserException; + +/** + * A while loop. + * + * @author TomyLobo + */ +public class While extends Node { + RValue condition; + RValue body; + boolean footChecked; + + public While(int position, RValue condition, RValue body, boolean footChecked) { + super(position); + + this.condition = condition; + this.body = body; + this.footChecked = footChecked; + } + + @Override + public double getValue() throws EvaluationException { + int iterations = 0; + double ret = 0.0; + + if (footChecked) { + do { + if (iterations > 256) { + throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations."); + } + ++iterations; + + try { + ret = body.getValue(); + } catch (BreakException e) { + if (e.doContinue) { + continue; + } else { + break; + } + } + } while (condition.getValue() > 0.0); + } else { + while (condition.getValue() > 0.0) { + if (iterations > 256) { + throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations."); + } + ++iterations; + + try { + ret = body.getValue(); + } catch (BreakException e) { + if (e.doContinue) { + //noinspection UnnecessaryContinue + continue; + } else { + break; + } + } + } + } + + return ret; + } + + @Override + public char id() { + return 'w'; + } + + @Override + public String toString() { + if (footChecked) { + return "do { " + body + " } while (" + condition + ")"; + } else { + return "while (" + condition + ") { " + body + " }"; + } + } + + @Override + public RValue optimize() throws EvaluationException { + final RValue newCondition = condition.optimize(); + + if (newCondition instanceof Constant && newCondition.getValue() <= 0) { + // If the condition is always false, the loop can be flattened. + if (footChecked) { + // Foot-checked loops run at least once. + return body.optimize(); + } else { + // Loops that never run always return 0.0. + return new Constant(getPosition(), 0.0); + } + } + + return new While(getPosition(), newCondition, body.optimize(), footChecked); + } + + @Override + public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException { + condition = condition.bindVariables(expression, false); + body = body.bindVariables(expression, false); + + return this; + } +} diff --git a/src/main/java/com/sk89q/worldedit/internal/util/DocumentationPrinter.java b/src/main/java/com/sk89q/worldedit/internal/util/DocumentationPrinter.java index 86e6cb976..cfacec6a6 100644 --- a/src/main/java/com/sk89q/worldedit/internal/util/DocumentationPrinter.java +++ b/src/main/java/com/sk89q/worldedit/internal/util/DocumentationPrinter.java @@ -31,20 +31,20 @@ import java.util.List; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.NestedCommand; -import com.sk89q.worldedit.commands.BiomeCommands; -import com.sk89q.worldedit.commands.ChunkCommands; -import com.sk89q.worldedit.commands.ClipboardCommands; -import com.sk89q.worldedit.commands.GeneralCommands; -import com.sk89q.worldedit.commands.GenerationCommands; -import com.sk89q.worldedit.commands.HistoryCommands; -import com.sk89q.worldedit.commands.NavigationCommands; -import com.sk89q.worldedit.commands.RegionCommands; -import com.sk89q.worldedit.commands.ScriptingCommands; -import com.sk89q.worldedit.commands.SelectionCommands; -import com.sk89q.worldedit.commands.SnapshotUtilCommands; -import com.sk89q.worldedit.commands.ToolCommands; -import com.sk89q.worldedit.commands.ToolUtilCommands; -import com.sk89q.worldedit.commands.UtilityCommands; +import com.sk89q.worldedit.command.BiomeCommands; +import com.sk89q.worldedit.command.ChunkCommands; +import com.sk89q.worldedit.command.ClipboardCommands; +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.ScriptingCommands; +import com.sk89q.worldedit.command.SelectionCommands; +import com.sk89q.worldedit.command.SnapshotUtilCommands; +import com.sk89q.worldedit.command.ToolCommands; +import com.sk89q.worldedit.command.ToolUtilCommands; +import com.sk89q.worldedit.command.UtilityCommands; public class DocumentationPrinter { public static void main(String[] args) throws IOException { diff --git a/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java b/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java index 90a4e7e59..677f7bf79 100644 --- a/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java +++ b/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java @@ -30,7 +30,7 @@ import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; -import com.sk89q.worldedit.data.ChunkStore; +import com.sk89q.worldedit.world.storage.ChunkStore; public abstract class AbstractRegion implements Region { /** diff --git a/src/main/java/com/sk89q/worldedit/regions/ConvexPolyhedralRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/ConvexPolyhedralRegionSelector.java index ba4d941ea..23c435900 100644 --- a/src/main/java/com/sk89q/worldedit/regions/ConvexPolyhedralRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/ConvexPolyhedralRegionSelector.java @@ -32,10 +32,10 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.cui.CUIRegion; -import com.sk89q.worldedit.cui.SelectionPointEvent; -import com.sk89q.worldedit.cui.SelectionPolygonEvent; -import com.sk89q.worldedit.cui.SelectionShapeEvent; +import com.sk89q.worldedit.internal.cui.CUIRegion; +import com.sk89q.worldedit.internal.cui.SelectionPointEvent; +import com.sk89q.worldedit.internal.cui.SelectionPolygonEvent; +import com.sk89q.worldedit.internal.cui.SelectionShapeEvent; import com.sk89q.worldedit.regions.polyhedron.Triangle; public class ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion { diff --git a/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java index dabdc848d..71958c2b8 100644 --- a/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java +++ b/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java @@ -20,7 +20,7 @@ package com.sk89q.worldedit.regions; import com.sk89q.worldedit.*; -import com.sk89q.worldedit.data.ChunkStore; +import com.sk89q.worldedit.world.storage.ChunkStore; import java.util.HashSet; import java.util.Iterator; diff --git a/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java index 229239dbf..48c6748f7 100644 --- a/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java @@ -27,8 +27,8 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.cui.CUIRegion; -import com.sk89q.worldedit.cui.SelectionPointEvent; +import com.sk89q.worldedit.internal.cui.CUIRegion; +import com.sk89q.worldedit.internal.cui.SelectionPointEvent; /** * Selector for cuboids. diff --git a/src/main/java/com/sk89q/worldedit/regions/CylinderRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/CylinderRegionSelector.java index 54585f708..813c76ab1 100644 --- a/src/main/java/com/sk89q/worldedit/regions/CylinderRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/CylinderRegionSelector.java @@ -28,11 +28,11 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; -import com.sk89q.worldedit.cui.CUIRegion; -import com.sk89q.worldedit.cui.SelectionCylinderEvent; -import com.sk89q.worldedit.cui.SelectionMinMaxEvent; -import com.sk89q.worldedit.cui.SelectionPointEvent; -import com.sk89q.worldedit.cui.SelectionShapeEvent; +import com.sk89q.worldedit.internal.cui.CUIRegion; +import com.sk89q.worldedit.internal.cui.SelectionCylinderEvent; +import com.sk89q.worldedit.internal.cui.SelectionMinMaxEvent; +import com.sk89q.worldedit.internal.cui.SelectionPointEvent; +import com.sk89q.worldedit.internal.cui.SelectionShapeEvent; import java.text.NumberFormat; /** diff --git a/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java b/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java index 55c0688ff..cd990d570 100644 --- a/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java +++ b/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java @@ -24,7 +24,7 @@ import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; -import com.sk89q.worldedit.data.ChunkStore; +import com.sk89q.worldedit.world.storage.ChunkStore; import java.util.Set; import java.util.HashSet; diff --git a/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegionSelector.java index 8a84ac8e7..4752b7166 100644 --- a/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegionSelector.java @@ -27,9 +27,9 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.cui.CUIRegion; -import com.sk89q.worldedit.cui.SelectionEllipsoidPointEvent; -import com.sk89q.worldedit.cui.SelectionPointEvent; +import com.sk89q.worldedit.internal.cui.CUIRegion; +import com.sk89q.worldedit.internal.cui.SelectionEllipsoidPointEvent; +import com.sk89q.worldedit.internal.cui.SelectionPointEvent; /** * Selector for ellipsoids. diff --git a/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java index 628179a96..72276b426 100644 --- a/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java @@ -28,10 +28,10 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.cui.CUIRegion; -import com.sk89q.worldedit.cui.SelectionMinMaxEvent; -import com.sk89q.worldedit.cui.SelectionPoint2DEvent; -import com.sk89q.worldedit.cui.SelectionShapeEvent; +import com.sk89q.worldedit.internal.cui.CUIRegion; +import com.sk89q.worldedit.internal.cui.SelectionMinMaxEvent; +import com.sk89q.worldedit.internal.cui.SelectionPoint2DEvent; +import com.sk89q.worldedit.internal.cui.SelectionShapeEvent; /** * Selector for polygonal regions. diff --git a/src/main/java/com/sk89q/worldedit/shape/ArbitraryBiomeShape.java b/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/shape/ArbitraryBiomeShape.java rename to src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java index 9b2c3c273..81130e22e 100644 --- a/src/main/java/com/sk89q/worldedit/shape/ArbitraryBiomeShape.java +++ b/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java @@ -1,189 +1,189 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.shape; - -import com.sk89q.worldedit.BiomeType; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.Vector2D; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.regions.FlatRegion; -import com.sk89q.worldedit.regions.Region; - -/** - * Generates solid and hollow shapes according to materials returned by the - * {@link #getBiome} method. - * - * @author TomyLobo - */ -public abstract class ArbitraryBiomeShape { - private final FlatRegion extent; - private int cacheOffsetX; - private int cacheOffsetZ; - @SuppressWarnings("FieldCanBeLocal") - private int cacheSizeX; - private int cacheSizeZ; - - public ArbitraryBiomeShape(Region extent) { - if (extent instanceof FlatRegion) { - this.extent = (FlatRegion) extent; - } - else { - // TODO: polygonize - this.extent = new CuboidRegion(extent.getWorld(), extent.getMinimumPoint(), extent.getMaximumPoint()); - } - - Vector2D min = extent.getMinimumPoint().toVector2D(); - Vector2D max = extent.getMaximumPoint().toVector2D(); - - cacheOffsetX = min.getBlockX() - 1; - cacheOffsetZ = min.getBlockZ() - 1; - - cacheSizeX = (int) (max.getX() - cacheOffsetX + 2); - cacheSizeZ = (int) (max.getZ() - cacheOffsetZ + 2); - - cache = new BiomeType[cacheSizeX * cacheSizeZ]; - } - - protected Iterable getExtent() { - return extent.asFlatRegion(); - } - - - /** - * Cache entries: - * null = unknown - * OUTSIDE = outside - * else = inside - */ - private final BiomeType[] cache; - - /** - * Override this function to specify the shape to generate. - * - * @param x X coordinate to be queried - * @param z Z coordinate to be queried - * @param defaultBiomeType The default biome for the current column. - * @return material to place or null to not place anything. - */ - protected abstract BiomeType getBiome(int x, int z, BiomeType defaultBiomeType); - - private BiomeType getBiomeCached(int x, int z, BiomeType biomeType) { - final int index = (z - cacheOffsetZ) + (x - cacheOffsetX) * cacheSizeZ; - - final BiomeType cacheEntry = cache[index]; - if (cacheEntry == null) {// unknown, fetch material - final BiomeType material = getBiome(x, z, biomeType); - if (material == null) { - // outside - cache[index] = OUTSIDE; - return null; - } - - cache[index] = material; - return material; - } - - if (cacheEntry == OUTSIDE) { - // outside - return null; - } - - return cacheEntry; - } - - private boolean isInsideCached(int x, int z, BiomeType biomeType) { - final int index = (z - cacheOffsetZ) + (x - cacheOffsetX) * cacheSizeZ; - - final BiomeType cacheEntry = cache[index]; - if (cacheEntry == null) { - // unknown block, meaning they must be outside the extent at this stage, but might still be inside the shape - return getBiomeCached(x, z, biomeType) != null; - } - - return cacheEntry != OUTSIDE; - } - - /** - * Generates the shape. - * - * @param editSession The EditSession to use. - * @param biomeType The default biome type. - * @param hollow Specifies whether to generate a hollow shape. - * @return number of affected blocks. - */ - public int generate(EditSession editSession, BiomeType biomeType, boolean hollow) { - int affected = 0; - - for (Vector2D position : getExtent()) { - int x = position.getBlockX(); - int z = position.getBlockZ(); - - if (!hollow) { - final BiomeType material = getBiome(x, z, biomeType); - if (material != OUTSIDE) { - editSession.getWorld().setBiome(position, material); - ++affected; - } - - continue; - } - - final BiomeType material = getBiomeCached(x, z, biomeType); - if (material == null) { - continue; - } - - boolean draw = false; - do { - if (!isInsideCached(x + 1, z, biomeType)) { - draw = true; - break; - } - if (!isInsideCached(x - 1, z, biomeType)) { - draw = true; - break; - } - if (!isInsideCached(x, z + 1, biomeType)) { - draw = true; - break; - } - if (!isInsideCached(x, z - 1, biomeType)) { - draw = true; - break; - } - } while (false); - - if (!draw) { - continue; - } - - editSession.getWorld().setBiome(position, material); - ++affected; - } - - return affected; - } - - private static final BiomeType OUTSIDE = new BiomeType() { - public String getName() { - throw new UnsupportedOperationException(); - } - }; -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.regions.shape; + +import com.sk89q.worldedit.BiomeType; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.FlatRegion; +import com.sk89q.worldedit.regions.Region; + +/** + * Generates solid and hollow shapes according to materials returned by the + * {@link #getBiome} method. + * + * @author TomyLobo + */ +public abstract class ArbitraryBiomeShape { + private final FlatRegion extent; + private int cacheOffsetX; + private int cacheOffsetZ; + @SuppressWarnings("FieldCanBeLocal") + private int cacheSizeX; + private int cacheSizeZ; + + public ArbitraryBiomeShape(Region extent) { + if (extent instanceof FlatRegion) { + this.extent = (FlatRegion) extent; + } + else { + // TODO: polygonize + this.extent = new CuboidRegion(extent.getWorld(), extent.getMinimumPoint(), extent.getMaximumPoint()); + } + + Vector2D min = extent.getMinimumPoint().toVector2D(); + Vector2D max = extent.getMaximumPoint().toVector2D(); + + cacheOffsetX = min.getBlockX() - 1; + cacheOffsetZ = min.getBlockZ() - 1; + + cacheSizeX = (int) (max.getX() - cacheOffsetX + 2); + cacheSizeZ = (int) (max.getZ() - cacheOffsetZ + 2); + + cache = new BiomeType[cacheSizeX * cacheSizeZ]; + } + + protected Iterable getExtent() { + return extent.asFlatRegion(); + } + + + /** + * Cache entries: + * null = unknown + * OUTSIDE = outside + * else = inside + */ + private final BiomeType[] cache; + + /** + * Override this function to specify the shape to generate. + * + * @param x X coordinate to be queried + * @param z Z coordinate to be queried + * @param defaultBiomeType The default biome for the current column. + * @return material to place or null to not place anything. + */ + protected abstract BiomeType getBiome(int x, int z, BiomeType defaultBiomeType); + + private BiomeType getBiomeCached(int x, int z, BiomeType biomeType) { + final int index = (z - cacheOffsetZ) + (x - cacheOffsetX) * cacheSizeZ; + + final BiomeType cacheEntry = cache[index]; + if (cacheEntry == null) {// unknown, fetch material + final BiomeType material = getBiome(x, z, biomeType); + if (material == null) { + // outside + cache[index] = OUTSIDE; + return null; + } + + cache[index] = material; + return material; + } + + if (cacheEntry == OUTSIDE) { + // outside + return null; + } + + return cacheEntry; + } + + private boolean isInsideCached(int x, int z, BiomeType biomeType) { + final int index = (z - cacheOffsetZ) + (x - cacheOffsetX) * cacheSizeZ; + + final BiomeType cacheEntry = cache[index]; + if (cacheEntry == null) { + // unknown block, meaning they must be outside the extent at this stage, but might still be inside the shape + return getBiomeCached(x, z, biomeType) != null; + } + + return cacheEntry != OUTSIDE; + } + + /** + * Generates the shape. + * + * @param editSession The EditSession to use. + * @param biomeType The default biome type. + * @param hollow Specifies whether to generate a hollow shape. + * @return number of affected blocks. + */ + public int generate(EditSession editSession, BiomeType biomeType, boolean hollow) { + int affected = 0; + + for (Vector2D position : getExtent()) { + int x = position.getBlockX(); + int z = position.getBlockZ(); + + if (!hollow) { + final BiomeType material = getBiome(x, z, biomeType); + if (material != OUTSIDE) { + editSession.getWorld().setBiome(position, material); + ++affected; + } + + continue; + } + + final BiomeType material = getBiomeCached(x, z, biomeType); + if (material == null) { + continue; + } + + boolean draw = false; + do { + if (!isInsideCached(x + 1, z, biomeType)) { + draw = true; + break; + } + if (!isInsideCached(x - 1, z, biomeType)) { + draw = true; + break; + } + if (!isInsideCached(x, z + 1, biomeType)) { + draw = true; + break; + } + if (!isInsideCached(x, z - 1, biomeType)) { + draw = true; + break; + } + } while (false); + + if (!draw) { + continue; + } + + editSession.getWorld().setBiome(position, material); + ++affected; + } + + return affected; + } + + private static final BiomeType OUTSIDE = new BiomeType() { + public String getName() { + throw new UnsupportedOperationException(); + } + }; +} diff --git a/src/main/java/com/sk89q/worldedit/shape/ArbitraryShape.java b/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/shape/ArbitraryShape.java rename to src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java index 785a10013..589a85301 100644 --- a/src/main/java/com/sk89q/worldedit/shape/ArbitraryShape.java +++ b/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java @@ -1,211 +1,211 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.shape; - -import com.sk89q.worldedit.BlockVector; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.patterns.Pattern; -import com.sk89q.worldedit.regions.Region; - -/** - * Generates solid and hollow shapes according to materials returned by the - * {@link #getMaterial} method. - * - * @author TomyLobo - */ -public abstract class ArbitraryShape { - protected final Region extent; - private int cacheOffsetX; - private int cacheOffsetY; - private int cacheOffsetZ; - @SuppressWarnings("FieldCanBeLocal") - private int cacheSizeX; - private int cacheSizeY; - private int cacheSizeZ; - - public ArbitraryShape(Region extent) { - this.extent = extent; - - Vector min = extent.getMinimumPoint(); - Vector max = extent.getMaximumPoint(); - - cacheOffsetX = min.getBlockX() - 1; - cacheOffsetY = min.getBlockY() - 1; - cacheOffsetZ = min.getBlockZ() - 1; - - cacheSizeX = (int) (max.getX() - cacheOffsetX + 2); - cacheSizeY = (int) (max.getY() - cacheOffsetY + 2); - cacheSizeZ = (int) (max.getZ() - cacheOffsetZ + 2); - - cache = new short[cacheSizeX * cacheSizeY * cacheSizeZ]; - } - - protected Region getExtent() { - return extent; - } - - - /** - * Cache entries: - * 0 = unknown - * -1 = outside - * -2 = inside but type and data 0 - * > 0 = inside, value = (type | (data << 8)), not handling data < 0 - */ - private final short[] cache; - - /** - * Override this function to specify the shape to generate. - * - * @param x X coordinate to be queried - * @param y Y coordinate to be queried - * @param z Z coordinate to be queried - * @param defaultMaterial The material returned by the pattern for the current block. - * @return material to place or null to not place anything. - */ - protected abstract BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial); - - private BaseBlock getMaterialCached(int x, int y, int z, Pattern pattern) { - final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ; - - final short cacheEntry = cache[index]; - switch (cacheEntry) { - case 0: - // unknown, fetch material - final BaseBlock material = getMaterial(x, y, z, pattern.next(new BlockVector(x, y, z))); - if (material == null) { - // outside - cache[index] = -1; - return null; - } - - short newCacheEntry = (short) (material.getType() | ((material.getData() + 1) << 8)); - if (newCacheEntry == 0) { - // type and data 0 - newCacheEntry = -2; - } - - cache[index] = newCacheEntry; - return material; - - case -1: - // outside - return null; - - case -2: - // type and data 0 - return new BaseBlock(0, 0); - } - - return new BaseBlock(cacheEntry & 255, ((cacheEntry >> 8) - 1) & 15); - } - - private boolean isInsideCached(int x, int y, int z, Pattern pattern) { - final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ; - - switch (cache[index]) { - case 0: - // unknown block, meaning they must be outside the extent at this stage, but might still be inside the shape - return getMaterialCached(x, y, z, pattern) != null; - - case -1: - // outside - return false; - - default: - // inside - return true; - } - } - - /** - * Generates the shape. - * - * @param editSession The EditSession to use. - * @param pattern The pattern to generate default materials from. - * @param hollow Specifies whether to generate a hollow shape. - * @return number of affected blocks. - * @throws MaxChangedBlocksException - */ - public int generate(EditSession editSession, Pattern pattern, boolean hollow) throws MaxChangedBlocksException { - int affected = 0; - - for (BlockVector position : getExtent()) { - int x = position.getBlockX(); - int y = position.getBlockY(); - int z = position.getBlockZ(); - - if (!hollow) { - final BaseBlock material = getMaterial(x, y, z, pattern.next(position)); - if (material != null && editSession.setBlock(position, material)) { - ++affected; - } - - continue; - } - - final BaseBlock material = getMaterialCached(x, y, z, pattern); - if (material == null) { - continue; - } - - boolean draw = false; - do { - if (!isInsideCached(x + 1, y, z, pattern)) { - draw = true; - break; - } - if (!isInsideCached(x - 1, y, z, pattern)) { - draw = true; - break; - } - if (!isInsideCached(x, y, z + 1, pattern)) { - draw = true; - break; - } - if (!isInsideCached(x, y, z - 1, pattern)) { - draw = true; - break; - } - if (!isInsideCached(x, y + 1, z, pattern)) { - draw = true; - break; - } - if (!isInsideCached(x, y - 1, z, pattern)) { - draw = true; - break; - } - } while (false); - - if (!draw) { - continue; - } - - if (editSession.setBlock(position, material)) { - ++affected; - } - } - - return affected; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.regions.shape; + +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.patterns.Pattern; +import com.sk89q.worldedit.regions.Region; + +/** + * Generates solid and hollow shapes according to materials returned by the + * {@link #getMaterial} method. + * + * @author TomyLobo + */ +public abstract class ArbitraryShape { + protected final Region extent; + private int cacheOffsetX; + private int cacheOffsetY; + private int cacheOffsetZ; + @SuppressWarnings("FieldCanBeLocal") + private int cacheSizeX; + private int cacheSizeY; + private int cacheSizeZ; + + public ArbitraryShape(Region extent) { + this.extent = extent; + + Vector min = extent.getMinimumPoint(); + Vector max = extent.getMaximumPoint(); + + cacheOffsetX = min.getBlockX() - 1; + cacheOffsetY = min.getBlockY() - 1; + cacheOffsetZ = min.getBlockZ() - 1; + + cacheSizeX = (int) (max.getX() - cacheOffsetX + 2); + cacheSizeY = (int) (max.getY() - cacheOffsetY + 2); + cacheSizeZ = (int) (max.getZ() - cacheOffsetZ + 2); + + cache = new short[cacheSizeX * cacheSizeY * cacheSizeZ]; + } + + protected Region getExtent() { + return extent; + } + + + /** + * Cache entries: + * 0 = unknown + * -1 = outside + * -2 = inside but type and data 0 + * > 0 = inside, value = (type | (data << 8)), not handling data < 0 + */ + private final short[] cache; + + /** + * Override this function to specify the shape to generate. + * + * @param x X coordinate to be queried + * @param y Y coordinate to be queried + * @param z Z coordinate to be queried + * @param defaultMaterial The material returned by the pattern for the current block. + * @return material to place or null to not place anything. + */ + protected abstract BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial); + + private BaseBlock getMaterialCached(int x, int y, int z, Pattern pattern) { + final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ; + + final short cacheEntry = cache[index]; + switch (cacheEntry) { + case 0: + // unknown, fetch material + final BaseBlock material = getMaterial(x, y, z, pattern.next(new BlockVector(x, y, z))); + if (material == null) { + // outside + cache[index] = -1; + return null; + } + + short newCacheEntry = (short) (material.getType() | ((material.getData() + 1) << 8)); + if (newCacheEntry == 0) { + // type and data 0 + newCacheEntry = -2; + } + + cache[index] = newCacheEntry; + return material; + + case -1: + // outside + return null; + + case -2: + // type and data 0 + return new BaseBlock(0, 0); + } + + return new BaseBlock(cacheEntry & 255, ((cacheEntry >> 8) - 1) & 15); + } + + private boolean isInsideCached(int x, int y, int z, Pattern pattern) { + final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ; + + switch (cache[index]) { + case 0: + // unknown block, meaning they must be outside the extent at this stage, but might still be inside the shape + return getMaterialCached(x, y, z, pattern) != null; + + case -1: + // outside + return false; + + default: + // inside + return true; + } + } + + /** + * Generates the shape. + * + * @param editSession The EditSession to use. + * @param pattern The pattern to generate default materials from. + * @param hollow Specifies whether to generate a hollow shape. + * @return number of affected blocks. + * @throws MaxChangedBlocksException + */ + public int generate(EditSession editSession, Pattern pattern, boolean hollow) throws MaxChangedBlocksException { + int affected = 0; + + for (BlockVector position : getExtent()) { + int x = position.getBlockX(); + int y = position.getBlockY(); + int z = position.getBlockZ(); + + if (!hollow) { + final BaseBlock material = getMaterial(x, y, z, pattern.next(position)); + if (material != null && editSession.setBlock(position, material)) { + ++affected; + } + + continue; + } + + final BaseBlock material = getMaterialCached(x, y, z, pattern); + if (material == null) { + continue; + } + + boolean draw = false; + do { + if (!isInsideCached(x + 1, y, z, pattern)) { + draw = true; + break; + } + if (!isInsideCached(x - 1, y, z, pattern)) { + draw = true; + break; + } + if (!isInsideCached(x, y, z + 1, pattern)) { + draw = true; + break; + } + if (!isInsideCached(x, y, z - 1, pattern)) { + draw = true; + break; + } + if (!isInsideCached(x, y + 1, z, pattern)) { + draw = true; + break; + } + if (!isInsideCached(x, y - 1, z, pattern)) { + draw = true; + break; + } + } while (false); + + if (!draw) { + continue; + } + + if (editSession.setBlock(position, material)) { + ++affected; + } + } + + return affected; + } +} diff --git a/src/main/java/com/sk89q/worldedit/shape/RegionShape.java b/src/main/java/com/sk89q/worldedit/regions/shape/RegionShape.java similarity index 84% rename from src/main/java/com/sk89q/worldedit/shape/RegionShape.java rename to src/main/java/com/sk89q/worldedit/regions/shape/RegionShape.java index 74cafe2b8..caab57190 100644 --- a/src/main/java/com/sk89q/worldedit/shape/RegionShape.java +++ b/src/main/java/com/sk89q/worldedit/regions/shape/RegionShape.java @@ -1,27 +1,26 @@ -package com.sk89q.worldedit.shape; - -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.shape.ArbitraryShape; - -/** - * Generates solid and hollow shapes according to materials returned by the - * {@link #getMaterial} method. - * - * @author TomyLobo - */ -public class RegionShape extends ArbitraryShape { - public RegionShape(Region extent) { - super(extent); - } - - @Override - protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) { - if (!this.extent.contains(new Vector(x, y, z))) { - return null; - } - - return defaultMaterial; - } -} +package com.sk89q.worldedit.regions.shape; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.regions.Region; + +/** + * Generates solid and hollow shapes according to materials returned by the + * {@link #getMaterial} method. + * + * @author TomyLobo + */ +public class RegionShape extends ArbitraryShape { + public RegionShape(Region extent) { + super(extent); + } + + @Override + protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) { + if (!this.extent.contains(new Vector(x, y, z))) { + return null; + } + + return defaultMaterial; + } +} diff --git a/src/main/java/com/sk89q/worldedit/shape/WorldEditExpressionEnvironment.java b/src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/shape/WorldEditExpressionEnvironment.java rename to src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java index f026bc5f4..a81dead3f 100644 --- a/src/main/java/com/sk89q/worldedit/shape/WorldEditExpressionEnvironment.java +++ b/src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java @@ -1,62 +1,62 @@ -package com.sk89q.worldedit.shape; - -import com.sk89q.worldedit.BlockVector; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.expression.runtime.ExpressionEnvironment; - -public class WorldEditExpressionEnvironment implements ExpressionEnvironment { - private final Vector unit; - private final Vector zero2; - private Vector current = new Vector(); - private EditSession editSession; - - public WorldEditExpressionEnvironment(EditSession editSession, Vector unit, Vector zero) { - this.editSession = editSession; - this.unit = unit; - this.zero2 = zero.add(0.5, 0.5, 0.5); - } - - public BlockVector toWorld(double x, double y, double z) { - // unscale, unoffset, round-nearest - return new Vector(x, y, z).multiply(unit).add(zero2).toBlockPoint(); - } - - public Vector toWorldRel(double x, double y, double z) { - return current.add(x, y, z); - } - - @Override - public int getBlockType(double x, double y, double z) { - return editSession.getBlockType(toWorld(x, y, z)); - } - - @Override - public int getBlockData(double x, double y, double z) { - return editSession.getBlockData(toWorld(x, y, z)); - } - - @Override - public int getBlockTypeAbs(double x, double y, double z) { - return editSession.getBlockType(new Vector(x, y, z)); - } - - @Override - public int getBlockDataAbs(double x, double y, double z) { - return editSession.getBlockData(new Vector(x, y, z)); - } - - @Override - public int getBlockTypeRel(double x, double y, double z) { - return editSession.getBlockType(toWorldRel(x, y, z)); - } - - @Override - public int getBlockDataRel(double x, double y, double z) { - return editSession.getBlockData(toWorldRel(x, y, z)); - } - - public void setCurrentBlock(Vector current) { - this.current = current; - } -} +package com.sk89q.worldedit.regions.shape; + +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment; + +public class WorldEditExpressionEnvironment implements ExpressionEnvironment { + private final Vector unit; + private final Vector zero2; + private Vector current = new Vector(); + private EditSession editSession; + + public WorldEditExpressionEnvironment(EditSession editSession, Vector unit, Vector zero) { + this.editSession = editSession; + this.unit = unit; + this.zero2 = zero.add(0.5, 0.5, 0.5); + } + + public BlockVector toWorld(double x, double y, double z) { + // unscale, unoffset, round-nearest + return new Vector(x, y, z).multiply(unit).add(zero2).toBlockPoint(); + } + + public Vector toWorldRel(double x, double y, double z) { + return current.add(x, y, z); + } + + @Override + public int getBlockType(double x, double y, double z) { + return editSession.getBlockType(toWorld(x, y, z)); + } + + @Override + public int getBlockData(double x, double y, double z) { + return editSession.getBlockData(toWorld(x, y, z)); + } + + @Override + public int getBlockTypeAbs(double x, double y, double z) { + return editSession.getBlockType(new Vector(x, y, z)); + } + + @Override + public int getBlockDataAbs(double x, double y, double z) { + return editSession.getBlockData(new Vector(x, y, z)); + } + + @Override + public int getBlockTypeRel(double x, double y, double z) { + return editSession.getBlockType(toWorldRel(x, y, z)); + } + + @Override + public int getBlockDataRel(double x, double y, double z) { + return editSession.getBlockData(toWorldRel(x, y, z)); + } + + public void setCurrentBlock(Vector current) { + this.current = current; + } +} diff --git a/src/main/java/com/sk89q/worldedit/schematic/MCEditSchematicFormat.java b/src/main/java/com/sk89q/worldedit/schematic/MCEditSchematicFormat.java index d654bed5d..e6e5e1892 100644 --- a/src/main/java/com/sk89q/worldedit/schematic/MCEditSchematicFormat.java +++ b/src/main/java/com/sk89q/worldedit/schematic/MCEditSchematicFormat.java @@ -45,7 +45,7 @@ import com.sk89q.worldedit.CuboidClipboard; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.TileEntityBlock; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * @author zml2008 diff --git a/src/main/java/com/sk89q/worldedit/schematic/SchematicFormat.java b/src/main/java/com/sk89q/worldedit/schematic/SchematicFormat.java index 274611167..a630cb4c3 100644 --- a/src/main/java/com/sk89q/worldedit/schematic/SchematicFormat.java +++ b/src/main/java/com/sk89q/worldedit/schematic/SchematicFormat.java @@ -30,7 +30,7 @@ import java.util.Set; import com.sk89q.worldedit.CuboidClipboard; import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.data.DataException; +import com.sk89q.worldedit.world.DataException; /** * Represents a format that a schematic can be stored as diff --git a/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java b/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java index f07ec4321..50e1ecf5f 100644 --- a/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java +++ b/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java @@ -35,7 +35,7 @@ import com.sk89q.worldedit.UnknownItemException; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.commands.InsufficientArgumentsException; +import com.sk89q.worldedit.command.InsufficientArgumentsException; import com.sk89q.worldedit.patterns.Pattern; /** diff --git a/src/main/java/com/sk89q/worldedit/Countable.java b/src/main/java/com/sk89q/worldedit/util/Countable.java similarity index 98% rename from src/main/java/com/sk89q/worldedit/Countable.java rename to src/main/java/com/sk89q/worldedit/util/Countable.java index ddadfc66b..bd8a24a74 100644 --- a/src/main/java/com/sk89q/worldedit/Countable.java +++ b/src/main/java/com/sk89q/worldedit/util/Countable.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit; +package com.sk89q.worldedit.util; /** * diff --git a/src/main/java/com/sk89q/worldedit/LogFormat.java b/src/main/java/com/sk89q/worldedit/util/LogFormat.java similarity index 98% rename from src/main/java/com/sk89q/worldedit/LogFormat.java rename to src/main/java/com/sk89q/worldedit/util/LogFormat.java index 513f9ce94..98e11a540 100644 --- a/src/main/java/com/sk89q/worldedit/LogFormat.java +++ b/src/main/java/com/sk89q/worldedit/util/LogFormat.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit; +package com.sk89q.worldedit.util; import java.util.logging.Formatter; import java.util.logging.LogRecord; diff --git a/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java b/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java index 9edd1ec3d..f9606eb0e 100644 --- a/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java +++ b/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java @@ -32,7 +32,7 @@ import java.util.Set; import com.sk89q.util.StringUtil; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.snapshots.SnapshotRepository; +import com.sk89q.worldedit.world.snapshot.SnapshotRepository; /** * Simple LocalConfiguration that loads settings using diff --git a/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java b/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java index b15ec4d10..a5ddf9ae3 100644 --- a/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java +++ b/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java @@ -26,7 +26,7 @@ import java.util.logging.Logger; import com.sk89q.util.yaml.YAMLProcessor; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.snapshots.SnapshotRepository; +import com.sk89q.worldedit.world.snapshot.SnapshotRepository; /** * A less simple implementation of {@link LocalConfiguration} using YAML configuration files. diff --git a/src/main/java/com/sk89q/worldedit/data/ForwardSeekableInputStream.java b/src/main/java/com/sk89q/worldedit/util/io/ForwardSeekableInputStream.java similarity index 94% rename from src/main/java/com/sk89q/worldedit/data/ForwardSeekableInputStream.java rename to src/main/java/com/sk89q/worldedit/util/io/ForwardSeekableInputStream.java index d23ff34c3..cf70fb736 100644 --- a/src/main/java/com/sk89q/worldedit/data/ForwardSeekableInputStream.java +++ b/src/main/java/com/sk89q/worldedit/util/io/ForwardSeekableInputStream.java @@ -1,102 +1,102 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.data; - -import java.io.IOException; -import java.io.InputStream; - -public class ForwardSeekableInputStream extends InputStream { - - protected InputStream parent; - protected long position = 0; - - public ForwardSeekableInputStream(InputStream parent) { - this.parent = parent; - } - - @Override - public int read() throws IOException { - int ret = parent.read(); - ++position; - return ret; - } - - @Override - public int available() throws IOException { - return parent.available(); - } - - @Override - public void close() throws IOException { - parent.close(); - } - - @Override - public synchronized void mark(int readlimit) { - parent.mark(readlimit); - } - - @Override - public boolean markSupported() { - return parent.markSupported(); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - int read = super.read(b, off, len); - position += read; - return read; - } - - @Override - public int read(byte[] b) throws IOException { - int read = parent.read(b); - position += read; - return read; - } - - @Override - public synchronized void reset() throws IOException { - parent.reset(); - } - - @Override - public long skip(long n) throws IOException { - long skipped = parent.skip(n); - position += skipped; - return skipped; - } - - public void seek(long n) throws IOException { - long diff = n - position; - - if (diff < 0) { - throw new IOException("Can't seek backwards"); - } - - if (diff == 0) { - return; - } - - if (skip(diff) < diff) { - throw new IOException("Failed to seek " + diff + " bytes"); - } - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.util.io; + +import java.io.IOException; +import java.io.InputStream; + +public class ForwardSeekableInputStream extends InputStream { + + protected InputStream parent; + protected long position = 0; + + public ForwardSeekableInputStream(InputStream parent) { + this.parent = parent; + } + + @Override + public int read() throws IOException { + int ret = parent.read(); + ++position; + return ret; + } + + @Override + public int available() throws IOException { + return parent.available(); + } + + @Override + public void close() throws IOException { + parent.close(); + } + + @Override + public synchronized void mark(int readlimit) { + parent.mark(readlimit); + } + + @Override + public boolean markSupported() { + return parent.markSupported(); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + int read = super.read(b, off, len); + position += read; + return read; + } + + @Override + public int read(byte[] b) throws IOException { + int read = parent.read(b); + position += read; + return read; + } + + @Override + public synchronized void reset() throws IOException { + parent.reset(); + } + + @Override + public long skip(long n) throws IOException { + long skipped = parent.skip(n); + position += skipped; + return skipped; + } + + public void seek(long n) throws IOException { + long diff = n - position; + + if (diff < 0) { + throw new IOException("Can't seek backwards"); + } + + if (diff == 0) { + return; + } + + if (skip(diff) < diff) { + throw new IOException("Failed to seek " + diff + " bytes"); + } + } +} diff --git a/src/main/java/com/sk89q/worldedit/data/DataException.java b/src/main/java/com/sk89q/worldedit/world/DataException.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/data/DataException.java rename to src/main/java/com/sk89q/worldedit/world/DataException.java index 535f37aac..376e9666d 100644 --- a/src/main/java/com/sk89q/worldedit/data/DataException.java +++ b/src/main/java/com/sk89q/worldedit/world/DataException.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world; /** * Thrown when there is an exception related to data handling. diff --git a/src/main/java/com/sk89q/worldedit/data/AnvilChunk.java b/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java similarity index 98% rename from src/main/java/com/sk89q/worldedit/data/AnvilChunk.java rename to src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java index 25fdf46cf..34b4a23f3 100644 --- a/src/main/java/com/sk89q/worldedit/data/AnvilChunk.java +++ b/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java @@ -1,4 +1,4 @@ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.chunk; import java.util.HashMap; import java.util.List; @@ -16,6 +16,8 @@ import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.TileEntityBlock; +import com.sk89q.worldedit.world.DataException; +import com.sk89q.worldedit.world.storage.InvalidFormatException; public class AnvilChunk implements Chunk { diff --git a/src/main/java/com/sk89q/worldedit/data/Chunk.java b/src/main/java/com/sk89q/worldedit/world/chunk/Chunk.java similarity index 88% rename from src/main/java/com/sk89q/worldedit/data/Chunk.java rename to src/main/java/com/sk89q/worldedit/world/chunk/Chunk.java index e0fd98867..c566ea881 100644 --- a/src/main/java/com/sk89q/worldedit/data/Chunk.java +++ b/src/main/java/com/sk89q/worldedit/world/chunk/Chunk.java @@ -1,7 +1,8 @@ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.chunk; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.world.DataException; public interface Chunk { diff --git a/src/main/java/com/sk89q/worldedit/data/OldChunk.java b/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/data/OldChunk.java rename to src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java index 3a2fb8a9c..ffd9fe9ad 100644 --- a/src/main/java/com/sk89q/worldedit/data/OldChunk.java +++ b/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java @@ -17,23 +17,20 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.chunk; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.sk89q.jnbt.ByteArrayTag; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.NBTUtils; -import com.sk89q.jnbt.Tag; +import com.sk89q.jnbt.*; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.TileEntityBlock; +import com.sk89q.worldedit.world.DataException; +import com.sk89q.worldedit.world.storage.InvalidFormatException; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Represents a chunk. diff --git a/src/main/java/com/sk89q/worldedit/snapshots/InvalidSnapshotException.java b/src/main/java/com/sk89q/worldedit/world/snapshot/InvalidSnapshotException.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/snapshots/InvalidSnapshotException.java rename to src/main/java/com/sk89q/worldedit/world/snapshot/InvalidSnapshotException.java index 19af8c238..5cc922437 100644 --- a/src/main/java/com/sk89q/worldedit/snapshots/InvalidSnapshotException.java +++ b/src/main/java/com/sk89q/worldedit/world/snapshot/InvalidSnapshotException.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.snapshots; +package com.sk89q.worldedit.world.snapshot; /** * diff --git a/src/main/java/com/sk89q/worldedit/snapshots/ModificationTimerParser.java b/src/main/java/com/sk89q/worldedit/world/snapshot/ModificationTimerParser.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/snapshots/ModificationTimerParser.java rename to src/main/java/com/sk89q/worldedit/world/snapshot/ModificationTimerParser.java index 1fc5aba61..c509f961b 100644 --- a/src/main/java/com/sk89q/worldedit/snapshots/ModificationTimerParser.java +++ b/src/main/java/com/sk89q/worldedit/world/snapshot/ModificationTimerParser.java @@ -1,34 +1,34 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.snapshots; - -import java.io.File; -import java.util.Calendar; -import java.util.GregorianCalendar; - -public class ModificationTimerParser implements SnapshotDateParser { - - public Calendar detectDate(File file) { - Calendar cal = new GregorianCalendar(); - cal.setTimeInMillis(file.lastModified()); - return cal; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.world.snapshot; + +import java.io.File; +import java.util.Calendar; +import java.util.GregorianCalendar; + +public class ModificationTimerParser implements SnapshotDateParser { + + public Calendar detectDate(File file) { + Calendar cal = new GregorianCalendar(); + cal.setTimeInMillis(file.lastModified()); + return cal; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/snapshots/Snapshot.java b/src/main/java/com/sk89q/worldedit/world/snapshot/Snapshot.java similarity index 97% rename from src/main/java/com/sk89q/worldedit/snapshots/Snapshot.java rename to src/main/java/com/sk89q/worldedit/world/snapshot/Snapshot.java index 872d2e70a..f06bc5038 100644 --- a/src/main/java/com/sk89q/worldedit/snapshots/Snapshot.java +++ b/src/main/java/com/sk89q/worldedit/world/snapshot/Snapshot.java @@ -16,9 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.sk89q.worldedit.snapshots; +package com.sk89q.worldedit.world.snapshot; -import com.sk89q.worldedit.data.*; +import com.sk89q.worldedit.world.DataException; +import com.sk89q.worldedit.world.storage.*; import java.io.File; import java.io.IOException; import java.util.Calendar; diff --git a/src/main/java/com/sk89q/worldedit/snapshots/SnapshotDateParser.java b/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotDateParser.java similarity index 93% rename from src/main/java/com/sk89q/worldedit/snapshots/SnapshotDateParser.java rename to src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotDateParser.java index 92938eb24..d5e958bb8 100644 --- a/src/main/java/com/sk89q/worldedit/snapshots/SnapshotDateParser.java +++ b/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotDateParser.java @@ -1,38 +1,38 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.snapshots; - -import java.io.File; -import java.util.Calendar; - -/** - * A name parser attempts to make sense of a filename for a snapshot. - * - * @author sk89q - */ -public interface SnapshotDateParser { - /** - * Attempt to detect a date from a file. - * - * @param file - * @return date or null - */ - public Calendar detectDate(File file); -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.world.snapshot; + +import java.io.File; +import java.util.Calendar; + +/** + * A name parser attempts to make sense of a filename for a snapshot. + * + * @author sk89q + */ +public interface SnapshotDateParser { + /** + * Attempt to detect a date from a file. + * + * @param file + * @return date or null + */ + public Calendar detectDate(File file); +} diff --git a/src/main/java/com/sk89q/worldedit/snapshots/SnapshotRepository.java b/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRepository.java similarity index 98% rename from src/main/java/com/sk89q/worldedit/snapshots/SnapshotRepository.java rename to src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRepository.java index 1ebdf8804..738b1f524 100644 --- a/src/main/java/com/sk89q/worldedit/snapshots/SnapshotRepository.java +++ b/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRepository.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.sk89q.worldedit.snapshots; +package com.sk89q.worldedit.world.snapshot; import java.io.File; import java.io.FilenameFilter; @@ -25,7 +25,7 @@ import java.util.Calendar; import java.util.Collections; import java.util.List; -import com.sk89q.worldedit.data.MissingWorldException; +import com.sk89q.worldedit.world.storage.MissingWorldException; /** * diff --git a/src/main/java/com/sk89q/worldedit/snapshots/SnapshotRestore.java b/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/snapshots/SnapshotRestore.java rename to src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java index 5f76d3c35..081515ead 100644 --- a/src/main/java/com/sk89q/worldedit/snapshots/SnapshotRestore.java +++ b/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.snapshots; +package com.sk89q.worldedit.world.snapshot; import java.io.IOException; import java.util.ArrayList; @@ -31,11 +31,11 @@ import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.data.Chunk; -import com.sk89q.worldedit.data.ChunkStore; -import com.sk89q.worldedit.data.DataException; -import com.sk89q.worldedit.data.MissingChunkException; -import com.sk89q.worldedit.data.MissingWorldException; +import com.sk89q.worldedit.world.chunk.Chunk; +import com.sk89q.worldedit.world.storage.ChunkStore; +import com.sk89q.worldedit.world.DataException; +import com.sk89q.worldedit.world.storage.MissingChunkException; +import com.sk89q.worldedit.world.storage.MissingWorldException; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; diff --git a/src/main/java/com/sk89q/worldedit/snapshots/YYMMDDHHIISSParser.java b/src/main/java/com/sk89q/worldedit/world/snapshot/YYMMDDHHIISSParser.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/snapshots/YYMMDDHHIISSParser.java rename to src/main/java/com/sk89q/worldedit/world/snapshot/YYMMDDHHIISSParser.java index 83c7fe491..cea6eb189 100644 --- a/src/main/java/com/sk89q/worldedit/snapshots/YYMMDDHHIISSParser.java +++ b/src/main/java/com/sk89q/worldedit/world/snapshot/YYMMDDHHIISSParser.java @@ -1,50 +1,50 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.snapshots; - -import java.io.File; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class YYMMDDHHIISSParser implements SnapshotDateParser { - - protected Pattern patt = - Pattern.compile("([0-9]+)[^0-9]?([0-9]+)[^0-9]?([0-9]+)[^0-9]?" - + "([0-9]+)[^0-9]?([0-9]+)[^0-9]?([0-9]+)"); - - public Calendar detectDate(File file) { - Matcher matcher = patt.matcher(file.getName()); - if (matcher.matches()) { - int year = Integer.parseInt(matcher.group(1)); - int month = Integer.parseInt(matcher.group(2)); - int day = Integer.parseInt(matcher.group(3)); - int hrs = Integer.parseInt(matcher.group(4)); - int min = Integer.parseInt(matcher.group(5)); - int sec = Integer.parseInt(matcher.group(6)); - Calendar calender = new GregorianCalendar(); - calender.set(year, month, day, hrs, min, sec); - return calender; - } - return null; - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.world.snapshot; + +import java.io.File; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class YYMMDDHHIISSParser implements SnapshotDateParser { + + protected Pattern patt = + Pattern.compile("([0-9]+)[^0-9]?([0-9]+)[^0-9]?([0-9]+)[^0-9]?" + + "([0-9]+)[^0-9]?([0-9]+)[^0-9]?([0-9]+)"); + + public Calendar detectDate(File file) { + Matcher matcher = patt.matcher(file.getName()); + if (matcher.matches()) { + int year = Integer.parseInt(matcher.group(1)); + int month = Integer.parseInt(matcher.group(2)); + int day = Integer.parseInt(matcher.group(3)); + int hrs = Integer.parseInt(matcher.group(4)); + int min = Integer.parseInt(matcher.group(5)); + int sec = Integer.parseInt(matcher.group(6)); + Calendar calender = new GregorianCalendar(); + calender.set(year, month, day, hrs, min, sec); + return calender; + } + return null; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/data/BlockData.java b/src/main/java/com/sk89q/worldedit/world/storage/BlockData.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/data/BlockData.java rename to src/main/java/com/sk89q/worldedit/world/storage/BlockData.java index 62c2bc8f0..ea0fc7718 100644 --- a/src/main/java/com/sk89q/worldedit/data/BlockData.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/BlockData.java @@ -1,124 +1,124 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.data; - -import com.sk89q.worldedit.CuboidClipboard.FlipDirection; - -/** - * Block data related classes. - * - * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData} - * @author sk89q - */ -@Deprecated -public final class BlockData { - /** - * Rotate a block's data value 90 degrees (north->east->south->west->north); - * - * @param type - * @param data - * @return - * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#rotate90(int, int)} - */ - @Deprecated - public static int rotate90(int type, int data) { - return com.sk89q.worldedit.blocks.BlockData.rotate90(type, data); - } - - /** - * Rotate a block's data value -90 degrees (north<-east<-south<-west<-north); - * - * @param type - * @param data - * @return - * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#rotate90Reverse(int, int)} - */ - @Deprecated - public static int rotate90Reverse(int type, int data) { - return com.sk89q.worldedit.blocks.BlockData.rotate90Reverse(type, data); - } - - /** - * Flip a block's data value. - * - * @param type - * @param data - * @return - * @deprecated use return {@link com.sk89q.worldedit.blocks.BlockData#flip(int, int)} - */ - @Deprecated - public static int flip(int type, int data) { - return rotate90(type, rotate90(type, data)); - } - - /** - * Flip a block's data value. - * - * @param type - * @param data - * @param direction - * @return - * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#flip(int, int, FlipDirection)} - */ - @Deprecated - public static int flip(int type, int data, FlipDirection direction) { - return com.sk89q.worldedit.blocks.BlockData.flip(type, data, direction); - } - - /** - * Cycle a block's data value. This usually goes through some rotational pattern - * depending on the block. If it returns -1, it means the id and data specified - * do not have anything to cycle to. - * - * @param type block id to be cycled - * @param data block data value that it starts at - * @param increment whether to go forward (1) or backward (-1) in the cycle - * @return the new data value for the block - * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#cycle(int, int, int)} - */ - @Deprecated - public static int cycle(int type, int data, int increment) { - return com.sk89q.worldedit.blocks.BlockData.cycle(type, data, increment); - } - - /** - * Returns the data value for the next color of cloth in the rainbow. This - * should not be used if you want to just increment the data value. - * @param data - * @return - * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#nextClothColor(int)} - */ - @Deprecated - public static int nextClothColor(int data) { - return com.sk89q.worldedit.blocks.BlockData.nextClothColor(data); - } - - /** - * Returns the data value for the previous ext color of cloth in the rainbow. - * This should not be used if you want to just increment the data value. - * @param data - * @return - * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#prevClothColor(int)} - */ - @Deprecated - public static int prevClothColor(int data) { - return com.sk89q.worldedit.blocks.BlockData.prevClothColor(data); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.world.storage; + +import com.sk89q.worldedit.CuboidClipboard.FlipDirection; + +/** + * Block data related classes. + * + * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData} + * @author sk89q + */ +@Deprecated +public final class BlockData { + /** + * Rotate a block's data value 90 degrees (north->east->south->west->north); + * + * @param type + * @param data + * @return + * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#rotate90(int, int)} + */ + @Deprecated + public static int rotate90(int type, int data) { + return com.sk89q.worldedit.blocks.BlockData.rotate90(type, data); + } + + /** + * Rotate a block's data value -90 degrees (north<-east<-south<-west<-north); + * + * @param type + * @param data + * @return + * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#rotate90Reverse(int, int)} + */ + @Deprecated + public static int rotate90Reverse(int type, int data) { + return com.sk89q.worldedit.blocks.BlockData.rotate90Reverse(type, data); + } + + /** + * Flip a block's data value. + * + * @param type + * @param data + * @return + * @deprecated use return {@link com.sk89q.worldedit.blocks.BlockData#flip(int, int)} + */ + @Deprecated + public static int flip(int type, int data) { + return rotate90(type, rotate90(type, data)); + } + + /** + * Flip a block's data value. + * + * @param type + * @param data + * @param direction + * @return + * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#flip(int, int, FlipDirection)} + */ + @Deprecated + public static int flip(int type, int data, FlipDirection direction) { + return com.sk89q.worldedit.blocks.BlockData.flip(type, data, direction); + } + + /** + * Cycle a block's data value. This usually goes through some rotational pattern + * depending on the block. If it returns -1, it means the id and data specified + * do not have anything to cycle to. + * + * @param type block id to be cycled + * @param data block data value that it starts at + * @param increment whether to go forward (1) or backward (-1) in the cycle + * @return the new data value for the block + * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#cycle(int, int, int)} + */ + @Deprecated + public static int cycle(int type, int data, int increment) { + return com.sk89q.worldedit.blocks.BlockData.cycle(type, data, increment); + } + + /** + * Returns the data value for the next color of cloth in the rainbow. This + * should not be used if you want to just increment the data value. + * @param data + * @return + * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#nextClothColor(int)} + */ + @Deprecated + public static int nextClothColor(int data) { + return com.sk89q.worldedit.blocks.BlockData.nextClothColor(data); + } + + /** + * Returns the data value for the previous ext color of cloth in the rainbow. + * This should not be used if you want to just increment the data value. + * @param data + * @return + * @deprecated use {@link com.sk89q.worldedit.blocks.BlockData#prevClothColor(int)} + */ + @Deprecated + public static int prevClothColor(int data) { + return com.sk89q.worldedit.blocks.BlockData.prevClothColor(data); + } +} diff --git a/src/main/java/com/sk89q/worldedit/data/ChunkStore.java b/src/main/java/com/sk89q/worldedit/world/storage/ChunkStore.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/data/ChunkStore.java rename to src/main/java/com/sk89q/worldedit/world/storage/ChunkStore.java index d977f7516..421217684 100644 --- a/src/main/java/com/sk89q/worldedit/data/ChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/ChunkStore.java @@ -17,13 +17,17 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.storage; import java.io.IOException; import java.util.Map; import com.sk89q.jnbt.*; import com.sk89q.worldedit.*; +import com.sk89q.worldedit.world.DataException; +import com.sk89q.worldedit.world.chunk.AnvilChunk; +import com.sk89q.worldedit.world.chunk.Chunk; +import com.sk89q.worldedit.world.chunk.OldChunk; /** * Represents chunk storage mechanisms. diff --git a/src/main/java/com/sk89q/worldedit/data/ChunkStoreException.java b/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreException.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/data/ChunkStoreException.java rename to src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreException.java index 2cc4dfbda..ca2090e95 100644 --- a/src/main/java/com/sk89q/worldedit/data/ChunkStoreException.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreException.java @@ -17,7 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.storage; + +import com.sk89q.worldedit.world.DataException; /** * diff --git a/src/main/java/com/sk89q/worldedit/data/FileLegacyChunkStore.java b/src/main/java/com/sk89q/worldedit/world/storage/FileLegacyChunkStore.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/data/FileLegacyChunkStore.java rename to src/main/java/com/sk89q/worldedit/world/storage/FileLegacyChunkStore.java index 614f2ad76..de02fcd46 100644 --- a/src/main/java/com/sk89q/worldedit/data/FileLegacyChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/FileLegacyChunkStore.java @@ -17,7 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.storage; + +import com.sk89q.worldedit.world.DataException; import java.io.File; import java.io.FileInputStream; diff --git a/src/main/java/com/sk89q/worldedit/data/FileMcRegionChunkStore.java b/src/main/java/com/sk89q/worldedit/world/storage/FileMcRegionChunkStore.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/data/FileMcRegionChunkStore.java rename to src/main/java/com/sk89q/worldedit/world/storage/FileMcRegionChunkStore.java index f244da89c..82094016a 100644 --- a/src/main/java/com/sk89q/worldedit/data/FileMcRegionChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/FileMcRegionChunkStore.java @@ -1,73 +1,75 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.data; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.regex.Pattern; - -public class FileMcRegionChunkStore extends McRegionChunkStore { - /** - * Folder to read from. - */ - private File path; - - /** - * Create an instance. The passed path is the folder to read the - * chunk files from. - * - * @param path - */ - public FileMcRegionChunkStore(File path) { - this.path = path; - } - - @Override - protected InputStream getInputStream(String name, String world) throws IOException, - DataException { - Pattern ext = Pattern.compile(".*\\.mc[ra]$"); // allow either file extension, both work the same - File file = null; - for (File f : new File(path, "region" + File.separator).listFiles()) { - String tempName = f.getName().replaceFirst("mcr$", "mca"); // matcher only does one at a time - if (ext.matcher(f.getName()).matches() && name.equalsIgnoreCase(tempName)) { - // get full original path now - file = new File(path + File.separator + "region" + File.separator + f.getName()); - break; - } - } - - try { - if (file == null) throw new FileNotFoundException(); - return new FileInputStream(file); - } catch (FileNotFoundException e) { - throw new MissingChunkException(); - } - } - - @Override - public boolean isValid() { - return new File(path, "region").isDirectory() || - new File(path, "DIM-1" + File.separator + "region").isDirectory(); - } - -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.world.storage; + +import com.sk89q.worldedit.world.DataException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.regex.Pattern; + +public class FileMcRegionChunkStore extends McRegionChunkStore { + /** + * Folder to read from. + */ + private File path; + + /** + * Create an instance. The passed path is the folder to read the + * chunk files from. + * + * @param path + */ + public FileMcRegionChunkStore(File path) { + this.path = path; + } + + @Override + protected InputStream getInputStream(String name, String world) throws IOException, + DataException { + Pattern ext = Pattern.compile(".*\\.mc[ra]$"); // allow either file extension, both work the same + File file = null; + for (File f : new File(path, "region" + File.separator).listFiles()) { + String tempName = f.getName().replaceFirst("mcr$", "mca"); // matcher only does one at a time + if (ext.matcher(f.getName()).matches() && name.equalsIgnoreCase(tempName)) { + // get full original path now + file = new File(path + File.separator + "region" + File.separator + f.getName()); + break; + } + } + + try { + if (file == null) throw new FileNotFoundException(); + return new FileInputStream(file); + } catch (FileNotFoundException e) { + throw new MissingChunkException(); + } + } + + @Override + public boolean isValid() { + return new File(path, "region").isDirectory() || + new File(path, "DIM-1" + File.separator + "region").isDirectory(); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/data/InvalidFormatException.java b/src/main/java/com/sk89q/worldedit/world/storage/InvalidFormatException.java similarity index 91% rename from src/main/java/com/sk89q/worldedit/data/InvalidFormatException.java rename to src/main/java/com/sk89q/worldedit/world/storage/InvalidFormatException.java index 4e9c07c4a..010b23b29 100644 --- a/src/main/java/com/sk89q/worldedit/data/InvalidFormatException.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/InvalidFormatException.java @@ -17,7 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.storage; + +import com.sk89q.worldedit.world.DataException; /** * diff --git a/src/main/java/com/sk89q/worldedit/data/LegacyChunkStore.java b/src/main/java/com/sk89q/worldedit/world/storage/LegacyChunkStore.java similarity index 98% rename from src/main/java/com/sk89q/worldedit/data/LegacyChunkStore.java rename to src/main/java/com/sk89q/worldedit/world/storage/LegacyChunkStore.java index 2107404db..d6e66f4da 100644 --- a/src/main/java/com/sk89q/worldedit/data/LegacyChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/LegacyChunkStore.java @@ -17,12 +17,14 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.storage; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.*; +import com.sk89q.worldedit.world.DataException; + import java.io.File; import java.io.IOException; import java.io.InputStream; diff --git a/src/main/java/com/sk89q/worldedit/data/McRegionChunkStore.java b/src/main/java/com/sk89q/worldedit/world/storage/McRegionChunkStore.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/data/McRegionChunkStore.java rename to src/main/java/com/sk89q/worldedit/world/storage/McRegionChunkStore.java index 58c161f7b..428fac7d6 100644 --- a/src/main/java/com/sk89q/worldedit/data/McRegionChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/McRegionChunkStore.java @@ -1,132 +1,133 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -package com.sk89q.worldedit.data; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.NBTInputStream; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.LocalWorld; -import com.sk89q.worldedit.Vector2D; - -public abstract class McRegionChunkStore extends ChunkStore { - protected String curFilename = null; - protected McRegionReader cachedReader = null; - - /** - * Get the filename of a region file. - * - * @param pos - * @return - */ - public static String getFilename(Vector2D pos) { - int x = pos.getBlockX(); - int z = pos.getBlockZ(); - - String filename = "r." + (x >> 5) + "." + (z >> 5) + ".mca"; - - return filename; - } - - protected McRegionReader getReader(Vector2D pos, String worldname) throws DataException, IOException { - String filename = getFilename(pos); - if (curFilename != null) { - if (curFilename.equals(filename)) { - return cachedReader; - } else { - try { - cachedReader.close(); - } catch (IOException e) { - } - } - } - InputStream stream = getInputStream(filename, worldname); - cachedReader = new McRegionReader(stream); - //curFilename = filename; - return cachedReader; - } - - @Override - public CompoundTag getChunkTag(Vector2D pos, LocalWorld world) throws DataException, - IOException { - - McRegionReader reader = getReader(pos, world.getName()); - - InputStream stream = reader.getChunkInputStream(pos); - NBTInputStream nbt = new NBTInputStream(stream); - Tag tag; - - try { - tag = nbt.readTag(); - if (!(tag instanceof CompoundTag)) { - throw new ChunkStoreException("CompoundTag expected for chunk; got " - + tag.getClass().getName()); - } - - Map children = (Map) ((CompoundTag) tag).getValue(); - CompoundTag rootTag = null; - - // Find Level tag - for (Map.Entry entry : children.entrySet()) { - if (entry.getKey().equals("Level")) { - if (entry.getValue() instanceof CompoundTag) { - rootTag = (CompoundTag) entry.getValue(); - break; - } else { - throw new ChunkStoreException("CompoundTag expected for 'Level'; got " - + entry.getValue().getClass().getName()); - } - } - } - - if (rootTag == null) { - throw new ChunkStoreException("Missing root 'Level' tag"); - } - - return rootTag; - } finally { - nbt.close(); - } - } - - /** - * Get the input stream for a chunk file. - * - * @param name - * @return - * @throws IOException - */ - protected abstract InputStream getInputStream(String name, String worldname) - throws IOException, DataException; - - /** - * Close resources. - * - * @throws IOException - */ - @Override - public void close() throws IOException { - if (cachedReader != null) { - cachedReader.close(); - } - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.worldedit.world.storage; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.NBTInputStream; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.world.DataException; + +public abstract class McRegionChunkStore extends ChunkStore { + protected String curFilename = null; + protected McRegionReader cachedReader = null; + + /** + * Get the filename of a region file. + * + * @param pos + * @return + */ + public static String getFilename(Vector2D pos) { + int x = pos.getBlockX(); + int z = pos.getBlockZ(); + + String filename = "r." + (x >> 5) + "." + (z >> 5) + ".mca"; + + return filename; + } + + protected McRegionReader getReader(Vector2D pos, String worldname) throws DataException, IOException { + String filename = getFilename(pos); + if (curFilename != null) { + if (curFilename.equals(filename)) { + return cachedReader; + } else { + try { + cachedReader.close(); + } catch (IOException e) { + } + } + } + InputStream stream = getInputStream(filename, worldname); + cachedReader = new McRegionReader(stream); + //curFilename = filename; + return cachedReader; + } + + @Override + public CompoundTag getChunkTag(Vector2D pos, LocalWorld world) throws DataException, + IOException { + + McRegionReader reader = getReader(pos, world.getName()); + + InputStream stream = reader.getChunkInputStream(pos); + NBTInputStream nbt = new NBTInputStream(stream); + Tag tag; + + try { + tag = nbt.readTag(); + if (!(tag instanceof CompoundTag)) { + throw new ChunkStoreException("CompoundTag expected for chunk; got " + + tag.getClass().getName()); + } + + Map children = (Map) ((CompoundTag) tag).getValue(); + CompoundTag rootTag = null; + + // Find Level tag + for (Map.Entry entry : children.entrySet()) { + if (entry.getKey().equals("Level")) { + if (entry.getValue() instanceof CompoundTag) { + rootTag = (CompoundTag) entry.getValue(); + break; + } else { + throw new ChunkStoreException("CompoundTag expected for 'Level'; got " + + entry.getValue().getClass().getName()); + } + } + } + + if (rootTag == null) { + throw new ChunkStoreException("Missing root 'Level' tag"); + } + + return rootTag; + } finally { + nbt.close(); + } + } + + /** + * Get the input stream for a chunk file. + * + * @param name + * @return + * @throws IOException + */ + protected abstract InputStream getInputStream(String name, String worldname) + throws IOException, DataException; + + /** + * Close resources. + * + * @throws IOException + */ + @Override + public void close() throws IOException { + if (cachedReader != null) { + cachedReader.close(); + } + } +} diff --git a/src/main/java/com/sk89q/worldedit/data/McRegionReader.java b/src/main/java/com/sk89q/worldedit/world/storage/McRegionReader.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/data/McRegionReader.java rename to src/main/java/com/sk89q/worldedit/world/storage/McRegionReader.java index 743bdfebf..07eb21f32 100644 --- a/src/main/java/com/sk89q/worldedit/data/McRegionReader.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/McRegionReader.java @@ -1,202 +1,204 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -/* - - Region File Format - - Concept: The minimum unit of storage on hard drives is 4KB. 90% of Minecraft - chunks are smaller than 4KB. 99% are smaller than 8KB. Write a simple - container to store chunks in single files in runs of 4KB sectors. - - Each region file represents a 32x32 group of chunks. The conversion from - chunk number to region number is floor(coord / 32): a chunk at (30, -3) - would be in region (0, -1), and one at (70, -30) would be at (3, -1). - Region files are named "r.x.z.data", where x and z are the region coordinates. - - A region file begins with a 4KB header that describes where chunks are stored - in the file. A 4-byte big-endian integer represents sector offsets and sector - counts. The chunk offset for a chunk (x, z) begins at byte 4*(x+z*32) in the - file. The bottom byte of the chunk offset indicates the number of sectors the - chunk takes up, and the top 3 bytes represent the sector number of the chunk. - Given a chunk offset o, the chunk data begins at byte 4096*(o/256) and takes up - at most 4096*(o%256) bytes. A chunk cannot exceed 1MB in size. If a chunk - offset is 0, the corresponding chunk is not stored in the region file. - - Chunk data begins with a 4-byte big-endian integer representing the chunk data - length in bytes, not counting the length field. The length must be smaller than - 4096 times the number of sectors. The next byte is a version field, to allow - backwards-compatible updates to how chunks are encoded. - - A version of 1 represents a gzipped NBT file. The gzipped data is the chunk - length - 1. - - A version of 2 represents a deflated (zlib compressed) NBT file. The deflated - data is the chunk length - 1. - - */ - -package com.sk89q.worldedit.data; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.GZIPInputStream; -import java.util.zip.InflaterInputStream; - -import com.sk89q.worldedit.Vector2D; - -/** - * Reader for a MCRegion file. This reader works on input streams, meaning - * that it can be used to read files from non-file based sources. - * - * @author sk89q - */ -public class McRegionReader { - - protected static final int VERSION_GZIP = 1; - protected static final int VERSION_DEFLATE = 2; - protected static final int SECTOR_BYTES = 4096; - protected static final int SECTOR_INTS = SECTOR_BYTES / 4; - public static final int CHUNK_HEADER_SIZE = 5; - - protected ForwardSeekableInputStream stream; - protected DataInputStream dataStream; - - protected int offsets[]; - - /** - * Construct the reader. - * - * @param stream - * @throws DataException - * @throws IOException - */ - public McRegionReader(InputStream stream) throws DataException, IOException { - this.stream = new ForwardSeekableInputStream(stream); - this.dataStream = new DataInputStream(this.stream); - - readHeader(); - } - - /** - * Read the header. - * - * @throws DataException - * @throws IOException - */ - private void readHeader() throws DataException, IOException { - offsets = new int[SECTOR_INTS]; - - for (int i = 0; i < SECTOR_INTS; ++i) { - int offset = dataStream.readInt(); - offsets[i] = offset; - } - } - - /** - * Gets the uncompressed data input stream for a chunk. - * - * @param pos - * @return - * @throws IOException - * @throws DataException - */ - public synchronized InputStream getChunkInputStream(Vector2D pos) - throws IOException, DataException { - - int x = pos.getBlockX() & 31; - int z = pos.getBlockZ() & 31; - - if (x < 0 || x >= 32 || z < 0 || z >= 32) { - throw new DataException("MCRegion file does not contain " + x + "," + z); - } - - int offset = getOffset(x, z); - - // The chunk hasn't been generated - if (offset == 0) { - throw new DataException("The chunk at " + x + "," + z + " is not generated"); - } - - int sectorNumber = offset >> 8; - int numSectors = offset & 0xFF; - - stream.seek(sectorNumber * SECTOR_BYTES); - int length = dataStream.readInt(); - - if (length > SECTOR_BYTES * numSectors) { - throw new DataException("MCRegion chunk at " - + x + "," + z + " has an invalid length of " + length); - } - - byte version = dataStream.readByte(); - - if (version == VERSION_GZIP) { - byte[] data = new byte[length - 1]; - if (dataStream.read(data) < length - 1) { - throw new DataException("MCRegion file does not contain " - + x + "," + z + " in full"); - } - return new GZIPInputStream(new ByteArrayInputStream(data)); - } else if (version == VERSION_DEFLATE) { - byte[] data = new byte[length - 1]; - if (dataStream.read(data) < length - 1) { - throw new DataException("MCRegion file does not contain " - + x + "," + z + " in full"); - } - return new InflaterInputStream(new ByteArrayInputStream(data)); - } else { - throw new DataException("MCRegion chunk at " - + x + "," + z + " has an unsupported version of " + version); - } - } - - /** - * Get the offset for a chunk. May return 0 if it doesn't exist. - * - * @param x - * @param z - * @return - */ - private int getOffset(int x, int z) { - return offsets[x + z * 32]; - } - - /** - * Returns whether the file contains a chunk. - * - * @param x - * @param z - * @return - */ - public boolean hasChunk(int x, int z) { - return getOffset(x, z) != 0; - } - - /** - * Close the stream. - * - * @throws IOException - */ - public void close() throws IOException { - stream.close(); - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +/* + + Region File Format + + Concept: The minimum unit of storage on hard drives is 4KB. 90% of Minecraft + chunks are smaller than 4KB. 99% are smaller than 8KB. Write a simple + container to store chunks in single files in runs of 4KB sectors. + + Each region file represents a 32x32 group of chunks. The conversion from + chunk number to region number is floor(coord / 32): a chunk at (30, -3) + would be in region (0, -1), and one at (70, -30) would be at (3, -1). + Region files are named "r.x.z.data", where x and z are the region coordinates. + + A region file begins with a 4KB header that describes where chunks are stored + in the file. A 4-byte big-endian integer represents sector offsets and sector + counts. The chunk offset for a chunk (x, z) begins at byte 4*(x+z*32) in the + file. The bottom byte of the chunk offset indicates the number of sectors the + chunk takes up, and the top 3 bytes represent the sector number of the chunk. + Given a chunk offset o, the chunk data begins at byte 4096*(o/256) and takes up + at most 4096*(o%256) bytes. A chunk cannot exceed 1MB in size. If a chunk + offset is 0, the corresponding chunk is not stored in the region file. + + Chunk data begins with a 4-byte big-endian integer representing the chunk data + length in bytes, not counting the length field. The length must be smaller than + 4096 times the number of sectors. The next byte is a version field, to allow + backwards-compatible updates to how chunks are encoded. + + A version of 1 represents a gzipped NBT file. The gzipped data is the chunk + length - 1. + + A version of 2 represents a deflated (zlib compressed) NBT file. The deflated + data is the chunk length - 1. + + */ + +package com.sk89q.worldedit.world.storage; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.InflaterInputStream; + +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.util.io.ForwardSeekableInputStream; +import com.sk89q.worldedit.world.DataException; + +/** + * Reader for a MCRegion file. This reader works on input streams, meaning + * that it can be used to read files from non-file based sources. + * + * @author sk89q + */ +public class McRegionReader { + + protected static final int VERSION_GZIP = 1; + protected static final int VERSION_DEFLATE = 2; + protected static final int SECTOR_BYTES = 4096; + protected static final int SECTOR_INTS = SECTOR_BYTES / 4; + public static final int CHUNK_HEADER_SIZE = 5; + + protected ForwardSeekableInputStream stream; + protected DataInputStream dataStream; + + protected int offsets[]; + + /** + * Construct the reader. + * + * @param stream + * @throws DataException + * @throws IOException + */ + public McRegionReader(InputStream stream) throws DataException, IOException { + this.stream = new ForwardSeekableInputStream(stream); + this.dataStream = new DataInputStream(this.stream); + + readHeader(); + } + + /** + * Read the header. + * + * @throws DataException + * @throws IOException + */ + private void readHeader() throws DataException, IOException { + offsets = new int[SECTOR_INTS]; + + for (int i = 0; i < SECTOR_INTS; ++i) { + int offset = dataStream.readInt(); + offsets[i] = offset; + } + } + + /** + * Gets the uncompressed data input stream for a chunk. + * + * @param pos + * @return + * @throws IOException + * @throws DataException + */ + public synchronized InputStream getChunkInputStream(Vector2D pos) + throws IOException, DataException { + + int x = pos.getBlockX() & 31; + int z = pos.getBlockZ() & 31; + + if (x < 0 || x >= 32 || z < 0 || z >= 32) { + throw new DataException("MCRegion file does not contain " + x + "," + z); + } + + int offset = getOffset(x, z); + + // The chunk hasn't been generated + if (offset == 0) { + throw new DataException("The chunk at " + x + "," + z + " is not generated"); + } + + int sectorNumber = offset >> 8; + int numSectors = offset & 0xFF; + + stream.seek(sectorNumber * SECTOR_BYTES); + int length = dataStream.readInt(); + + if (length > SECTOR_BYTES * numSectors) { + throw new DataException("MCRegion chunk at " + + x + "," + z + " has an invalid length of " + length); + } + + byte version = dataStream.readByte(); + + if (version == VERSION_GZIP) { + byte[] data = new byte[length - 1]; + if (dataStream.read(data) < length - 1) { + throw new DataException("MCRegion file does not contain " + + x + "," + z + " in full"); + } + return new GZIPInputStream(new ByteArrayInputStream(data)); + } else if (version == VERSION_DEFLATE) { + byte[] data = new byte[length - 1]; + if (dataStream.read(data) < length - 1) { + throw new DataException("MCRegion file does not contain " + + x + "," + z + " in full"); + } + return new InflaterInputStream(new ByteArrayInputStream(data)); + } else { + throw new DataException("MCRegion chunk at " + + x + "," + z + " has an unsupported version of " + version); + } + } + + /** + * Get the offset for a chunk. May return 0 if it doesn't exist. + * + * @param x + * @param z + * @return + */ + private int getOffset(int x, int z) { + return offsets[x + z * 32]; + } + + /** + * Returns whether the file contains a chunk. + * + * @param x + * @param z + * @return + */ + public boolean hasChunk(int x, int z) { + return getOffset(x, z) != 0; + } + + /** + * Close the stream. + * + * @throws IOException + */ + public void close() throws IOException { + stream.close(); + } +} diff --git a/src/main/java/com/sk89q/worldedit/data/MissingChunkException.java b/src/main/java/com/sk89q/worldedit/world/storage/MissingChunkException.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/data/MissingChunkException.java rename to src/main/java/com/sk89q/worldedit/world/storage/MissingChunkException.java index 1f9ef31c7..135c53163 100644 --- a/src/main/java/com/sk89q/worldedit/data/MissingChunkException.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/MissingChunkException.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.storage; import com.sk89q.worldedit.Vector2D; diff --git a/src/main/java/com/sk89q/worldedit/data/MissingWorldException.java b/src/main/java/com/sk89q/worldedit/world/storage/MissingWorldException.java similarity index 97% rename from src/main/java/com/sk89q/worldedit/data/MissingWorldException.java rename to src/main/java/com/sk89q/worldedit/world/storage/MissingWorldException.java index 453c74bd0..a21cba34c 100644 --- a/src/main/java/com/sk89q/worldedit/data/MissingWorldException.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/MissingWorldException.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.storage; /** * diff --git a/src/main/java/com/sk89q/worldedit/data/TrueZipLegacyChunkStore.java b/src/main/java/com/sk89q/worldedit/world/storage/TrueZipLegacyChunkStore.java similarity index 98% rename from src/main/java/com/sk89q/worldedit/data/TrueZipLegacyChunkStore.java rename to src/main/java/com/sk89q/worldedit/world/storage/TrueZipLegacyChunkStore.java index af8018897..b6242c763 100644 --- a/src/main/java/com/sk89q/worldedit/data/TrueZipLegacyChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/TrueZipLegacyChunkStore.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.storage; import java.io.File; import java.io.IOException; @@ -25,6 +25,8 @@ import java.io.InputStream; import java.util.regex.Pattern; import java.util.zip.ZipException; import java.util.Enumeration; + +import com.sk89q.worldedit.world.DataException; import de.schlichtherle.util.zip.ZipEntry; import de.schlichtherle.util.zip.ZipFile; diff --git a/src/main/java/com/sk89q/worldedit/data/TrueZipMcRegionChunkStore.java b/src/main/java/com/sk89q/worldedit/world/storage/TrueZipMcRegionChunkStore.java similarity index 96% rename from src/main/java/com/sk89q/worldedit/data/TrueZipMcRegionChunkStore.java rename to src/main/java/com/sk89q/worldedit/world/storage/TrueZipMcRegionChunkStore.java index 201cfd053..ac954e756 100644 --- a/src/main/java/com/sk89q/worldedit/data/TrueZipMcRegionChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/TrueZipMcRegionChunkStore.java @@ -1,174 +1,176 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.sk89q.worldedit.data; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.regex.Pattern; -import java.util.zip.ZipException; -import java.util.Enumeration; -import de.schlichtherle.util.zip.ZipEntry; -import de.schlichtherle.util.zip.ZipFile; - -/** - * Represents the chunk store used by Minecraft but zipped. Uses - * the replacement classes for java.util.zip.* from TrueZip. - * - * @author sk89q - */ -public class TrueZipMcRegionChunkStore extends McRegionChunkStore { - - /** - * ZIP file. - */ - protected File zipFile; - /** - * Actual ZIP. - */ - protected ZipFile zip; - /** - * Folder inside the ZIP file to read from, if any. - */ - protected String folder; - - /** - * Create an instance. The folder argument lets you choose a folder or - * path to look into in the ZIP for the files. Use a blank string for - * the folder to not look into a subdirectory. - * - * @param zipFile - * @param folder - * @throws IOException - * @throws ZipException - */ - public TrueZipMcRegionChunkStore(File zipFile, String folder) - throws IOException, ZipException { - this.zipFile = zipFile; - this.folder = folder; - - zip = new ZipFile(zipFile); - } - - /** - * Create an instance. The subfolder containing the chunk data will - * be detected. - * - * @param zipFile - * @throws IOException - * @throws ZipException - */ - public TrueZipMcRegionChunkStore(File zipFile) - throws IOException, ZipException { - this.zipFile = zipFile; - - zip = new ZipFile(zipFile); - } - - /** - * Get the input stream for a chunk file. - * - * @param name - * @return - * @throws IOException - * @throws DataException - */ - @Override - @SuppressWarnings("unchecked") - protected InputStream getInputStream(String name, String worldname) - throws IOException, DataException { - - // Detect subfolder for the world's files - if (folder != null) { - if (!folder.equals("")) { - name = folder + "/" + name; - } - } else { - Pattern pattern = Pattern.compile(".*\\.mc[ra]$"); - // World pattern - Pattern worldPattern = Pattern.compile(worldname + "\\$"); - for (Enumeration e = zip.entries(); e.hasMoreElements(); ) { - ZipEntry testEntry = (ZipEntry) e.nextElement(); - // Check for world - if (worldPattern.matcher(worldname).matches()) { - // Check for file - if (pattern.matcher(testEntry.getName()).matches()) { - folder = testEntry.getName().substring(0, testEntry.getName().lastIndexOf("/")); - name = folder + "/" + name; - break; - } - } - } - - // Check if world is found - if (folder == null) { - throw new MissingWorldException("Target world is not present in ZIP.", worldname); - } - } - - ZipEntry entry = getEntry(name); - if (entry == null) { - throw new MissingChunkException(); - } - try { - return zip.getInputStream(entry); - } catch (ZipException e) { - throw new IOException("Failed to read " + name + " in ZIP"); - } - } - - /** - * Get an entry from the ZIP, trying both types of slashes. - * - * @param file - * @return - */ - private ZipEntry getEntry(String file) { - ZipEntry entry = zip.getEntry(file); - if (entry != null) { - return entry; - } - return zip.getEntry(file.replace("/", "\\")); - } - - /** - * Close resources. - * - * @throws IOException - */ - @Override - public void close() throws IOException { - zip.close(); - } - - @Override - @SuppressWarnings("unchecked") - public boolean isValid() { - for (Enumeration e = zip.entries(); e.hasMoreElements(); ) { - - ZipEntry testEntry = e.nextElement(); - - if (testEntry.getName().matches(".*\\.mcr$") || testEntry.getName().matches(".*\\.mca$")) { // TODO: does this need a separate class? - return true; - } - } - - return false; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.sk89q.worldedit.world.storage; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.regex.Pattern; +import java.util.zip.ZipException; +import java.util.Enumeration; + +import com.sk89q.worldedit.world.DataException; +import de.schlichtherle.util.zip.ZipEntry; +import de.schlichtherle.util.zip.ZipFile; + +/** + * Represents the chunk store used by Minecraft but zipped. Uses + * the replacement classes for java.util.zip.* from TrueZip. + * + * @author sk89q + */ +public class TrueZipMcRegionChunkStore extends McRegionChunkStore { + + /** + * ZIP file. + */ + protected File zipFile; + /** + * Actual ZIP. + */ + protected ZipFile zip; + /** + * Folder inside the ZIP file to read from, if any. + */ + protected String folder; + + /** + * Create an instance. The folder argument lets you choose a folder or + * path to look into in the ZIP for the files. Use a blank string for + * the folder to not look into a subdirectory. + * + * @param zipFile + * @param folder + * @throws IOException + * @throws ZipException + */ + public TrueZipMcRegionChunkStore(File zipFile, String folder) + throws IOException, ZipException { + this.zipFile = zipFile; + this.folder = folder; + + zip = new ZipFile(zipFile); + } + + /** + * Create an instance. The subfolder containing the chunk data will + * be detected. + * + * @param zipFile + * @throws IOException + * @throws ZipException + */ + public TrueZipMcRegionChunkStore(File zipFile) + throws IOException, ZipException { + this.zipFile = zipFile; + + zip = new ZipFile(zipFile); + } + + /** + * Get the input stream for a chunk file. + * + * @param name + * @return + * @throws IOException + * @throws DataException + */ + @Override + @SuppressWarnings("unchecked") + protected InputStream getInputStream(String name, String worldname) + throws IOException, DataException { + + // Detect subfolder for the world's files + if (folder != null) { + if (!folder.equals("")) { + name = folder + "/" + name; + } + } else { + Pattern pattern = Pattern.compile(".*\\.mc[ra]$"); + // World pattern + Pattern worldPattern = Pattern.compile(worldname + "\\$"); + for (Enumeration e = zip.entries(); e.hasMoreElements(); ) { + ZipEntry testEntry = (ZipEntry) e.nextElement(); + // Check for world + if (worldPattern.matcher(worldname).matches()) { + // Check for file + if (pattern.matcher(testEntry.getName()).matches()) { + folder = testEntry.getName().substring(0, testEntry.getName().lastIndexOf("/")); + name = folder + "/" + name; + break; + } + } + } + + // Check if world is found + if (folder == null) { + throw new MissingWorldException("Target world is not present in ZIP.", worldname); + } + } + + ZipEntry entry = getEntry(name); + if (entry == null) { + throw new MissingChunkException(); + } + try { + return zip.getInputStream(entry); + } catch (ZipException e) { + throw new IOException("Failed to read " + name + " in ZIP"); + } + } + + /** + * Get an entry from the ZIP, trying both types of slashes. + * + * @param file + * @return + */ + private ZipEntry getEntry(String file) { + ZipEntry entry = zip.getEntry(file); + if (entry != null) { + return entry; + } + return zip.getEntry(file.replace("/", "\\")); + } + + /** + * Close resources. + * + * @throws IOException + */ + @Override + public void close() throws IOException { + zip.close(); + } + + @Override + @SuppressWarnings("unchecked") + public boolean isValid() { + for (Enumeration e = zip.entries(); e.hasMoreElements(); ) { + + ZipEntry testEntry = e.nextElement(); + + if (testEntry.getName().matches(".*\\.mcr$") || testEntry.getName().matches(".*\\.mca$")) { // TODO: does this need a separate class? + return true; + } + } + + return false; + } +} diff --git a/src/main/java/com/sk89q/worldedit/data/ZippedLegacyChunkStore.java b/src/main/java/com/sk89q/worldedit/world/storage/ZippedLegacyChunkStore.java similarity index 98% rename from src/main/java/com/sk89q/worldedit/data/ZippedLegacyChunkStore.java rename to src/main/java/com/sk89q/worldedit/world/storage/ZippedLegacyChunkStore.java index 076be1ead..8fedcbd43 100644 --- a/src/main/java/com/sk89q/worldedit/data/ZippedLegacyChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/ZippedLegacyChunkStore.java @@ -17,7 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.data; +package com.sk89q.worldedit.world.storage; + +import com.sk89q.worldedit.world.DataException; import java.io.File; import java.io.IOException; diff --git a/src/main/java/com/sk89q/worldedit/data/ZippedMcRegionChunkStore.java b/src/main/java/com/sk89q/worldedit/world/storage/ZippedMcRegionChunkStore.java similarity index 95% rename from src/main/java/com/sk89q/worldedit/data/ZippedMcRegionChunkStore.java rename to src/main/java/com/sk89q/worldedit/world/storage/ZippedMcRegionChunkStore.java index 5c1e64d81..daa4714f6 100644 --- a/src/main/java/com/sk89q/worldedit/data/ZippedMcRegionChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/world/storage/ZippedMcRegionChunkStore.java @@ -1,169 +1,171 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010 sk89q and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.sk89q.worldedit.data; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; -import java.util.Enumeration; - -/** - * Represents the chunk store used by Minecraft alpha but zipped. - * - * @author sk89q - */ -public class ZippedMcRegionChunkStore extends McRegionChunkStore { - - /** - * ZIP file. - */ - protected File zipFile; - /** - * Actual ZIP. - */ - protected ZipFile zip; - /** - * Folder inside the ZIP file to read from, if any. - */ - protected String folder; - - /** - * Create an instance. The folder argument lets you choose a folder or - * path to look into in the ZIP for the files. Use a blank string for - * the folder to not look into a subdirectory. - * - * @param zipFile - * @param folder - * @throws IOException - * @throws ZipException - */ - public ZippedMcRegionChunkStore(File zipFile, String folder) - throws IOException, ZipException { - this.zipFile = zipFile; - this.folder = folder; - - zip = new ZipFile(zipFile); - } - - /** - * Create an instance. The subfolder containing the chunk data will - * be detected. - * - * @param zipFile - * @throws IOException - * @throws ZipException - */ - public ZippedMcRegionChunkStore(File zipFile) - throws IOException, ZipException { - this.zipFile = zipFile; - - zip = new ZipFile(zipFile); - } - - /** - * Get the input stream for a chunk file. - * - * @param name - * @return - * @throws IOException - * @throws DataException - */ - @Override - protected InputStream getInputStream(String name, String worldname) - throws IOException, DataException { - - // Detect subfolder for the world's files - if (folder != null) { - if (!folder.equals("")) { - name = folder + "/" + name; - } - } else { - Pattern pattern = Pattern.compile(".*\\.mc[ra]$"); - for (Enumeration e = zip.entries(); e.hasMoreElements(); ) { - ZipEntry testEntry = (ZipEntry) e.nextElement(); - // Check for world - if (testEntry.getName().startsWith(worldname + "/")) { - if (pattern.matcher(testEntry.getName()).matches()) { // does entry end in .mca - folder = testEntry.getName().substring(0, testEntry.getName().lastIndexOf("/")); - name = folder + "/" + name; - break; - } - - } - } - - // Check if world is found - if (folder == null) { - throw new MissingWorldException("Target world is not present in ZIP.", worldname); - } - } - - ZipEntry entry = getEntry(name); - if (entry == null) { - throw new MissingChunkException(); - } - try { - return zip.getInputStream(entry); - } catch (ZipException e) { - throw new IOException("Failed to read " + name + " in ZIP"); - } - } - - /** - * Get an entry from the ZIP, trying both types of slashes. - * - * @param file - * @return - */ - private ZipEntry getEntry(String file) { - ZipEntry entry = zip.getEntry(file); - if (entry != null) { - return entry; - } - return zip.getEntry(file.replace("/", "\\")); - } - - /** - * Close resources. - * - * @throws IOException - */ - @Override - public void close() throws IOException { - zip.close(); - } - - @Override - public boolean isValid() { - for (Enumeration e = zip.entries(); e.hasMoreElements(); ) { - - ZipEntry testEntry = e.nextElement(); - - if (testEntry.getName().matches(".*\\.mcr$") || testEntry.getName().matches(".*\\.mca$")) { // TODO: does this need a separate class? - return true; - } - } - - return false; - } -} +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010 sk89q and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.sk89q.worldedit.world.storage; + +import com.sk89q.worldedit.world.DataException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; +import java.util.Enumeration; + +/** + * Represents the chunk store used by Minecraft alpha but zipped. + * + * @author sk89q + */ +public class ZippedMcRegionChunkStore extends McRegionChunkStore { + + /** + * ZIP file. + */ + protected File zipFile; + /** + * Actual ZIP. + */ + protected ZipFile zip; + /** + * Folder inside the ZIP file to read from, if any. + */ + protected String folder; + + /** + * Create an instance. The folder argument lets you choose a folder or + * path to look into in the ZIP for the files. Use a blank string for + * the folder to not look into a subdirectory. + * + * @param zipFile + * @param folder + * @throws IOException + * @throws ZipException + */ + public ZippedMcRegionChunkStore(File zipFile, String folder) + throws IOException, ZipException { + this.zipFile = zipFile; + this.folder = folder; + + zip = new ZipFile(zipFile); + } + + /** + * Create an instance. The subfolder containing the chunk data will + * be detected. + * + * @param zipFile + * @throws IOException + * @throws ZipException + */ + public ZippedMcRegionChunkStore(File zipFile) + throws IOException, ZipException { + this.zipFile = zipFile; + + zip = new ZipFile(zipFile); + } + + /** + * Get the input stream for a chunk file. + * + * @param name + * @return + * @throws IOException + * @throws DataException + */ + @Override + protected InputStream getInputStream(String name, String worldname) + throws IOException, DataException { + + // Detect subfolder for the world's files + if (folder != null) { + if (!folder.equals("")) { + name = folder + "/" + name; + } + } else { + Pattern pattern = Pattern.compile(".*\\.mc[ra]$"); + for (Enumeration e = zip.entries(); e.hasMoreElements(); ) { + ZipEntry testEntry = (ZipEntry) e.nextElement(); + // Check for world + if (testEntry.getName().startsWith(worldname + "/")) { + if (pattern.matcher(testEntry.getName()).matches()) { // does entry end in .mca + folder = testEntry.getName().substring(0, testEntry.getName().lastIndexOf("/")); + name = folder + "/" + name; + break; + } + + } + } + + // Check if world is found + if (folder == null) { + throw new MissingWorldException("Target world is not present in ZIP.", worldname); + } + } + + ZipEntry entry = getEntry(name); + if (entry == null) { + throw new MissingChunkException(); + } + try { + return zip.getInputStream(entry); + } catch (ZipException e) { + throw new IOException("Failed to read " + name + " in ZIP"); + } + } + + /** + * Get an entry from the ZIP, trying both types of slashes. + * + * @param file + * @return + */ + private ZipEntry getEntry(String file) { + ZipEntry entry = zip.getEntry(file); + if (entry != null) { + return entry; + } + return zip.getEntry(file.replace("/", "\\")); + } + + /** + * Close resources. + * + * @throws IOException + */ + @Override + public void close() throws IOException { + zip.close(); + } + + @Override + public boolean isValid() { + for (Enumeration e = zip.entries(); e.hasMoreElements(); ) { + + ZipEntry testEntry = e.nextElement(); + + if (testEntry.getName().matches(".*\\.mcr$") || testEntry.getName().matches(".*\\.mca$")) { // TODO: does this need a separate class? + return true; + } + } + + return false; + } +} diff --git a/src/spout/java/com/sk89q/worldedit/spout/SpoutCommandSender.java b/src/spout/java/com/sk89q/worldedit/spout/SpoutCommandSender.java index 899618062..0a84e5819 100644 --- a/src/spout/java/com/sk89q/worldedit/spout/SpoutCommandSender.java +++ b/src/spout/java/com/sk89q/worldedit/spout/SpoutCommandSender.java @@ -27,7 +27,7 @@ import com.sk89q.worldedit.PlayerNeededException; import com.sk89q.worldedit.ServerInterface; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; -import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.extent.inventory.BlockBag; import org.spout.api.chat.style.ChatStyle; import org.spout.api.command.CommandSource; import org.spout.api.entity.Player; diff --git a/src/spout/java/com/sk89q/worldedit/spout/SpoutPlayer.java b/src/spout/java/com/sk89q/worldedit/spout/SpoutPlayer.java index de9f73089..325e7551c 100644 --- a/src/spout/java/com/sk89q/worldedit/spout/SpoutPlayer.java +++ b/src/spout/java/com/sk89q/worldedit/spout/SpoutPlayer.java @@ -26,8 +26,8 @@ import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.ServerInterface; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; -import com.sk89q.worldedit.bags.BlockBag; -import com.sk89q.worldedit.cui.CUIEvent; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.internal.cui.CUIEvent; import org.spout.api.Client; import org.spout.api.chat.style.ChatStyle; diff --git a/src/spout/java/com/sk89q/worldedit/spout/SpoutPlayerBlockBag.java b/src/spout/java/com/sk89q/worldedit/spout/SpoutPlayerBlockBag.java index 9da5ab045..9e23acd0a 100644 --- a/src/spout/java/com/sk89q/worldedit/spout/SpoutPlayerBlockBag.java +++ b/src/spout/java/com/sk89q/worldedit/spout/SpoutPlayerBlockBag.java @@ -22,13 +22,12 @@ package com.sk89q.worldedit.spout; import com.sk89q.worldedit.WorldVector; -import com.sk89q.worldedit.bags.BlockBag; -import com.sk89q.worldedit.bags.BlockBagException; -import com.sk89q.worldedit.bags.OutOfBlocksException; -import com.sk89q.worldedit.bags.OutOfSpaceException; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.extent.inventory.BlockBagException; +import com.sk89q.worldedit.extent.inventory.OutOfBlocksException; +import com.sk89q.worldedit.extent.inventory.OutOfSpaceException; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.blocks.BlockID; import org.spout.api.inventory.Inventory; import org.spout.api.inventory.ItemStack; import org.spout.api.material.Material; diff --git a/src/spout/java/com/sk89q/worldedit/spout/WorldEditCUIMessage.java b/src/spout/java/com/sk89q/worldedit/spout/WorldEditCUIMessage.java index ccc8ae5ac..71096ada3 100644 --- a/src/spout/java/com/sk89q/worldedit/spout/WorldEditCUIMessage.java +++ b/src/spout/java/com/sk89q/worldedit/spout/WorldEditCUIMessage.java @@ -19,7 +19,7 @@ package com.sk89q.worldedit.spout; import com.sk89q.util.StringUtil; -import com.sk89q.worldedit.cui.CUIEvent; +import com.sk89q.worldedit.internal.cui.CUIEvent; import org.apache.commons.lang3.builder.ToStringBuilder; import org.spout.api.protocol.Message; import org.spout.api.util.SpoutToStringStyle; diff --git a/src/spout/java/com/sk89q/worldedit/spout/WorldEditPlugin.java b/src/spout/java/com/sk89q/worldedit/spout/WorldEditPlugin.java index b9781e418..de2a46085 100644 --- a/src/spout/java/com/sk89q/worldedit/spout/WorldEditPlugin.java +++ b/src/spout/java/com/sk89q/worldedit/spout/WorldEditPlugin.java @@ -23,7 +23,7 @@ package com.sk89q.worldedit.spout; import com.sk89q.util.yaml.YAMLProcessor; import com.sk89q.worldedit.*; -import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Polygonal2DRegion; import com.sk89q.worldedit.regions.Region; diff --git a/src/test/java/com/sk89q/worldedit/expression/ExpressionTest.java b/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java similarity index 93% rename from src/test/java/com/sk89q/worldedit/expression/ExpressionTest.java rename to src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java index ab30d0b27..9117f0688 100644 --- a/src/test/java/com/sk89q/worldedit/expression/ExpressionTest.java +++ b/src/test/java/com/sk89q/worldedit/internal/expression/ExpressionTest.java @@ -1,188 +1,188 @@ -package com.sk89q.worldedit.expression; - -import static org.junit.Assert.*; -import static java.lang.Math.*; - -import com.sk89q.worldedit.expression.runtime.ExpressionEnvironment; -import org.junit.*; - -import com.sk89q.worldedit.expression.lexer.LexerException; -import com.sk89q.worldedit.expression.parser.ParserException; -import com.sk89q.worldedit.expression.runtime.EvaluationException; - -public class ExpressionTest { - @Test - public void testEvaluate() throws ExpressionException { - // check - assertEquals(1 - 2 + 3, simpleEval("1 - 2 + 3"), 0); - - // check unary ops - assertEquals(2 + +4, simpleEval("2 + +4"), 0); - assertEquals(2 - -4, simpleEval("2 - -4"), 0); - assertEquals(2 * -4, simpleEval("2 * -4"), 0); - - // check functions - assertEquals(sin(5), simpleEval("sin(5)"), 0); - assertEquals(atan2(3, 4), simpleEval("atan2(3, 4)"), 0); - - // check variables - assertEquals(8, compile("foo+bar", "foo", "bar").evaluate(5, 3), 0); - } - - @Test - public void testErrors() throws ExpressionException { - // test lexer errors - try { - compile("#"); - fail("Error expected"); - } catch (LexerException e) { - assertEquals("Error position", 0, e.getPosition()); - } - - // test parser errors - try { - compile("x"); - fail("Error expected"); - } catch (ParserException e) { - assertEquals("Error position", 0, e.getPosition()); - } - try { - compile("x()"); - fail("Error expected"); - } catch (ParserException e) { - assertEquals("Error position", 0, e.getPosition()); - } - try { - compile("("); - fail("Error expected"); - } catch (ParserException e) {} - try { - compile("x("); - fail("Error expected"); - } catch (ParserException e) {} - - // test overloader errors - try { - compile("atan2(1)"); - fail("Error expected"); - } catch (ParserException e) { - assertEquals("Error position", 0, e.getPosition()); - } - try { - compile("atan2(1, 2, 3)"); - fail("Error expected"); - } catch (ParserException e) { - assertEquals("Error position", 0, e.getPosition()); - } - try { - compile("rotate(1, 2, 3)"); - fail("Error expected"); - } catch (ParserException e) { - assertEquals("Error position", 0, e.getPosition()); - } - } - - @Test - public void testAssign() throws ExpressionException { - Expression foo = compile("{a=x} b=y; c=z", "x", "y", "z", "a", "b", "c"); - foo.evaluate(2, 3, 5); - assertEquals(2, foo.getVariable("a", false).getValue(), 0); - assertEquals(3, foo.getVariable("b", false).getValue(), 0); - assertEquals(5, foo.getVariable("c", false).getValue(), 0); - } - - @Test - public void testIf() throws ExpressionException { - assertEquals(40, simpleEval("if (1) x=4; else y=5; x*10+y;"), 0); - assertEquals(5, simpleEval("if (0) x=4; else y=5; x*10+y;"), 0); - - // test 'dangling else' - final Expression expression1 = compile("if (1) if (0) x=4; else y=5;", "x", "y"); - expression1.evaluate(1, 2); - assertEquals(1, expression1.getVariable("x", false).getValue(), 0); - assertEquals(5, expression1.getVariable("y", false).getValue(), 0); - - // test if the if construct is correctly recognized as a statement - final Expression expression2 = compile("if (0) if (1) x=5; y=4;", "x", "y"); - expression2.evaluate(1, 2); - assertEquals(4, expression2.getVariable("y", false).getValue(), 0); - } - - @Test - public void testWhile() throws ExpressionException { - assertEquals(5, simpleEval("c=5; a=0; while (c > 0) { ++a; --c; } a"), 0); - assertEquals(5, simpleEval("c=5; a=0; do { ++a; --c; } while (c > 0); a"), 0); - } - - @Test - public void testFor() throws ExpressionException { - assertEquals(5, simpleEval("a=0; for (i=0; i<5; ++i) { ++a; } a"), 0); - assertEquals(12345, simpleEval("y=0; for (i=1,5) { y *= 10; y += i; } y"), 0); - } - - @Test - public void testSwitch() throws ExpressionException { - assertEquals(523, simpleEval("x=1;y=2;z=3;switch (1) { case 1: x=5; break; case 2: y=6; break; default: z=7 } x*100+y*10+z"), 0); - assertEquals(163, simpleEval("x=1;y=2;z=3;switch (2) { case 1: x=5; break; case 2: y=6; break; default: z=7 } x*100+y*10+z"), 0); - assertEquals(127, simpleEval("x=1;y=2;z=3;switch (3) { case 1: x=5; break; case 2: y=6; break; default: z=7 } x*100+y*10+z"), 0); - - assertEquals(567, simpleEval("x=1;y=2;z=3;switch (1) { case 1: x=5; case 2: y=6; default: z=7 } x*100+y*10+z"), 0); - assertEquals(167, simpleEval("x=1;y=2;z=3;switch (2) { case 1: x=5; case 2: y=6; default: z=7 } x*100+y*10+z"), 0); - assertEquals(127, simpleEval("x=1;y=2;z=3;switch (3) { case 1: x=5; case 2: y=6; default: z=7 } x*100+y*10+z"), 0); - } - - @Test - public void testQuery() throws Exception { - assertEquals(1, simpleEval("a=1;b=2;query(3,4,5,a,b); a==3 && b==4"), 0); - assertEquals(1, simpleEval("a=1;b=2;queryAbs(3,4,5,a*1,b*1); a==1 && b==2"), 0); - assertEquals(1, simpleEval("a=1;b=2;queryRel(3,4,5,(a),(b)); a==300 && b==400"), 0); - assertEquals(1, simpleEval("query(3,4,5,3,4)"), 0); - assertEquals(1, simpleEval("!query(3,4,5,3,2)"), 0); - assertEquals(1, simpleEval("!queryAbs(3,4,5,10,40)"), 0); - assertEquals(1, simpleEval("!queryRel(3,4,5,100,200)"), 0); - } - - private double simpleEval(String expressionString) throws ExpressionException { - final Expression expression = compile(expressionString); - - expression.setEnvironment(new ExpressionEnvironment() { - @Override - public int getBlockType(double x, double y, double z) { - return (int) x; - } - - @Override - public int getBlockData(double x, double y, double z) { - return (int) y; - } - - @Override - public int getBlockTypeAbs(double x, double y, double z) { - return (int) x*10; - } - - @Override - public int getBlockDataAbs(double x, double y, double z) { - return (int) y*10; - } - - @Override - public int getBlockTypeRel(double x, double y, double z) { - return (int) x*100; - } - - @Override - public int getBlockDataRel(double x, double y, double z) { - return (int) y*100; - } - }); - - return expression.evaluate(); - } - - private Expression compile(String expressionString, String... variableNames) throws ExpressionException, EvaluationException { - final Expression expression = Expression.compile(expressionString, variableNames); - expression.optimize(); - return expression; - } -} +package com.sk89q.worldedit.internal.expression; + +import static org.junit.Assert.*; +import static java.lang.Math.*; + +import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment; +import org.junit.*; + +import com.sk89q.worldedit.internal.expression.lexer.LexerException; +import com.sk89q.worldedit.internal.expression.parser.ParserException; +import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; + +public class ExpressionTest { + @Test + public void testEvaluate() throws ExpressionException { + // check + assertEquals(1 - 2 + 3, simpleEval("1 - 2 + 3"), 0); + + // check unary ops + assertEquals(2 + +4, simpleEval("2 + +4"), 0); + assertEquals(2 - -4, simpleEval("2 - -4"), 0); + assertEquals(2 * -4, simpleEval("2 * -4"), 0); + + // check functions + assertEquals(sin(5), simpleEval("sin(5)"), 0); + assertEquals(atan2(3, 4), simpleEval("atan2(3, 4)"), 0); + + // check variables + assertEquals(8, compile("foo+bar", "foo", "bar").evaluate(5, 3), 0); + } + + @Test + public void testErrors() throws ExpressionException { + // test lexer errors + try { + compile("#"); + fail("Error expected"); + } catch (LexerException e) { + assertEquals("Error position", 0, e.getPosition()); + } + + // test parser errors + try { + compile("x"); + fail("Error expected"); + } catch (ParserException e) { + assertEquals("Error position", 0, e.getPosition()); + } + try { + compile("x()"); + fail("Error expected"); + } catch (ParserException e) { + assertEquals("Error position", 0, e.getPosition()); + } + try { + compile("("); + fail("Error expected"); + } catch (ParserException e) {} + try { + compile("x("); + fail("Error expected"); + } catch (ParserException e) {} + + // test overloader errors + try { + compile("atan2(1)"); + fail("Error expected"); + } catch (ParserException e) { + assertEquals("Error position", 0, e.getPosition()); + } + try { + compile("atan2(1, 2, 3)"); + fail("Error expected"); + } catch (ParserException e) { + assertEquals("Error position", 0, e.getPosition()); + } + try { + compile("rotate(1, 2, 3)"); + fail("Error expected"); + } catch (ParserException e) { + assertEquals("Error position", 0, e.getPosition()); + } + } + + @Test + public void testAssign() throws ExpressionException { + Expression foo = compile("{a=x} b=y; c=z", "x", "y", "z", "a", "b", "c"); + foo.evaluate(2, 3, 5); + assertEquals(2, foo.getVariable("a", false).getValue(), 0); + assertEquals(3, foo.getVariable("b", false).getValue(), 0); + assertEquals(5, foo.getVariable("c", false).getValue(), 0); + } + + @Test + public void testIf() throws ExpressionException { + assertEquals(40, simpleEval("if (1) x=4; else y=5; x*10+y;"), 0); + assertEquals(5, simpleEval("if (0) x=4; else y=5; x*10+y;"), 0); + + // test 'dangling else' + final Expression expression1 = compile("if (1) if (0) x=4; else y=5;", "x", "y"); + expression1.evaluate(1, 2); + assertEquals(1, expression1.getVariable("x", false).getValue(), 0); + assertEquals(5, expression1.getVariable("y", false).getValue(), 0); + + // test if the if construct is correctly recognized as a statement + final Expression expression2 = compile("if (0) if (1) x=5; y=4;", "x", "y"); + expression2.evaluate(1, 2); + assertEquals(4, expression2.getVariable("y", false).getValue(), 0); + } + + @Test + public void testWhile() throws ExpressionException { + assertEquals(5, simpleEval("c=5; a=0; while (c > 0) { ++a; --c; } a"), 0); + assertEquals(5, simpleEval("c=5; a=0; do { ++a; --c; } while (c > 0); a"), 0); + } + + @Test + public void testFor() throws ExpressionException { + assertEquals(5, simpleEval("a=0; for (i=0; i<5; ++i) { ++a; } a"), 0); + assertEquals(12345, simpleEval("y=0; for (i=1,5) { y *= 10; y += i; } y"), 0); + } + + @Test + public void testSwitch() throws ExpressionException { + assertEquals(523, simpleEval("x=1;y=2;z=3;switch (1) { case 1: x=5; break; case 2: y=6; break; default: z=7 } x*100+y*10+z"), 0); + assertEquals(163, simpleEval("x=1;y=2;z=3;switch (2) { case 1: x=5; break; case 2: y=6; break; default: z=7 } x*100+y*10+z"), 0); + assertEquals(127, simpleEval("x=1;y=2;z=3;switch (3) { case 1: x=5; break; case 2: y=6; break; default: z=7 } x*100+y*10+z"), 0); + + assertEquals(567, simpleEval("x=1;y=2;z=3;switch (1) { case 1: x=5; case 2: y=6; default: z=7 } x*100+y*10+z"), 0); + assertEquals(167, simpleEval("x=1;y=2;z=3;switch (2) { case 1: x=5; case 2: y=6; default: z=7 } x*100+y*10+z"), 0); + assertEquals(127, simpleEval("x=1;y=2;z=3;switch (3) { case 1: x=5; case 2: y=6; default: z=7 } x*100+y*10+z"), 0); + } + + @Test + public void testQuery() throws Exception { + assertEquals(1, simpleEval("a=1;b=2;query(3,4,5,a,b); a==3 && b==4"), 0); + assertEquals(1, simpleEval("a=1;b=2;queryAbs(3,4,5,a*1,b*1); a==1 && b==2"), 0); + assertEquals(1, simpleEval("a=1;b=2;queryRel(3,4,5,(a),(b)); a==300 && b==400"), 0); + assertEquals(1, simpleEval("query(3,4,5,3,4)"), 0); + assertEquals(1, simpleEval("!query(3,4,5,3,2)"), 0); + assertEquals(1, simpleEval("!queryAbs(3,4,5,10,40)"), 0); + assertEquals(1, simpleEval("!queryRel(3,4,5,100,200)"), 0); + } + + private double simpleEval(String expressionString) throws ExpressionException { + final Expression expression = compile(expressionString); + + expression.setEnvironment(new ExpressionEnvironment() { + @Override + public int getBlockType(double x, double y, double z) { + return (int) x; + } + + @Override + public int getBlockData(double x, double y, double z) { + return (int) y; + } + + @Override + public int getBlockTypeAbs(double x, double y, double z) { + return (int) x*10; + } + + @Override + public int getBlockDataAbs(double x, double y, double z) { + return (int) y*10; + } + + @Override + public int getBlockTypeRel(double x, double y, double z) { + return (int) x*100; + } + + @Override + public int getBlockDataRel(double x, double y, double z) { + return (int) y*100; + } + }); + + return expression.evaluate(); + } + + private Expression compile(String expressionString, String... variableNames) throws ExpressionException, EvaluationException { + final Expression expression = Expression.compile(expressionString, variableNames); + expression.optimize(); + return expression; + } +}