Switch to Gradle. Use git log --follow for history.

This converts the project into a multi-module Gradle build.

By default, Git does not show history past a rename, so use git log
--follow to see further history.
This commit is contained in:
sk89q
2014-11-14 11:27:39 -08:00
parent 44559cde68
commit 7192780251
714 changed files with 333 additions and 834 deletions

View File

@ -0,0 +1,27 @@
dependencies {
compile 'de.schlichtherle:truezip:6.8.3'
compile 'rhino:js:1.7R2'
compile 'org.yaml:snakeyaml:1.9'
compile 'com.google.guava:guava:17.0'
compile 'com.sk89q:jchronic:0.2.4a'
compile 'com.google.code.findbugs:jsr305:1.3.9'
compile 'com.thoughtworks.paranamer:paranamer:2.6'
compile 'com.google.code.gson:gson:2.2.4'
compile 'com.sk89q.lib:jlibnoise:1.0.0'
//compile 'net.sf.trove4j:trove4j:3.0.3'
testCompile 'org.mockito:mockito-core:1.9.0-rc1'
}
sourceSets {
main {
java {
srcDir 'src/main/java'
srcDir 'src/legacy/java'
}
resources {
srcDir 'src/main/resources'
}
}
}
build.dependsOn(shadowJar)

View File

@ -0,0 +1,202 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.bags;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.blocks.*;
/**
* @deprecated Block bags are currently not a supported feature of WorldEdit
*/
@SuppressWarnings("deprecation")
@Deprecated
public abstract class BlockBag {
/**
* Stores a block as if it was mined.
*
* @param id the ID of the block
* @throws BlockBagException thrown on a error
* @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 the ID of the block
* @param data the data value of the block
* @throws BlockBagException thrown on a error
*/
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 the ID of the block
* @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 the ID of the block
* @param data the data value of the block
* @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 the ID of the block
* @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 the 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 the ID of the block
* @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 the 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 the ID of the block
* @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 position the position of the source
*/
public abstract void addSourcePosition(WorldVector position);
/**
* Adds a position to be used a source.
*
* @param position the position of the source
*/
public abstract void addSingleSourcePosition(WorldVector position);
}

View File

@ -0,0 +1,29 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.bags;
/**
* @deprecated Block bags are currently not a supported feature of WorldEdit
*/
@Deprecated
public class BlockBagException extends Exception {
}

View File

@ -0,0 +1,29 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.bags;
/**
* @deprecated Block bags are currently not a supported feature of WorldEdit
*/
@Deprecated
public class OutOfBlocksException extends BlockBagException {
}

View File

@ -0,0 +1,46 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.bags;
/**
* @deprecated Block bags are currently not a supported feature of WorldEdit
*/
@Deprecated
public class OutOfSpaceException extends BlockBagException {
private int id;
/**
* Construct the object.
*
* @param id the type ID
*/
public OutOfSpaceException(int id) {
this.id = id;
}
/**
* @return the id
*/
public int getID() {
return id;
}
}

View File

@ -0,0 +1,29 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.bags;
/**
* @deprecated Block bags are currently not a supported feature of WorldEdit
*/
@Deprecated
public class UnplaceableBlockException extends BlockBagException {
}

View File

@ -0,0 +1,111 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException;
import com.sk89q.worldedit.world.storage.InvalidFormatException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Represents a chest block.
*/
public class ChestBlock extends ContainerBlock {
/**
* Construct an empty chest block with the default orientation (data value).
*/
public ChestBlock() {
super(BlockID.CHEST, 27);
}
/**
* Construct an empty chest block with a custom data value.
*
* @param data data indicating the position of the chest
*/
public ChestBlock(int data) {
super(BlockID.CHEST, data, 27);
}
/**
* Construct the chest block with a custom data value and a list of items.
*
* @param data data indicating the position of the chest
* @param items array of items
*/
public ChestBlock(int data, BaseItemStack[] items) {
super(BlockID.CHEST, data, 27);
setItems(items);
}
@Override
public String getNbtId() {
return "Chest";
}
@Override
public CompoundTag getNbtData() {
Map<String, Tag> values = new HashMap<String, Tag>();
values.put("Items", new ListTag("Items", CompoundTag.class, serializeInventory(getItems())));
return new CompoundTag(getNbtId(), values);
}
@Override
public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
Map<String, Tag> values = rootTag.getValue();
Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Chest")) {
throw new RuntimeException("'Chest' tile entity expected");
}
List<CompoundTag> items = new ArrayList<CompoundTag>();
try {
for (Tag tag : NBTUtils.getChildTag(values, "Items", ListTag.class).getValue()) {
if (!(tag instanceof CompoundTag)) {
throw new RuntimeException("CompoundTag expected as child tag of Chest's Items");
}
items.add((CompoundTag) tag);
}
setItems(deserializeInventory(items));
} catch (InvalidFormatException e) {
throw new RuntimeException(e);
} catch (DataException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,141 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Represents a block that stores items.
*/
public abstract class ContainerBlock extends BaseBlock implements TileEntityBlock {
private BaseItemStack[] items;
public ContainerBlock(int type, int inventorySize) {
super(type);
this.items = new BaseItemStack[inventorySize];
}
public ContainerBlock(int type, int data, int inventorySize) {
super(type, data);
this.items = new BaseItemStack[inventorySize];
}
/**
* Get the list of items.
*
* @return an array of stored items
*/
public BaseItemStack[] getItems() {
return this.items;
}
/**
* Set the list of items.
*
* @param items an array of stored items
*/
public void setItems(BaseItemStack[] items) {
this.items = items;
}
@Override
public boolean hasNbtData() {
return true;
}
public Map<String, Tag> serializeItem(BaseItemStack item) {
Map<String, Tag> data = new HashMap<String, Tag>();
data.put("id", new ShortTag("id", (short) item.getType()));
data.put("Damage", new ShortTag("Damage", item.getData()));
data.put("Count", new ByteTag("Count", (byte) item.getAmount()));
if (!item.getEnchantments().isEmpty()) {
List<CompoundTag> enchantmentList = new ArrayList<CompoundTag>();
for(Map.Entry<Integer, Integer> entry : item.getEnchantments().entrySet()) {
Map<String, Tag> enchantment = new HashMap<String, Tag>();
enchantment.put("id", new ShortTag("id", entry.getKey().shortValue()));
enchantment.put("lvl", new ShortTag("lvl", entry.getValue().shortValue()));
enchantmentList.add(new CompoundTag(null, enchantment));
}
Map<String, Tag> auxData = new HashMap<String, Tag>();
auxData.put("ench", new ListTag("ench", CompoundTag.class, enchantmentList));
data.put("tag", new CompoundTag("tag", auxData));
}
return data;
}
public BaseItemStack deserializeItem(Map<String, Tag> data) throws DataException {
short id = NBTUtils.getChildTag(data, "id", ShortTag.class).getValue();
short damage = NBTUtils.getChildTag(data, "Damage", ShortTag.class).getValue();
byte count = NBTUtils.getChildTag(data, "Count", ByteTag.class).getValue();
BaseItemStack stack = new BaseItemStack(id, count, damage);
if (data.containsKey("tag")) {
Map<String, Tag> auxData = NBTUtils.getChildTag(data, "tag", CompoundTag.class).getValue();
ListTag ench = (ListTag)auxData.get("ench");
for(Tag e : ench.getValue()) {
Map<String, Tag> vars = ((CompoundTag) e).getValue();
short enchId = NBTUtils.getChildTag(vars, "id", ShortTag.class).getValue();
short enchLevel = NBTUtils.getChildTag(vars, "lvl", ShortTag.class).getValue();
stack.getEnchantments().put((int) enchId, (int) enchLevel);
}
}
return stack;
}
public BaseItemStack[] deserializeInventory(List<CompoundTag> items) throws DataException {
BaseItemStack[] stacks = new BaseItemStack[items.size()];
for (CompoundTag tag : items) {
Map<String, Tag> item = tag.getValue();
BaseItemStack stack = deserializeItem(item);
byte slot = NBTUtils.getChildTag(item, "Slot", ByteTag.class).getValue();
if (slot >= 0 && slot < stacks.length) {
stacks[slot] = stack;
}
}
return stacks;
}
public List<CompoundTag> serializeInventory(BaseItemStack[] items) {
List<CompoundTag> tags = new ArrayList<CompoundTag>();
for (int i = 0; i < items.length; ++i) {
if (items[i] != null) {
Map<String, Tag> tagData = serializeItem(items[i]);
tagData.put("Slot", new ByteTag("Slot", (byte) i));
tags.add(new CompoundTag("", tagData));
}
}
return tags;
}
}

View File

@ -0,0 +1,108 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Represents dispensers.
*/
public class DispenserBlock extends ContainerBlock {
/**
* Construct an empty dispenser block.
*/
public DispenserBlock() {
super(BlockID.DISPENSER, 9);
}
/**
* Construct an empty dispenser block.
*
* @param data data value (orientation)
*/
public DispenserBlock(int data) {
super(BlockID.DISPENSER, data, 9);
}
/**
* Construct a dispenser block with the given orientation and inventory.
*
* @param data data value (orientation)
* @param items array of items in the inventory
*/
public DispenserBlock(int data, BaseItemStack[] items) {
super(BlockID.DISPENSER, data, 9);
this.setItems(items);
}
@Override
public String getNbtId() {
return "Trap";
}
@Override
public CompoundTag getNbtData() {
Map<String, Tag> values = new HashMap<String, Tag>();
values.put("Items", new ListTag("Items", CompoundTag.class,
serializeInventory(getItems())));
return new CompoundTag(getNbtId(), values);
}
@Override
public void setNbtData(CompoundTag rootTag) {
try {
if (rootTag == null) {
return;
}
Map<String, Tag> values = rootTag.getValue();
Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Trap")) {
throw new DataException("'Trap' tile entity expected");
}
List<CompoundTag> items = new ArrayList<CompoundTag>();
for (Tag tag : NBTUtils.getChildTag(values, "Items", ListTag.class).getValue()) {
if (!(tag instanceof CompoundTag)) {
throw new DataException("CompoundTag expected as child tag of Trap Items");
}
items.add((CompoundTag) tag);
}
setItems(deserializeInventory(items));
} catch (DataException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,166 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.DataException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Represents a furnace block.
*/
public class FurnaceBlock extends ContainerBlock {
private short burnTime;
private short cookTime;
/**
* Construct an empty furnace block with the default orientation.
*
* @param type type ID
*/
public FurnaceBlock(int type) {
super(type, 2);
}
/**
* Construct an empty furnace block with a given orientation.
*
* @param type type ID
* @param data orientation
*/
public FurnaceBlock(int type, int data) {
super(type, data, 2);
}
/**
* Construct an furnace block with a given orientation and inventory.
*
* @param type type ID
* @param data orientation
* @param items inventory items
*/
public FurnaceBlock(int type, int data, BaseItemStack[] items) {
super(type, data, 2);
setItems(items);
}
/**
* Get the burn time.
*
* @return the burn time
*/
public short getBurnTime() {
return burnTime;
}
/**
* Set the burn time.
*
* @param burnTime the burn time
*/
public void setBurnTime(short burnTime) {
this.burnTime = burnTime;
}
/**
* Get the cook time.
*
* @return the cook time
*/
public short getCookTime() {
return cookTime;
}
/**
* Set the cook time.
*
* @param cookTime the cook time to set
*/
public void setCookTime(short cookTime) {
this.cookTime = cookTime;
}
@Override
public String getNbtId() {
return "Furnace";
}
@Override
public CompoundTag getNbtData() {
Map<String, Tag> values = new HashMap<String, Tag>();
values.put("Items", new ListTag("Items", CompoundTag.class,
serializeInventory(getItems())));
values.put("BurnTime", new ShortTag("BurnTime", burnTime));
values.put("CookTime", new ShortTag("CookTime", cookTime));
return new CompoundTag(getNbtId(), values);
}
@Override
public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
try {
Map<String, Tag> values = rootTag.getValue();
Tag t = values.get("id");
if (!(t instanceof StringTag)
|| !((StringTag) t).getValue().equals("Furnace")) {
throw new RuntimeException("'Furnace' tile entity expected");
}
ListTag items = NBTUtils.getChildTag(values, "Items", ListTag.class);
List<CompoundTag> compound = new ArrayList<CompoundTag>();
for (Tag tag : items.getValue()) {
if (!(tag instanceof CompoundTag)) {
throw new RuntimeException("CompoundTag expected as child tag of Furnace Items");
}
compound.add((CompoundTag) tag);
}
setItems(deserializeInventory(compound));
t = values.get("BurnTime");
if (t instanceof ShortTag) {
burnTime = ((ShortTag) t).getValue();
}
t = values.get("CookTime");
if (t instanceof ShortTag) {
cookTime = ((ShortTag) t).getValue();
}
} catch (DataException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,100 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.extent.Extent;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A implementation of a lazy block for {@link Extent#getLazyBlock(Vector)}
* that takes the block's ID and metadata, but will defer loading of NBT
* data until time of access.
*
* <p>NBT data is later loaded using a call to {@link Extent#getBlock(Vector)}
* with a stored {@link Extent} and location.</p>
*
* <p>All mutators on this object will throw an
* {@link UnsupportedOperationException}.</p>
*/
public class LazyBlock extends BaseBlock {
private final Extent extent;
private final Vector position;
private boolean loaded = false;
/**
* Create a new lazy block.
*
* @param type the block type
* @param extent the extent to later load the full block data from
* @param position the position to later load the full block data from
*/
public LazyBlock(int type, Extent extent, Vector position) {
super(type);
checkNotNull(extent);
checkNotNull(position);
this.extent = extent;
this.position = position;
}
/**
* Create a new lazy block.
*
* @param type the block type
* @param data the data value
* @param extent the extent to later load the full block data from
* @param position the position to later load the full block data from
*/
public LazyBlock(int type, int data, Extent extent, Vector position) {
super(type, data);
checkNotNull(extent);
checkNotNull(position);
this.extent = extent;
this.position = position;
}
@Override
public void setId(int id) {
throw new UnsupportedOperationException("This object is immutable");
}
@Override
public void setData(int data) {
throw new UnsupportedOperationException("This object is immutable");
}
@Override
public CompoundTag getNbtData() {
if (!loaded) {
BaseBlock loadedBlock = extent.getBlock(position);
super.setNbtData(loadedBlock.getNbtData());
}
return super.getNbtData();
}
@Override
public void setNbtData(CompoundTag nbtData) {
throw new UnsupportedOperationException("This object is immutable");
}
}

View File

@ -0,0 +1,250 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.metadata.MobType;
import com.sk89q.worldedit.world.storage.InvalidFormatException;
import java.util.HashMap;
import java.util.Map;
/**
* A mob spawner block.
*/
public class MobSpawnerBlock extends BaseBlock implements TileEntityBlock {
private String mobType;
private short delay;
// advanced mob spawner features
private short spawnCount;
private short spawnRange;
private CompoundTag spawnData;
private ListTag spawnPotentials;
private short minSpawnDelay;
private short maxSpawnDelay;
private short maxNearbyEntities;
private short requiredPlayerRange;
/**
* Construct the mob spawner block with a pig as the mob type.
*/
public MobSpawnerBlock() {
super(BlockID.MOB_SPAWNER);
this.mobType = MobType.PIG.getName();
}
/**
* Construct the mob spawner block with a given mob type.
*
* @param mobType mob type
*/
public MobSpawnerBlock(String mobType) {
super(BlockID.MOB_SPAWNER);
this.mobType = mobType;
}
/**
* Construct the mob spawner block with a specified data value.
*
* @param data data value
*/
public MobSpawnerBlock(int data) {
super(BlockID.MOB_SPAWNER, data);
}
/**
* Construct the mob spawner block.
*
* @param data data value
* @param mobType mob type
*/
public MobSpawnerBlock(int data, String mobType) {
super(BlockID.MOB_SPAWNER, data);
this.mobType = mobType;
}
/**
* Get the mob type.
*
* @return the mob type
*/
public String getMobType() {
return mobType;
}
/**
* Set the mob type.
*
* @param mobType the mob type
*/
public void setMobType(String mobType) {
this.mobType = mobType;
}
/**
* Get the spawn delay.
*
* @return the delay
*/
public short getDelay() {
return delay;
}
/**
* Set the spawn delay.
*
* @param delay the delay to set
*/
public void setDelay(short delay) {
this.delay = delay;
}
@Override
public boolean hasNbtData() {
return true;
}
@Override
public String getNbtId() {
return "MobSpawner";
}
@Override
public CompoundTag getNbtData() {
Map<String, Tag> values = new HashMap<String, Tag>();
values.put("EntityId", new StringTag("EntityId", mobType));
values.put("Delay", new ShortTag("Delay", delay));
values.put("SpawnCount", new ShortTag("SpawnCount", spawnCount));
values.put("SpawnRange", new ShortTag("SpawnRange", spawnRange));
values.put("MinSpawnDelay", new ShortTag("MinSpawnDelay", minSpawnDelay));
values.put("MaxSpawnDelay", new ShortTag("MaxSpawnDelay", maxSpawnDelay));
values.put("MaxNearbyEntities", new ShortTag("MaxNearbyEntities", maxNearbyEntities));
values.put("RequiredPlayerRange", new ShortTag("RequiredPlayerRange", requiredPlayerRange));
if (spawnData != null) {
values.put("SpawnData", new CompoundTag("SpawnData", spawnData.getValue()));
}
if (spawnPotentials != null) {
values.put("SpawnPotentials", new ListTag("SpawnPotentials", CompoundTag.class, spawnPotentials.getValue()));
}
return new CompoundTag(getNbtId(), values);
}
@Override
public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
Map<String, Tag> values = rootTag.getValue();
Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("MobSpawner")) {
throw new RuntimeException("'MobSpawner' tile entity expected");
}
StringTag mobTypeTag;
ShortTag delayTag;
try {
mobTypeTag = NBTUtils.getChildTag(values, "EntityId", StringTag.class);
delayTag = NBTUtils.getChildTag(values, "Delay", ShortTag.class);
} catch (InvalidFormatException ignored) {
throw new RuntimeException("Invalid mob spawner data: no EntityId and/or no Delay");
}
this.mobType = mobTypeTag.getValue();
this.delay = delayTag.getValue();
ShortTag spawnCountTag = null;
ShortTag spawnRangeTag = null;
ShortTag minSpawnDelayTag = null;
ShortTag maxSpawnDelayTag = null;
ShortTag maxNearbyEntitiesTag = null;
ShortTag requiredPlayerRangeTag = null;
ListTag spawnPotentialsTag = null;
CompoundTag spawnDataTag = null;
try {
spawnCountTag = NBTUtils.getChildTag(values, "SpawnCount", ShortTag.class);
} catch (InvalidFormatException ignored) {
}
try {
spawnRangeTag = NBTUtils.getChildTag(values, "SpawnRange", ShortTag.class);
} catch (InvalidFormatException ignored) {
}
try {
minSpawnDelayTag = NBTUtils.getChildTag(values, "MinSpawnDelay", ShortTag.class);
} catch (InvalidFormatException ignored) {
}
try {
maxSpawnDelayTag = NBTUtils.getChildTag(values, "MaxSpawnDelay", ShortTag.class);
} catch (InvalidFormatException ignored) {
}
try {
maxNearbyEntitiesTag = NBTUtils.getChildTag(values, "MaxNearbyEntities", ShortTag.class);
} catch (InvalidFormatException ignored) {
}
try {
requiredPlayerRangeTag = NBTUtils.getChildTag(values, "RequiredPlayerRange", ShortTag.class);
} catch (InvalidFormatException ignored) {
}
try {
spawnPotentialsTag = NBTUtils.getChildTag(values, "SpawnPotentials", ListTag.class);
} catch (InvalidFormatException ignored) {
}
try {
spawnDataTag = NBTUtils.getChildTag(values, "SpawnData", CompoundTag.class);
} catch (InvalidFormatException ignored) {
}
if (spawnCountTag != null) {
this.spawnCount = spawnCountTag.getValue();
}
if (spawnRangeTag != null) {
this.spawnRange =spawnRangeTag.getValue();
}
if (minSpawnDelayTag != null) {
this.minSpawnDelay = minSpawnDelayTag.getValue();
}
if (maxSpawnDelayTag != null) {
this.maxSpawnDelay = maxSpawnDelayTag.getValue();
}
if (maxNearbyEntitiesTag != null) {
this.maxNearbyEntities = maxNearbyEntitiesTag.getValue();
}
if (requiredPlayerRangeTag != null) {
this.requiredPlayerRange = requiredPlayerRangeTag.getValue();
}
if (spawnPotentialsTag != null) {
this.spawnPotentials = new ListTag("SpawnPotentials", CompoundTag.class, spawnPotentialsTag.getValue());
}
if (spawnDataTag != null) {
this.spawnData = new CompoundTag("SpawnData", spawnDataTag.getValue());
}
}
}

View File

@ -0,0 +1,122 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import java.util.HashMap;
import java.util.Map;
/**
* A note block.
*/
public class NoteBlock extends BaseBlock implements TileEntityBlock {
private byte note;
/**
* Construct the note block with a data value of 0.
*/
public NoteBlock() {
super(BlockID.NOTE_BLOCK);
this.note = 0;
}
/**
* Construct the note block with a given data value.
*
* @param data data value
*/
public NoteBlock(int data) {
super(BlockID.NOTE_BLOCK, data);
this.note = 0;
}
/**
* Construct the note block with a given data value and note.
*
* @param data data value
* @param note note
*/
public NoteBlock(int data, byte note) {
super(BlockID.NOTE_BLOCK, data);
this.note = note;
}
/**
* Get the note.
*
* @return the note
*/
public byte getNote() {
return note;
}
/**
* Set the note.
*
* @param note the note to set
*/
public void setNote(byte note) {
this.note = note;
}
@Override
public boolean hasNbtData() {
return true;
}
@Override
public String getNbtId() {
return "Music";
}
@Override
public CompoundTag getNbtData() {
Map<String, Tag> values = new HashMap<String, Tag>();
values.put("note", new ByteTag("note", note));
return new CompoundTag(getNbtId(), values);
}
@Override
public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
Map<String, Tag> values = rootTag.getValue();
Tag t;
t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Music")) {
throw new RuntimeException("'Music' tile entity expected");
}
t = values.get("note");
if (t instanceof ByteTag) {
note = ((ByteTag) t).getValue();
}
}
}

View File

@ -0,0 +1,141 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import java.util.HashMap;
import java.util.Map;
/**
* Represents a sign block.
*/
public class SignBlock extends BaseBlock implements TileEntityBlock {
private String[] text;
/**
* Construct the sign without text.
*
* @param type type ID
* @param data data value (orientation)
*/
public SignBlock(int type, int data) {
super(type, data);
this.text = new String[] { "", "", "", "" };
}
/**
* Construct the sign with text.
*
* @param type type ID
* @param data data value (orientation)
* @param text lines of text
*/
public SignBlock(int type, int data, String[] text) {
super(type, data);
if (text == null) {
this.text = new String[] { "", "", "", "" };
}
this.text = text;
}
/**
* Get the text.
*
* @return the text
*/
public String[] getText() {
return text;
}
/**
* Set the text.
*
* @param text the text to set
*/
public void setText(String[] text) {
if (text == null) {
throw new IllegalArgumentException("Can't set null text for a sign");
}
this.text = text;
}
@Override
public boolean hasNbtData() {
return true;
}
@Override
public String getNbtId() {
return "Sign";
}
@Override
public CompoundTag getNbtData() {
Map<String, Tag> values = new HashMap<String, Tag>();
values.put("Text1", new StringTag("Text1", text[0]));
values.put("Text2", new StringTag("Text2", text[1]));
values.put("Text3", new StringTag("Text3", text[2]));
values.put("Text4", new StringTag("Text4", text[3]));
return new CompoundTag(getNbtId(), values);
}
@Override
public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
Map<String, Tag> values = rootTag.getValue();
Tag t;
text = new String[] { "", "", "", "" };
t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Sign")) {
throw new RuntimeException("'Sign' tile entity expected");
}
t = values.get("Text1");
if (t instanceof StringTag) {
text[0] = ((StringTag) t).getValue();
}
t = values.get("Text2");
if (t instanceof StringTag) {
text[1] = ((StringTag) t).getValue();
}
t = values.get("Text3");
if (t instanceof StringTag) {
text[2] = ((StringTag) t).getValue();
}
t = values.get("Text4");
if (t instanceof StringTag) {
text[3] = ((StringTag) t).getValue();
}
}
}

View File

@ -0,0 +1,194 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import java.util.HashMap;
import java.util.Map;
/**
* A skull block.
*/
public class SkullBlock extends BaseBlock implements TileEntityBlock {
private String owner = ""; // notchian
private byte skullType; // stored here for block, in damage value for item
private byte rot; // only matters if block data == 0x1 (on floor)
/**
* Construct the skull block with a default type of skelton.
* @param data data value to set, controls placement
*/
public SkullBlock(int data) {
this(data, (byte) 0);
}
/**
* Construct the skull block with a given type.
* 0 - skeleton
* 1 - wither skelly
* 2 - zombie
* 3 - human
* 4 - creeper
* @param data data value to set, controls placement
* @param type type of skull
*/
public SkullBlock(int data, byte type) {
this(data, type, (byte) 0);
}
/**
* Construct the skull block with a given type and rotation.
* @param data data value to set, controls placement
* @param type type of skull
* @param rot rotation (if on floor)
*/
public SkullBlock(int data, byte type, byte rot) {
super(BlockID.HEAD, data);
if (type < (byte) 0 || type > (byte) 4) {
this.skullType = (byte) 0;
} else {
this.skullType = type;
}
this.rot = rot;
this.owner = "";
}
/**
* Construct the skull block with a given rotation and owner.
* The type is assumed to be player unless owner is null or empty.
* @param data data value to set, controls placement
* @param rot rotation of skull
* @param owner name of player
*/
public SkullBlock(int data, byte rot, String owner) {
super(BlockID.HEAD, data);
this.rot = rot;
this.setOwner(owner);
if (owner == null || owner.isEmpty()) this.skullType = (byte) 0;
}
/**
* Set the skull's owner. Automatically sets type to player if not empty or null.
* @param owner player name to set the skull to
*/
public void setOwner(String owner) {
if (owner == null) {
this.owner = "";
} else {
if (owner.length() > 16 || owner.isEmpty()) this.owner = "";
else this.owner = owner;
}
if (this.owner != null && !this.owner.isEmpty()) this.skullType = (byte) 3;
}
/**
* Get the skull's owner. Returns null if unset.
* @return player name or null
*/
public String getOwner() {
return owner;
}
/**
* Get the type of skull.
* @return the skullType
*/
public byte getSkullType() {
return skullType;
}
/**
* Set the type of skull;
* @param skullType the skullType to set
*/
public void setSkullType(byte skullType) {
this.skullType = skullType;
}
/**
* Get rotation of skull. This only means anything if the block data is 1.
* @return the rotation
*/
public byte getRot() {
return rot;
}
/**
* Set the rotation of skull.
* @param rot the rotation to set
*/
public void setRot(byte rot) {
this.rot = rot;
}
@Override
public boolean hasNbtData() {
return true;
}
@Override
public String getNbtId() {
return "Skull";
}
@Override
public CompoundTag getNbtData() {
Map<String, Tag> values = new HashMap<String, Tag>();
values.put("SkullType", new ByteTag("SkullType", skullType));
if (owner == null) owner = "";
values.put("ExtraType", new StringTag("ExtraType", owner));
values.put("Rot", new ByteTag("Rot", rot));
return new CompoundTag(getNbtId(), values);
}
@Override
public void setNbtData(CompoundTag rootTag) {
if (rootTag == null) {
return;
}
Map<String, Tag> values = rootTag.getValue();
Tag t;
t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals("Skull")) {
throw new RuntimeException("'Skull' tile entity expected");
}
t = values.get("SkullType");
if (t instanceof ByteTag) {
skullType = ((ByteTag) t).getValue();
}
t = values.get("ExtraType");
if (t != null && t instanceof StringTag) {
owner = ((StringTag) t).getValue();
}
t = values.get("Rot");
if (t instanceof ByteTag) {
rot = ((ByteTag) t).getValue();
}
}
}

View File

@ -0,0 +1,34 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.data;
/**
* @deprecated Switch to {@link com.sk89q.worldedit.world.DataException}
*/
@Deprecated
public class DataException extends com.sk89q.worldedit.world.DataException {
public DataException(String msg) {
super(msg);
}
public DataException() {
}
}

View File

@ -0,0 +1,42 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.foundation;
import com.sk89q.worldedit.blocks.BaseBlock;
/**
* @deprecated Use {@link BaseBlock}
*/
@Deprecated
public abstract class Block {
public abstract int getId();
public abstract void setId(int id);
public abstract int getData();
public abstract void setData(int data);
public abstract void setIdAndData(int id, int data);
public abstract boolean hasWildcardData();
}

View File

@ -0,0 +1,35 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
/**
* @deprecated Switch to {@link com.sk89q.worldedit.function.mask.AbstractMask}
*/
@Deprecated
public abstract class AbstractMask implements Mask {
@Override
public void prepare(LocalSession session, LocalPlayer player, Vector target) {
}
}

View File

@ -0,0 +1,73 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* @deprecated Use {@link com.sk89q.worldedit.function.mask.BlockMask}
*/
@Deprecated
public class BlockMask extends AbstractMask {
private final Set<BaseBlock> blocks;
public BlockMask() {
blocks = new HashSet<BaseBlock>();
}
public BlockMask(Set<BaseBlock> types) {
this.blocks = types;
}
public BlockMask(BaseBlock... block) {
blocks = new HashSet<BaseBlock>();
for (BaseBlock b : block) {
add(b);
}
}
public BlockMask(BaseBlock block) {
this();
add(block);
}
public void add(BaseBlock block) {
blocks.add(block);
}
public void addAll(Collection<BaseBlock> blocks) {
blocks.addAll(blocks);
}
@Override
public boolean matches(EditSession editSession, Vector position) {
BaseBlock block = editSession.getBlock(position);
return blocks.contains(block)
|| blocks.contains(new BaseBlock(block.getType(), -1));
}
}

View File

@ -0,0 +1,54 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.blocks.BaseBlock;
import java.util.Set;
/**
* A filter that matches blocks based on block types.
*
* @deprecated replaced by {@link #BlockMask}
*/
@Deprecated
public class BlockTypeMask extends BlockMask {
public BlockTypeMask() {
super();
}
public BlockTypeMask(Set<Integer> types) {
super();
for (int type : types) {
add(type);
}
}
public BlockTypeMask(int type) {
this();
add(type);
}
public void add(int type) {
add(new BaseBlock(type));
}
}

View File

@ -0,0 +1,84 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import java.util.ArrayList;
import java.util.List;
/**
* @deprecated See {@link MaskIntersection}
*/
@Deprecated
public class CombinedMask extends AbstractMask {
private final List<Mask> masks = new ArrayList<Mask>();
public CombinedMask() {
}
public CombinedMask(Mask mask) {
add(mask);
}
public CombinedMask(Mask ...mask) {
for (Mask m : mask) {
add(m);
}
}
public CombinedMask(List<Mask> masks) {
this.masks.addAll(masks);
}
public void add(Mask mask) {
masks.add(mask);
}
public boolean remove(Mask mask) {
return masks.remove(mask);
}
public boolean has(Mask mask) {
return masks.contains(mask);
}
@Override
public void prepare(LocalSession session, LocalPlayer player, Vector target) {
for (Mask mask : masks) {
mask.prepare(session, player, target);
}
}
@Override
public boolean matches(EditSession editSession, Vector position) {
for (Mask mask : masks) {
if (!mask.matches(editSession, position)) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,46 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.request.RequestSelection;
/**
* @deprecated Use {@link RequestSelection} with {@link com.sk89q.worldedit.function.mask.RegionMask}
*/
@Deprecated
public class DynamicRegionMask extends AbstractMask {
private Region region;
@Override
public void prepare(LocalSession session, LocalPlayer player, Vector target) {
try {
region = session.getSelection(player.getWorld());
} catch (IncompleteRegionException exc) {
region = null;
}
}
@Override
public boolean matches(EditSession editSession, Vector position) {
return region == null || region.contains(position);
}
}

View File

@ -0,0 +1,35 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockID;
/**
* @deprecated See {@link com.sk89q.worldedit.function.mask.ExistingBlockMask}
*/
@Deprecated
public class ExistingBlockMask extends AbstractMask {
@Override
public boolean matches(EditSession editSession, Vector position) {
return editSession.getBlockType(position) != BlockID.AIR;
}
}

View File

@ -0,0 +1,64 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.Blocks;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* @deprecated See {@link com.sk89q.worldedit.function.mask.FuzzyBlockMask}
*/
@Deprecated
public class FuzzyBlockMask extends AbstractMask {
private final Set<BaseBlock> filter;
/**
* Create a new fuzzy block mask.
*
* @param filter a list of block types to match
*/
public FuzzyBlockMask(Set<BaseBlock> filter) {
this.filter = filter;
}
/**
* Create a new fuzzy block mask.
*
* @param block a list of block types to match
*/
public FuzzyBlockMask(BaseBlock... block) {
Set<BaseBlock> filter = new HashSet<BaseBlock>();
Collections.addAll(filter, block);
this.filter = filter;
}
@Override
public boolean matches(EditSession editSession, Vector position) {
BaseBlock compare = new BaseBlock(editSession.getBlockType(position), editSession.getBlockData(position));
return Blocks.containsFuzzy(filter, compare);
}
}

View File

@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import java.util.Set;
/**
* A block type mask that only matches blocks that are not in the list.
*/
@Deprecated
public class InvertedBlockTypeMask extends BlockTypeMask {
public InvertedBlockTypeMask() {
}
public InvertedBlockTypeMask(Set<Integer> types) {
super(types);
}
public InvertedBlockTypeMask(int type) {
super(type);
}
@Override
public boolean matches(EditSession editSession, Vector position) {
return !super.matches(editSession, position);
}
}

View File

@ -0,0 +1,52 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.function.mask.Masks;
/**
* @deprecated See {@link Masks#negate(com.sk89q.worldedit.function.mask.Mask)}
*/
@Deprecated
public class InvertedMask extends AbstractMask {
private final Mask mask;
public InvertedMask(Mask mask) {
this.mask = mask;
}
@Override
public void prepare(LocalSession session, LocalPlayer player, Vector target) {
mask.prepare(session, player, target);
}
@Override
public boolean matches(EditSession editSession, Vector position) {
return !mask.matches(editSession, position);
}
public Mask getInvertedMask() {
return mask;
}
}

View File

@ -0,0 +1,54 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
/**
* @deprecated Use {@link com.sk89q.worldedit.function.mask.Mask}
*/
@Deprecated
public interface Mask {
/**
* Called one time before each edit session.
*
* @param session a session
* @param player a player
* @param target target of the brush, null if not a brush mask
*/
void prepare(LocalSession session, LocalPlayer player, Vector target);
/**
* Given a block position, this method returns true if the block at
* that position matches the filter. Block information is not provided
* as getting a BaseBlock has unneeded overhead in most block querying
* situations (enumerating a chest's contents is a waste, for example).
*
* @param editSession an instance
* @param position the position to check
* @return true if it matches
*/
boolean matches(EditSession editSession, Vector position);
}

View File

@ -0,0 +1,41 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.function.mask.NoiseFilter;
/**
* @deprecated See {@link NoiseFilter}
*/
@Deprecated
public class RandomMask extends AbstractMask {
private final double ratio;
public RandomMask(double ratio) {
this.ratio = ratio;
}
@Override
public boolean matches(EditSession editSession, Vector position) {
return Math.random() < ratio;
}
}

View File

@ -0,0 +1,41 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.regions.Region;
/**
* @deprecated See {@link com.sk89q.worldedit.function.mask.RegionMask}
*/
@Deprecated
public class RegionMask extends AbstractMask {
private final Region region;
public RegionMask(Region region) {
this.region = region.clone();
}
@Override
public boolean matches(EditSession editSession, Vector position) {
return region.contains(position);
}
}

View File

@ -0,0 +1,35 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockType;
/**
* @deprecated See {@link com.sk89q.worldedit.function.mask.SolidBlockMask}
*/
@Deprecated
public class SolidBlockMask extends AbstractMask {
@Override
public boolean matches(EditSession editSession, Vector position) {
return !BlockType.canPassThrough(editSession.getBlockType(position), editSession.getBlockData(position));
}
}

View File

@ -0,0 +1,76 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.mask.OffsetMask;
import java.util.Set;
/**
* @deprecated Use {@link OffsetMask} with {@link MaskIntersection} and {@link Masks#negate(com.sk89q.worldedit.function.mask.Mask)}
*/
@Deprecated
public class UnderOverlayMask extends AbstractMask {
private final int yMod;
private Mask mask;
@Deprecated
public UnderOverlayMask(Set<Integer> ids, boolean overlay) {
this(new BlockTypeMask(ids), overlay);
}
public UnderOverlayMask(Mask mask, boolean overlay) {
this.yMod = overlay ? -1 : 1;
this.mask = mask;
}
@Deprecated
public void addAll(Set<Integer> ids) {
if (mask instanceof BlockMask) {
final BlockMask blockTypeMask = (BlockMask) mask;
for (Integer id : ids) {
blockTypeMask.add(new BaseBlock(id));
}
} else if (mask instanceof ExistingBlockMask) {
final BlockMask blockMask = new BlockMask();
for (int type : ids) {
blockMask.add(new BaseBlock(type));
}
mask = blockMask;
}
}
@Override
public void prepare(LocalSession session, LocalPlayer player, Vector target) {
mask.prepare(session, player, target);
}
@Override
public boolean matches(EditSession editSession, Vector position) {
return !mask.matches(editSession, position) && mask.matches(editSession, position.add(0, yMod, 0));
}
}

View File

@ -0,0 +1,58 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.patterns;
import com.sk89q.worldedit.blocks.BaseBlock;
/**
* @deprecated Will be removed in the future -- there is no replacement
*/
@Deprecated
public class BlockChance {
private BaseBlock block;
private double chance;
/**
* Construct the object.
*
* @param block the block
* @param chance the probability of the block
*/
public BlockChance(BaseBlock block, double chance) {
this.block = block;
this.chance = chance;
}
/**
* @return the block
*/
public BaseBlock getBlock() {
return block;
}
/**
* @return the chance
*/
public double getChance() {
return chance;
}
}

View File

@ -0,0 +1,57 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.patterns;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock;
/**
* Pattern that repeats the clipboard.
*/
public class ClipboardPattern implements Pattern {
private CuboidClipboard clipboard;
private Vector size;
/**
* Construct the object.
*
* @param clipboard the clipboard
*/
public ClipboardPattern(CuboidClipboard clipboard) {
this.clipboard = clipboard;
this.size = clipboard.getSize();
}
@Override
public BaseBlock next(Vector position) {
return next(position.getBlockX(), position.getBlockY(), position.getBlockZ());
}
@Override
public BaseBlock next(int x, int y, int z) {
int xp = Math.abs(x) % size.getBlockX();
int yp = Math.abs(y) % size.getBlockY();
int zp = Math.abs(z) % size.getBlockZ();
return clipboard.getPoint(new Vector(xp, yp, zp));
}
}

View File

@ -0,0 +1,51 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.patterns;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock;
/**
* @deprecated See {@link com.sk89q.worldedit.function.pattern.Pattern}
*/
@Deprecated
public interface Pattern {
/**
* Get a block for a position. This return value of this method does
* not have to be consistent for the same position.
*
* @param position the position where a block is needed
* @return a block
*/
public BaseBlock next(Vector position);
/**
* Get a block for a position. This return value of this method does
* not have to be consistent for the same position.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
* @return a block
*/
public BaseBlock next(int x, int y, int z);
}

View File

@ -0,0 +1,82 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.patterns;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* @deprecated See {@link RandomPattern}
*/
@Deprecated
public class RandomFillPattern implements Pattern {
private static final Random random = new Random();
private List<BlockChance> blocks;
/**
* Construct the object.
*
* @param blocks a list of blocks
*/
public RandomFillPattern(List<BlockChance> blocks) {
double max = 0;
for (BlockChance block : blocks) {
max += block.getChance();
}
List<BlockChance> finalBlocks = new ArrayList<BlockChance>();
double i = 0;
for (BlockChance block : blocks) {
double v = block.getChance() / max;
i += v;
finalBlocks.add(new BlockChance(block.getBlock(), i));
}
this.blocks = finalBlocks;
}
@Override
public BaseBlock next(Vector position) {
double r = random.nextDouble();
for (BlockChance block : blocks) {
if (r <= block.getChance()) {
return block.getBlock();
}
}
throw new RuntimeException("ProportionalFillPattern");
}
@Override
public BaseBlock next(int x, int y, int z) {
return next(null);
}
}

View File

@ -0,0 +1,62 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.patterns;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.function.pattern.BlockPattern;
/**
* @deprecated See {@link BlockPattern}
*/
@Deprecated
public class SingleBlockPattern implements Pattern {
private BaseBlock block;
/**
* Construct the object.
*
* @param block the block
*/
public SingleBlockPattern(BaseBlock block) {
this.block = block;
}
/**
* Get the block.
*
* @return the block
*/
public BaseBlock getBlock() {
return block;
}
@Override
public BaseBlock next(Vector position) {
return block;
}
@Override
public BaseBlock next(int x, int y, int z) {
return block;
}
}

View File

@ -0,0 +1,44 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.extension.platform.Actor;
abstract class AbstractLegacyRegionSelector implements RegionSelector {
@Deprecated
public final void explainPrimarySelection(LocalPlayer player, LocalSession session, Vector position) {
explainPrimarySelection((Actor) player, session, position);
}
@Deprecated
public final void explainSecondarySelection(LocalPlayer player, LocalSession session, Vector position) {
explainSecondarySelection((Actor) player, session, position);
}
@Deprecated
public final void explainRegionAdjust(LocalPlayer player, LocalSession session) {
explainRegionAdjust((Actor) player, session);
}
}

View File

@ -0,0 +1,29 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions;
import com.sk89q.worldedit.internal.cui.CUIRegion;
/**
* @deprecated This class only exists as to not break binary compatibility
*/
@Deprecated
public abstract class ConvexPolyhedralRegionSelector extends AbstractLegacyRegionSelector implements CUIRegion {
}

View File

@ -0,0 +1,29 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions;
import com.sk89q.worldedit.internal.cui.CUIRegion;
/**
* @deprecated This class only exists as to not break binary compatibility
*/
@Deprecated
public abstract class CuboidRegionSelector extends AbstractLegacyRegionSelector implements CUIRegion {
}

View File

@ -0,0 +1,29 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions;
import com.sk89q.worldedit.internal.cui.CUIRegion;
/**
* @deprecated This class only exists as to not break binary compatibility
*/
@Deprecated
public abstract class CylinderRegionSelector extends AbstractLegacyRegionSelector implements CUIRegion {
}

View File

@ -0,0 +1,29 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions;
import com.sk89q.worldedit.internal.cui.CUIRegion;
/**
* @deprecated This class only exists as to not break binary compatibility
*/
@Deprecated
public abstract class EllipsoidRegionSelector extends AbstractLegacyRegionSelector implements CUIRegion {
}

View File

@ -0,0 +1,29 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions;
import com.sk89q.worldedit.internal.cui.CUIRegion;
/**
* @deprecated This class only exists as to not break binary compatibility
*/
@Deprecated
public abstract class ExtendingCuboidRegionSelector extends AbstractLegacyRegionSelector implements CUIRegion {
}

View File

@ -0,0 +1,37 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions;
import com.sk89q.worldedit.internal.cui.CUIRegion;
/**
* @deprecated This class only exists as to not break binary compatibility
*/
@Deprecated
public abstract class Polygonal2DRegionSelector extends AbstractLegacyRegionSelector implements CUIRegion {
/**
* Get the number of points.
*
* @return the number of points
*/
public abstract int getPointCount();
}

View File

@ -0,0 +1,29 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions;
import com.sk89q.worldedit.internal.cui.CUIRegion;
/**
* @deprecated This class only exists as to not break binary compatibility
*/
@Deprecated
public abstract class SphereRegionSelector extends AbstractLegacyRegionSelector implements CUIRegion {
}

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>tar.gz</format>
<format>tar.bz2</format>
<format>zip</format>
</formats>
<files>
<file>
<source>${project.build.directory}/${artifactId}-${project.version}.jar</source>
<destName>WorldEdit.jar</destName>
<outputDirectory>/</outputDirectory>
<filtered>false</filtered>
</file>
<file>
<source>README.html</source>
<outputDirectory>/</outputDirectory>
<filtered>true</filtered>
</file>
</files>
<fileSets>
<fileSet>
<includes>
<include>LICENSE.txt</include>
<include>CHANGELOG.txt</include>
<include>contrib/craftscripts/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@ -0,0 +1,73 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
/**
* The {@code TAG_Byte_Array} tag.
*/
public final class ByteArrayTag extends Tag {
private final byte[] value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public ByteArrayTag(byte[] value) {
super();
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public ByteArrayTag(String name, byte[] value) {
super(name);
this.value = value;
}
@Override
public byte[] getValue() {
return value;
}
@Override
public String toString() {
StringBuilder hex = new StringBuilder();
for (byte b : value) {
String hexDigits = Integer.toHexString(b).toUpperCase();
if (hexDigits.length() == 1) {
hex.append("0");
}
hex.append(hexDigits).append(" ");
}
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Byte_Array" + append + ": " + hex;
}
}

View File

@ -0,0 +1,65 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
/**
* The {@code TAG_Byte} tag.
*/
public final class ByteTag extends Tag {
private final byte value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public ByteTag(byte value) {
super();
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public ByteTag(String name, byte value) {
super(name);
this.value = value;
}
@Override
public Byte getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Byte" + append + ": " + value;
}
}

View File

@ -0,0 +1,436 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The {@code TAG_Compound} tag.
*/
public final class CompoundTag extends Tag {
private final Map<String, Tag> value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public CompoundTag(Map<String, Tag> value) {
super();
this.value = Collections.unmodifiableMap(value);
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public CompoundTag(String name, Map<String, Tag> value) {
super(name);
this.value = Collections.unmodifiableMap(value);
}
/**
* Returns whether this compound tag contains the given key.
*
* @param key the given key
* @return true if the tag contains the given key
*/
public boolean containsKey(String key) {
return value.containsKey(key);
}
@Override
public Map<String, Tag> getValue() {
return value;
}
/**
* Return a new compound tag with the given values.
*
* @param value the value
* @return the new compound tag
*/
public CompoundTag setValue(Map<String, Tag> value) {
return new CompoundTag(getName(), value);
}
/**
* Create a compound tag builder.
*
* @return the builder
*/
public CompoundTagBuilder createBuilder() {
return new CompoundTagBuilder(new HashMap<String, Tag>(value));
}
/**
* Get a byte array named with the given key.
*
* <p>If the key does not exist or its value is not a byte array tag,
* then an empty byte array will be returned.</p>
*
* @param key the key
* @return a byte array
*/
public byte[] getByteArray(String key) {
Tag tag = value.get(key);
if (tag instanceof ByteArrayTag) {
return ((ByteArrayTag) tag).getValue();
} else {
return new byte[0];
}
}
/**
* Get a byte named with the given key.
*
* <p>If the key does not exist or its value is not a byte tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a byte
*/
public byte getByte(String key) {
Tag tag = value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else {
return (byte) 0;
}
}
/**
* Get a double named with the given key.
*
* <p>If the key does not exist or its value is not a double tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a double
*/
public double getDouble(String key) {
Tag tag = value.get(key);
if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a double named with the given key, even if it's another
* type of number.
*
* <p>If the key does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a double
*/
public double asDouble(String key) {
Tag tag = value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a float named with the given key.
*
* <p>If the key does not exist or its value is not a float tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a float
*/
public float getFloat(String key) {
Tag tag = value.get(key);
if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a {@code int[]} named with the given key.
*
* <p>If the key does not exist or its value is not an int array tag,
* then an empty array will be returned.</p>
*
* @param key the key
* @return an int array
*/
public int[] getIntArray(String key) {
Tag tag = value.get(key);
if (tag instanceof IntArrayTag) {
return ((IntArrayTag) tag).getValue();
} else {
return new int[0];
}
}
/**
* Get an int named with the given key.
*
* <p>If the key does not exist or its value is not an int tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return an int
*/
public int getInt(String key) {
Tag tag = value.get(key);
if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get an int named with the given key, even if it's another
* type of number.
*
* <p>If the key does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return an int
*/
public int asInt(String key) {
Tag tag = value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue().intValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().intValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().intValue();
} else {
return 0;
}
}
/**
* Get a list of tags named with the given key.
*
* <p>If the key does not exist or its value is not a list tag,
* then an empty list will be returned.</p>
*
* @param key the key
* @return a list of tags
*/
public List<Tag> getList(String key) {
Tag tag = value.get(key);
if (tag instanceof ListTag) {
return ((ListTag) tag).getValue();
} else {
return Collections.emptyList();
}
}
/**
* Get a {@code TagList} named with the given key.
*
* <p>If the key does not exist or its value is not a list tag,
* then an empty tag list will be returned.</p>
*
* @param key the key
* @return a tag list instance
*/
public ListTag getListTag(String key) {
Tag tag = value.get(key);
if (tag instanceof ListTag) {
return (ListTag) tag;
} else {
return new ListTag(key, StringTag.class, Collections.<Tag>emptyList());
}
}
/**
* Get a list of tags named with the given key.
*
* <p>If the key does not exist or its value is not a list tag,
* then an empty list will be returned. If the given key references
* a list but the list of of a different type, then an empty
* list will also be returned.</p>
*
* @param key the key
* @param listType the class of the contained type
* @return a list of tags
* @param <T> the type of list
*/
@SuppressWarnings("unchecked")
public <T extends Tag> List<T> getList(String key, Class<T> listType) {
Tag tag = value.get(key);
if (tag instanceof ListTag) {
ListTag listTag = (ListTag) tag;
if (listTag.getType().equals(listType)) {
return (List<T>) listTag.getValue();
} else {
return Collections.emptyList();
}
} else {
return Collections.emptyList();
}
}
/**
* Get a long named with the given key.
*
* <p>If the key does not exist or its value is not a long tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a long
*/
public long getLong(String key) {
Tag tag = value.get(key);
if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else {
return 0L;
}
}
/**
* Get a long named with the given key, even if it's another
* type of number.
*
* <p>If the key does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a long
*/
public long asLong(String key) {
Tag tag = value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().longValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().longValue();
} else {
return 0L;
}
}
/**
* Get a short named with the given key.
*
* <p>If the key does not exist or its value is not a short tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a short
*/
public short getShort(String key) {
Tag tag = value.get(key);
if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a string named with the given key.
*
* <p>If the key does not exist or its value is not a string tag,
* then {@code ""} will be returned.</p>
*
* @param key the key
* @return a string
*/
public String getString(String key) {
Tag tag = value.get(key);
if (tag instanceof StringTag) {
return ((StringTag) tag).getValue();
} else {
return "";
}
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
StringBuilder bldr = new StringBuilder();
bldr.append("TAG_Compound").append(append).append(": ").append(value.size()).append(" entries\r\n{\r\n");
for (Map.Entry<String, Tag> entry : value.entrySet()) {
bldr.append(" ").append(entry.getValue().toString().replaceAll("\r\n", "\r\n ")).append("\r\n");
}
bldr.append("}");
return bldr.toString();
}
}

View File

@ -0,0 +1,214 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
import java.util.HashMap;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Helps create compound tags.
*/
public class CompoundTagBuilder {
private final Map<String, Tag> entries;
/**
* Create a new instance.
*/
CompoundTagBuilder() {
this.entries = new HashMap<String, Tag>();
}
/**
* Create a new instance and use the given map (which will be modified).
*
* @param value the value
*/
CompoundTagBuilder(Map<String, Tag> value) {
checkNotNull(value);
this.entries = value;
}
/**
* Put the given key and tag into the compound tag.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder put(String key, Tag value) {
checkNotNull(key);
checkNotNull(value);
entries.put(key, value);
return this;
}
/**
* Put the given key and value into the compound tag as a
* {@code ByteArrayTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putByteArray(String key, byte[] value) {
return put(key, new ByteArrayTag(key, value));
}
/**
* Put the given key and value into the compound tag as a
* {@code ByteTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putByte(String key, byte value) {
return put(key, new ByteTag(key, value));
}
/**
* Put the given key and value into the compound tag as a
* {@code DoubleTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putDouble(String key, double value) {
return put(key, new DoubleTag(key, value));
}
/**
* Put the given key and value into the compound tag as a
* {@code FloatTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putFloat(String key, float value) {
return put(key, new FloatTag(key, value));
}
/**
* Put the given key and value into the compound tag as a
* {@code IntArrayTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putIntArray(String key, int[] value) {
return put(key, new IntArrayTag(key, value));
}
/**
* Put the given key and value into the compound tag as an {@code IntTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putInt(String key, int value) {
return put(key, new IntTag(key, value));
}
/**
* Put the given key and value into the compound tag as a
* {@code LongTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putLong(String key, long value) {
return put(key, new LongTag(key, value));
}
/**
* Put the given key and value into the compound tag as a
* {@code ShortTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putShort(String key, short value) {
return put(key, new ShortTag(key, value));
}
/**
* Put the given key and value into the compound tag as a
* {@code StringTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putString(String key, String value) {
return put(key, new StringTag(key, value));
}
/**
* Put all the entries from the given map into this map.
*
* @param value the map of tags
* @return this object
*/
public CompoundTagBuilder putAll(Map<String, ? extends Tag> value) {
checkNotNull(value);
for (Map.Entry<String, ? extends Tag> entry : value.entrySet()) {
put(entry.getKey(), entry.getValue());
}
return this;
}
/**
* Build an unnamed compound tag with this builder's entries.
*
* @return the new compound tag
*/
public CompoundTag build() {
return new CompoundTag(new HashMap<String, Tag>(entries));
}
/**
* Build a new compound tag with this builder's entries.
*
* @param name the name of the tag
* @return the created compound tag
*/
public CompoundTag build(String name) {
return new CompoundTag(name, new HashMap<String, Tag>(entries));
}
/**
* Create a new builder instance.
*
* @return a new builder
*/
public static CompoundTagBuilder create() {
return new CompoundTagBuilder();
}
}

View File

@ -0,0 +1,66 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
/**
* The {@code TAG_Double} tag.
*
*/
public final class DoubleTag extends Tag {
private final double value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public DoubleTag(double value) {
super();
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public DoubleTag(String name, double value) {
super(name);
this.value = value;
}
@Override
public Double getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Double" + append + ": " + value;
}
}

View File

@ -0,0 +1,44 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
/**
* The {@code TAG_End} tag.
*/
public final class EndTag extends Tag {
/**
* Creates the tag.
*/
public EndTag() {
super();
}
@Override
public Object getValue() {
return null;
}
@Override
public String toString() {
return "TAG_End";
}
}

View File

@ -0,0 +1,65 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
/**
* The {@code TAG_Float} tag.
*/
public final class FloatTag extends Tag {
private final float value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public FloatTag(float value) {
super();
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public FloatTag(String name, float value) {
super(name);
this.value = value;
}
@Override
public Float getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Float" + append + ": " + value;
}
}

View File

@ -0,0 +1,77 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The {@code TAG_Int_Array} tag.
*/
public final class IntArrayTag extends Tag {
private final int[] value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public IntArrayTag(int[] value) {
super();
checkNotNull(value);
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public IntArrayTag(String name, int[] value) {
super(name);
checkNotNull(value);
this.value = value;
}
@Override
public int[] getValue() {
return value;
}
@Override
public String toString() {
StringBuilder hex = new StringBuilder();
for (int b : value) {
String hexDigits = Integer.toHexString(b).toUpperCase();
if (hexDigits.length() == 1) {
hex.append("0");
}
hex.append(hexDigits).append(" ");
}
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Int_Array" + append + ": " + hex;
}
}

View File

@ -0,0 +1,65 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
/**
* The {@code TAG_Int} tag.
*/
public final class IntTag extends Tag {
private final int value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public IntTag(int value) {
super();
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public IntTag(String name, int value) {
super(name);
this.value = value;
}
@Override
public Integer getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Int" + append + ": " + value;
}
}

View File

@ -0,0 +1,450 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The {@code TAG_List} tag.
*/
public final class ListTag extends Tag {
private final Class<? extends Tag> type;
private final List<Tag> value;
/**
* Creates the tag with an empty name.
*
* @param type the type of tag
* @param value the value of the tag
*/
public ListTag(Class<? extends Tag> type, List<? extends Tag> value) {
super();
checkNotNull(value);
this.type = type;
this.value = Collections.unmodifiableList(value);
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param type the type of tag
* @param value the value of the tag
*/
public ListTag(String name, Class<? extends Tag> type, List<? extends Tag> value) {
super(name);
checkNotNull(value);
this.type = type;
this.value = Collections.unmodifiableList(value);
}
/**
* Gets the type of item in this list.
*
* @return The type of item in this list.
*/
public Class<? extends Tag> getType() {
return type;
}
@Override
public List<Tag> getValue() {
return value;
}
/**
* Create a new list tag with this tag's name and type.
*
* @param list the new list
* @return a new list tag
*/
public ListTag setValue(List<Tag> list) {
return new ListTag(getName(), getType(), list);
}
/**
* Get the tag if it exists at the given index.
*
* @param index the index
* @return the tag or null
*/
@Nullable
public Tag getIfExists(int index) {
try {
return value.get(index);
} catch (NoSuchElementException e) {
return null;
}
}
/**
* Get a byte array named with the given index.
*
* <p>If the index does not exist or its value is not a byte array tag,
* then an empty byte array will be returned.</p>
*
* @param index the index
* @return a byte array
*/
public byte[] getByteArray(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteArrayTag) {
return ((ByteArrayTag) tag).getValue();
} else {
return new byte[0];
}
}
/**
* Get a byte named with the given index.
*
* <p>If the index does not exist or its value is not a byte tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a byte
*/
public byte getByte(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else {
return (byte) 0;
}
}
/**
* Get a double named with the given index.
*
* <p>If the index does not exist or its value is not a double tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a double
*/
public double getDouble(int index) {
Tag tag = getIfExists(index);
if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a double named with the given index, even if it's another
* type of number.
*
* <p>If the index does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a double
*/
public double asDouble(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a float named with the given index.
*
* <p>If the index does not exist or its value is not a float tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a float
*/
public float getFloat(int index) {
Tag tag = getIfExists(index);
if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a {@code int[]} named with the given index.
*
* <p>If the index does not exist or its value is not an int array tag,
* then an empty array will be returned.</p>
*
* @param index the index
* @return an int array
*/
public int[] getIntArray(int index) {
Tag tag = getIfExists(index);
if (tag instanceof IntArrayTag) {
return ((IntArrayTag) tag).getValue();
} else {
return new int[0];
}
}
/**
* Get an int named with the given index.
*
* <p>If the index does not exist or its value is not an int tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return an int
*/
public int getInt(int index) {
Tag tag = getIfExists(index);
if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get an int named with the given index, even if it's another
* type of number.
*
* <p>If the index does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return an int
*/
public int asInt(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue().intValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().intValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().intValue();
} else {
return 0;
}
}
/**
* Get a list of tags named with the given index.
*
* <p>If the index does not exist or its value is not a list tag,
* then an empty list will be returned.</p>
*
* @param index the index
* @return a list of tags
*/
public List<Tag> getList(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ListTag) {
return ((ListTag) tag).getValue();
} else {
return Collections.emptyList();
}
}
/**
* Get a {@code TagList} named with the given index.
*
* <p>If the index does not exist or its value is not a list tag,
* then an empty tag list will be returned.</p>
*
* @param index the index
* @return a tag list instance
*/
public ListTag getListTag(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ListTag) {
return (ListTag) tag;
} else {
return new ListTag(StringTag.class, Collections.<Tag>emptyList());
}
}
/**
* Get a list of tags named with the given index.
*
* <p>If the index does not exist or its value is not a list tag,
* then an empty list will be returned. If the given index references
* a list but the list of of a different type, then an empty
* list will also be returned.</p>
*
* @param index the index
* @param listType the class of the contained type
* @return a list of tags
* @param <T> the NBT type
*/
@SuppressWarnings("unchecked")
public <T extends Tag> List<T> getList(int index, Class<T> listType) {
Tag tag = getIfExists(index);
if (tag instanceof ListTag) {
ListTag listTag = (ListTag) tag;
if (listTag.getType().equals(listType)) {
return (List<T>) listTag.getValue();
} else {
return Collections.emptyList();
}
} else {
return Collections.emptyList();
}
}
/**
* Get a long named with the given index.
*
* <p>If the index does not exist or its value is not a long tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a long
*/
public long getLong(int index) {
Tag tag = getIfExists(index);
if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else {
return 0L;
}
}
/**
* Get a long named with the given index, even if it's another
* type of number.
*
* <p>If the index does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a long
*/
public long asLong(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().longValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().longValue();
} else {
return 0;
}
}
/**
* Get a short named with the given index.
*
* <p>If the index does not exist or its value is not a short tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a short
*/
public short getShort(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a string named with the given index.
*
* <p>If the index does not exist or its value is not a string tag,
* then {@code ""} will be returned.</p>
*
* @param index the index
* @return a string
*/
public String getString(int index) {
Tag tag = getIfExists(index);
if (tag instanceof StringTag) {
return ((StringTag) tag).getValue();
} else {
return "";
}
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
StringBuilder bldr = new StringBuilder();
bldr.append("TAG_List").append(append).append(": ").append(value.size()).append(" entries of type ").append(NBTUtils.getTypeName(type)).append("\r\n{\r\n");
for (Tag t : value) {
bldr.append(" ").append(t.toString().replaceAll("\r\n", "\r\n ")).append("\r\n");
}
bldr.append("}");
return bldr.toString();
}
}

View File

@ -0,0 +1,129 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Helps create list tags.
*/
public class ListTagBuilder {
private final Class<? extends Tag> type;
private final List<Tag> entries;
/**
* Create a new instance.
*
* @param type of tag contained in this list
*/
ListTagBuilder(Class<? extends Tag> type) {
checkNotNull(type);
this.type = type;
this.entries = new ArrayList<Tag>();
}
/**
* Add the given tag.
*
* @param value the tag
* @return this object
*/
public ListTagBuilder add(Tag value) {
checkNotNull(value);
if (!type.isInstance(value)) {
throw new IllegalArgumentException(value.getClass().getCanonicalName() + " is not of expected type " + type.getCanonicalName());
}
entries.add(value);
return this;
}
/**
* Add all the tags in the given list.
*
* @param value a list of tags
* @return this object
*/
public ListTagBuilder addAll(Collection<? extends Tag> value) {
checkNotNull(value);
for (Tag v : value) {
add(v);
}
return this;
}
/**
* Build an unnamed list tag with this builder's entries.
*
* @return the new list tag
*/
public ListTag build() {
return new ListTag(type, new ArrayList<Tag>(entries));
}
/**
* Build a new list tag with this builder's entries.
*
* @param name the name of the tag
* @return the created list tag
*/
public ListTag build(String name) {
return new ListTag(name, type, new ArrayList<Tag>(entries));
}
/**
* Create a new builder instance.
*
* @return a new builder
*/
public static ListTagBuilder create(Class<? extends Tag> type) {
return new ListTagBuilder(type);
}
/**
* Create a new builder instance.
*
* @return a new builder
*/
public static <T extends Tag> ListTagBuilder createWith(T ... entries) {
checkNotNull(entries);
if (entries.length == 0) {
throw new IllegalArgumentException("This method needs an array of at least one entry");
}
Class<? extends Tag> type = entries[0].getClass();
for (int i = 1; i < entries.length; i++) {
if (!type.isInstance(entries[i])) {
throw new IllegalArgumentException("An array of different tag types was provided");
}
}
ListTagBuilder builder = new ListTagBuilder(type);
builder.addAll(Arrays.asList(entries));
return builder;
}
}

View File

@ -0,0 +1,66 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
/**
* The {@code TAG_Long} tag.
*
*/
public final class LongTag extends Tag {
private final long value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public LongTag(long value) {
super();
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public LongTag(String name, long value) {
super(name);
this.value = value;
}
@Override
public Long getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Long" + append + ": " + value;
}
}

View File

@ -0,0 +1,81 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
import java.nio.charset.Charset;
/**
* A class which holds constant values.
*/
public final class NBTConstants {
public static final Charset CHARSET = Charset.forName("UTF-8");
public static final int TYPE_END = 0, TYPE_BYTE = 1, TYPE_SHORT = 2,
TYPE_INT = 3, TYPE_LONG = 4, TYPE_FLOAT = 5, TYPE_DOUBLE = 6,
TYPE_BYTE_ARRAY = 7, TYPE_STRING = 8, TYPE_LIST = 9,
TYPE_COMPOUND = 10, TYPE_INT_ARRAY = 11;
/**
* Default private constructor.
*/
private NBTConstants() {
}
/**
* Convert a type ID to its corresponding {@link Tag} class.
*
* @param id type ID
* @return tag class
* @throws IllegalArgumentException thrown if the tag ID is not valid
*/
public static Class<? extends Tag> getClassFromType(int id) {
switch (id) {
case TYPE_END:
return EndTag.class;
case TYPE_BYTE:
return ByteTag.class;
case TYPE_SHORT:
return ShortTag.class;
case TYPE_INT:
return IntTag.class;
case TYPE_LONG:
return LongTag.class;
case TYPE_FLOAT:
return FloatTag.class;
case TYPE_DOUBLE:
return DoubleTag.class;
case TYPE_BYTE_ARRAY:
return ByteArrayTag.class;
case TYPE_STRING:
return StringTag.class;
case TYPE_LIST:
return ListTag.class;
case TYPE_COMPOUND:
return CompoundTag.class;
case TYPE_INT_ARRAY:
return IntArrayTag.class;
default:
throw new IllegalArgumentException("Unknown tag type ID of " + id);
}
}
}

View File

@ -0,0 +1,171 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This class reads <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
* streams, and produces an object graph of subclasses of the {@code Tag}
* object.
*
* <p>The NBT format was created by Markus Persson, and the specification may be
* found at <a href="http://www.minecraft.net/docs/NBT.txt">
* http://www.minecraft.net/docs/NBT.txt</a>.</p>
*/
public final class NBTInputStream implements Closeable {
private final DataInputStream is;
/**
* Creates a new {@code NBTInputStream}, which will source its data
* from the specified input stream.
*
* @param is the input stream
* @throws IOException if an I/O error occurs
*/
public NBTInputStream(InputStream is) throws IOException {
this.is = new DataInputStream(is);
}
/**
* Reads an NBT tag from the stream.
*
* @return The tag that was read.
* @throws IOException if an I/O error occurs.
*/
public Tag readTag() throws IOException {
return readTag(0);
}
/**
* Reads an NBT from the stream.
*
* @param depth the depth of this tag
* @return The tag that was read.
* @throws IOException if an I/O error occurs.
*/
private Tag readTag(int depth) throws IOException {
int type = is.readByte() & 0xFF;
String name;
if (type != NBTConstants.TYPE_END) {
int nameLength = is.readShort() & 0xFFFF;
byte[] nameBytes = new byte[nameLength];
is.readFully(nameBytes);
name = new String(nameBytes, NBTConstants.CHARSET);
} else {
name = "";
}
return readTagPayload(type, name, depth);
}
/**
* Reads the payload of a tag, given the name and type.
*
* @param type the type
* @param name the name
* @param depth the depth
* @return the tag
* @throws IOException if an I/O error occurs.
*/
private Tag readTagPayload(int type, String name, int depth) throws IOException {
switch (type) {
case NBTConstants.TYPE_END:
if (depth == 0) {
throw new IOException(
"TAG_End found without a TAG_Compound/TAG_List tag preceding it.");
} else {
return new EndTag();
}
case NBTConstants.TYPE_BYTE:
return new ByteTag(name, is.readByte());
case NBTConstants.TYPE_SHORT:
return new ShortTag(name, is.readShort());
case NBTConstants.TYPE_INT:
return new IntTag(name, is.readInt());
case NBTConstants.TYPE_LONG:
return new LongTag(name, is.readLong());
case NBTConstants.TYPE_FLOAT:
return new FloatTag(name, is.readFloat());
case NBTConstants.TYPE_DOUBLE:
return new DoubleTag(name, is.readDouble());
case NBTConstants.TYPE_BYTE_ARRAY:
int length = is.readInt();
byte[] bytes = new byte[length];
is.readFully(bytes);
return new ByteArrayTag(name, bytes);
case NBTConstants.TYPE_STRING:
length = is.readShort();
bytes = new byte[length];
is.readFully(bytes);
return new StringTag(name, new String(bytes, NBTConstants.CHARSET));
case NBTConstants.TYPE_LIST:
int childType = is.readByte();
length = is.readInt();
List<Tag> tagList = new ArrayList<Tag>();
for (int i = 0; i < length; ++i) {
Tag tag = readTagPayload(childType, "", depth + 1);
if (tag instanceof EndTag) {
throw new IOException("TAG_End not permitted in a list.");
}
tagList.add(tag);
}
return new ListTag(name, NBTUtils.getTypeClass(childType), tagList);
case NBTConstants.TYPE_COMPOUND:
Map<String, Tag> tagMap = new HashMap<String, Tag>();
while (true) {
Tag tag = readTag(depth + 1);
if (tag instanceof EndTag) {
break;
} else {
tagMap.put(tag.getName(), tag);
}
}
return new CompoundTag(name, tagMap);
case NBTConstants.TYPE_INT_ARRAY:
length = is.readInt();
int[] data = new int[length];
for (int i = 0; i < length; i++) {
data[i] = is.readInt();
}
return new IntArrayTag(name, data);
default:
throw new IOException("Invalid tag type: " + type + ".");
}
}
@Override
public void close() throws IOException {
is.close();
}
}

View File

@ -0,0 +1,289 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
import java.io.Closeable;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
/**
* This class writes <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
* {@code Tag} objects to an underlying {@code OutputStream}.
*
* <p>The NBT format was created by Markus Persson, and the specification may be
* found at <a href="http://www.minecraft.net/docs/NBT.txt">
* http://www.minecraft.net/docs/NBT.txt</a>.</p>
*/
public final class NBTOutputStream implements Closeable {
/**
* The output stream.
*/
private final DataOutputStream os;
/**
* Creates a new {@code NBTOutputStream}, which will write data to the
* specified underlying output stream.
*
* @param os
* The output stream.
* @throws IOException
* if an I/O error occurs.
*/
public NBTOutputStream(OutputStream os) throws IOException {
this.os = new DataOutputStream(os);
}
/**
* Writes a tag.
*
* @param tag
* The tag to write.
* @throws IOException
* if an I/O error occurs.
*/
public void writeTag(Tag tag) throws IOException {
int type = NBTUtils.getTypeCode(tag.getClass());
String name = tag.getName();
byte[] nameBytes = name.getBytes(NBTConstants.CHARSET);
os.writeByte(type);
os.writeShort(nameBytes.length);
os.write(nameBytes);
if (type == NBTConstants.TYPE_END) {
throw new IOException("Named TAG_End not permitted.");
}
writeTagPayload(tag);
}
/**
* Writes tag payload.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeTagPayload(Tag tag) throws IOException {
int type = NBTUtils.getTypeCode(tag.getClass());
switch (type) {
case NBTConstants.TYPE_END:
writeEndTagPayload((EndTag) tag);
break;
case NBTConstants.TYPE_BYTE:
writeByteTagPayload((ByteTag) tag);
break;
case NBTConstants.TYPE_SHORT:
writeShortTagPayload((ShortTag) tag);
break;
case NBTConstants.TYPE_INT:
writeIntTagPayload((IntTag) tag);
break;
case NBTConstants.TYPE_LONG:
writeLongTagPayload((LongTag) tag);
break;
case NBTConstants.TYPE_FLOAT:
writeFloatTagPayload((FloatTag) tag);
break;
case NBTConstants.TYPE_DOUBLE:
writeDoubleTagPayload((DoubleTag) tag);
break;
case NBTConstants.TYPE_BYTE_ARRAY:
writeByteArrayTagPayload((ByteArrayTag) tag);
break;
case NBTConstants.TYPE_STRING:
writeStringTagPayload((StringTag) tag);
break;
case NBTConstants.TYPE_LIST:
writeListTagPayload((ListTag) tag);
break;
case NBTConstants.TYPE_COMPOUND:
writeCompoundTagPayload((CompoundTag) tag);
break;
case NBTConstants.TYPE_INT_ARRAY:
writeIntArrayTagPayload((IntArrayTag) tag);
break;
default:
throw new IOException("Invalid tag type: " + type + ".");
}
}
/**
* Writes a {@code TAG_Byte} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeByteTagPayload(ByteTag tag) throws IOException {
os.writeByte(tag.getValue());
}
/**
* Writes a {@code TAG_Byte_Array} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeByteArrayTagPayload(ByteArrayTag tag) throws IOException {
byte[] bytes = tag.getValue();
os.writeInt(bytes.length);
os.write(bytes);
}
/**
* Writes a {@code TAG_Compound} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeCompoundTagPayload(CompoundTag tag) throws IOException {
for (Tag childTag : tag.getValue().values()) {
writeTag(childTag);
}
os.writeByte((byte) 0); // end tag - better way?
}
/**
* Writes a {@code TAG_List} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeListTagPayload(ListTag tag) throws IOException {
Class<? extends Tag> clazz = tag.getType();
List<Tag> tags = tag.getValue();
int size = tags.size();
os.writeByte(NBTUtils.getTypeCode(clazz));
os.writeInt(size);
for (Tag tag1 : tags) {
writeTagPayload(tag1);
}
}
/**
* Writes a {@code TAG_String} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeStringTagPayload(StringTag tag) throws IOException {
byte[] bytes = tag.getValue().getBytes(NBTConstants.CHARSET);
os.writeShort(bytes.length);
os.write(bytes);
}
/**
* Writes a {@code TAG_Double} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeDoubleTagPayload(DoubleTag tag) throws IOException {
os.writeDouble(tag.getValue());
}
/**
* Writes a {@code TAG_Float} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeFloatTagPayload(FloatTag tag) throws IOException {
os.writeFloat(tag.getValue());
}
/**
* Writes a {@code TAG_Long} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeLongTagPayload(LongTag tag) throws IOException {
os.writeLong(tag.getValue());
}
/**
* Writes a {@code TAG_Int} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeIntTagPayload(IntTag tag) throws IOException {
os.writeInt(tag.getValue());
}
/**
* Writes a {@code TAG_Short} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeShortTagPayload(ShortTag tag) throws IOException {
os.writeShort(tag.getValue());
}
/**
* Writes a {@code TAG_Empty} tag.
*
* @param tag the tag
*/
private void writeEndTagPayload(EndTag tag) {
/* empty */
}
private void writeIntArrayTagPayload(IntArrayTag tag) throws IOException {
int[] data = tag.getValue();
os.writeInt(data.length);
for (int aData : data) {
os.writeInt(aData);
}
}
@Override
public void close() throws IOException {
os.close();
}
}

View File

@ -0,0 +1,189 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.world.storage.InvalidFormatException;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A class which contains NBT-related utility methods.
*
*/
public final class NBTUtils {
/**
* Default private constructor.
*/
private NBTUtils() {
}
/**
* Gets the type name of a tag.
*
* @param clazz the tag class
* @return The type name.
*/
public static String getTypeName(Class<? extends Tag> clazz) {
if (clazz.equals(ByteArrayTag.class)) {
return "TAG_Byte_Array";
} else if (clazz.equals(ByteTag.class)) {
return "TAG_Byte";
} else if (clazz.equals(CompoundTag.class)) {
return "TAG_Compound";
} else if (clazz.equals(DoubleTag.class)) {
return "TAG_Double";
} else if (clazz.equals(EndTag.class)) {
return "TAG_End";
} else if (clazz.equals(FloatTag.class)) {
return "TAG_Float";
} else if (clazz.equals(IntTag.class)) {
return "TAG_Int";
} else if (clazz.equals(ListTag.class)) {
return "TAG_List";
} else if (clazz.equals(LongTag.class)) {
return "TAG_Long";
} else if (clazz.equals(ShortTag.class)) {
return "TAG_Short";
} else if (clazz.equals(StringTag.class)) {
return "TAG_String";
} else if (clazz.equals(IntArrayTag.class)) {
return "TAG_Int_Array";
} else {
throw new IllegalArgumentException("Invalid tag classs ("
+ clazz.getName() + ").");
}
}
/**
* Gets the type code of a tag class.
*
* @param clazz the tag class
* @return The type code.
* @throws IllegalArgumentException if the tag class is invalid.
*/
public static int getTypeCode(Class<? extends Tag> clazz) {
if (clazz.equals(ByteArrayTag.class)) {
return NBTConstants.TYPE_BYTE_ARRAY;
} else if (clazz.equals(ByteTag.class)) {
return NBTConstants.TYPE_BYTE;
} else if (clazz.equals(CompoundTag.class)) {
return NBTConstants.TYPE_COMPOUND;
} else if (clazz.equals(DoubleTag.class)) {
return NBTConstants.TYPE_DOUBLE;
} else if (clazz.equals(EndTag.class)) {
return NBTConstants.TYPE_END;
} else if (clazz.equals(FloatTag.class)) {
return NBTConstants.TYPE_FLOAT;
} else if (clazz.equals(IntTag.class)) {
return NBTConstants.TYPE_INT;
} else if (clazz.equals(ListTag.class)) {
return NBTConstants.TYPE_LIST;
} else if (clazz.equals(LongTag.class)) {
return NBTConstants.TYPE_LONG;
} else if (clazz.equals(ShortTag.class)) {
return NBTConstants.TYPE_SHORT;
} else if (clazz.equals(StringTag.class)) {
return NBTConstants.TYPE_STRING;
} else if (clazz.equals(IntArrayTag.class)) {
return NBTConstants.TYPE_INT_ARRAY;
} else {
throw new IllegalArgumentException("Invalid tag classs ("
+ clazz.getName() + ").");
}
}
/**
* Gets the class of a type of tag.
*
* @param type the type
* @return The class.
* @throws IllegalArgumentException if the tag type is invalid.
*/
public static Class<? extends Tag> getTypeClass(int type) {
switch (type) {
case NBTConstants.TYPE_END:
return EndTag.class;
case NBTConstants.TYPE_BYTE:
return ByteTag.class;
case NBTConstants.TYPE_SHORT:
return ShortTag.class;
case NBTConstants.TYPE_INT:
return IntTag.class;
case NBTConstants.TYPE_LONG:
return LongTag.class;
case NBTConstants.TYPE_FLOAT:
return FloatTag.class;
case NBTConstants.TYPE_DOUBLE:
return DoubleTag.class;
case NBTConstants.TYPE_BYTE_ARRAY:
return ByteArrayTag.class;
case NBTConstants.TYPE_STRING:
return StringTag.class;
case NBTConstants.TYPE_LIST:
return ListTag.class;
case NBTConstants.TYPE_COMPOUND:
return CompoundTag.class;
case NBTConstants.TYPE_INT_ARRAY:
return IntArrayTag.class;
default:
throw new IllegalArgumentException("Invalid tag type : " + type
+ ".");
}
}
/**
* Read a vector from a list tag containing ideally three values: the
* X, Y, and Z components.
*
* <p>For values that are unavailable, their values will be 0.</p>
*
* @param listTag the list tag
* @return a vector
*/
public static Vector toVector(ListTag listTag) {
checkNotNull(listTag);
return new Vector(listTag.asDouble(0), listTag.asDouble(1), listTag.asDouble(2));
}
/**
* Get child tag of a NBT structure.
*
* @param items the map to read from
* @param key the key to look for
* @param expected the expected NBT class type
* @return child tag
* @throws InvalidFormatException
*/
public static <T extends Tag> T getChildTag(Map<String, Tag> items, String key, Class<T> expected) throws InvalidFormatException {
if (!items.containsKey(key)) {
throw new InvalidFormatException("Missing a \"" + key + "\" tag");
}
Tag tag = items.get(key);
if (!expected.isInstance(tag)) {
throw new InvalidFormatException(key + " tag is not of tag type " + expected.getName());
}
return expected.cast(tag);
}
}

View File

@ -0,0 +1,65 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
/**
* The {@code TAG_Short} tag.
*/
public final class ShortTag extends Tag {
private final short value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public ShortTag(short value) {
super();
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public ShortTag(String name, short value) {
super(name);
this.value = value;
}
@Override
public Short getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Short" + append + ": " + value;
}
}

View File

@ -0,0 +1,69 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The {@code TAG_String} tag.
*/
public final class StringTag extends Tag {
private final String value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public StringTag(String value) {
super();
checkNotNull(value);
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public StringTag(String name, String value) {
super(name);
checkNotNull(value);
this.value = value;
}
@Override
public String getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_String" + append + ": " + value;
}
}

View File

@ -0,0 +1,64 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.jnbt;
/**
* Represents a NBT tag.
*/
public abstract class Tag {
private final String name;
/**
* Create a new tag with an empty name.
*/
Tag() {
this("");
}
/**
* Creates the tag with the specified name.
*
* @param name the name
*/
Tag(String name) {
if (name == null) {
name = "";
}
this.name = name;
}
/**
* Gets the name of this tag.
*
* @return the name of this tag
*/
public final String getName() {
return name;
}
/**
* Gets the value of this tag.
*
* @return the value
*/
public abstract Object getValue();
}

View File

@ -0,0 +1,93 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* This annotation indicates a command. Methods should be marked with this
* annotation to tell {@link CommandsManager} that the method is a command.
* Note that the method name can actually be anything.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Command {
/**
* A list of aliases for the command. The first alias is the most
* important -- it is the main name of the command. (The method name
* is never used for anything).
*
* @return Aliases for a command
*/
String[] aliases();
/**
* Usage instruction. Example text for usage could be
* {@code [-h harps] [name] [message]}.
*
* @return Usage instructions for a command
*/
String usage() default "";
/**
* @return A short description for the command.
*/
String desc();
/**
* The minimum number of arguments. This should be 0 or above.
*
* @return the minimum number of arguments
*/
int min() default 0;
/**
* The maximum number of arguments. Use -1 for an unlimited number
* of arguments.
*
* @return the maximum number of arguments
*/
int max() default -1;
/**
* Flags allow special processing for flags such as -h in the command,
* allowing users to easily turn on a flag. This is a string with
* each character being a flag. Use A-Z and a-z as possible flags.
* Appending a flag with a : makes the flag character before a value flag,
* meaning that if it is given it must have a value
*
* @return Flags matching a-zA-Z
*/
String flags() default "";
/**
* @return A long description for the command.
*/
String help() default "";
/**
* Get whether any flag can be used.
*
* @return true if so
*/
boolean anyFlags() default false;
}

View File

@ -0,0 +1,40 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Any command with this annotation will run the raw command as shown in the
* thing, as long as it is registered in the current {@link CommandsManager}.
* Mostly to move commands around without breaking things.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandAlias {
/**
* Get the raw {@link CommandsManager}-formatted command arg array to run
*
* @return the command
*/
String[] value();
}

View File

@ -0,0 +1,339 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CommandContext {
protected final String command;
protected final List<String> parsedArgs;
protected final List<Integer> originalArgIndices;
protected final String[] originalArgs;
protected final Set<Character> booleanFlags = new HashSet<Character>();
protected final Map<Character, String> valueFlags = new HashMap<Character, String>();
protected final SuggestionContext suggestionContext;
protected final CommandLocals locals;
public static String[] split(String args) {
return args.split(" ", -1);
}
public CommandContext(String args) throws CommandException {
this(args.split(" ", -1), null);
}
public CommandContext(String[] args) throws CommandException {
this(args, null);
}
public CommandContext(String args, Set<Character> valueFlags) throws CommandException {
this(args.split(" ", -1), valueFlags);
}
public CommandContext(String args, Set<Character> valueFlags, boolean allowHangingFlag)
throws CommandException {
this(args.split(" ", -1), valueFlags, allowHangingFlag, new CommandLocals());
}
public CommandContext(String[] args, Set<Character> valueFlags) throws CommandException {
this(args, valueFlags, false, null);
}
/**
* Parse the given array of arguments.
*
* <p>Empty arguments are removed from the list of arguments.</p>
*
* @param args an array with arguments
* @param valueFlags a set containing all value flags (pass null to disable value flag parsing)
* @param allowHangingFlag true if hanging flags are allowed
* @param locals the locals, null to create empty one
* @throws CommandException thrown on a parsing error
*/
public CommandContext(String[] args, Set<Character> valueFlags,
boolean allowHangingFlag, CommandLocals locals) throws CommandException {
if (valueFlags == null) {
valueFlags = Collections.emptySet();
}
originalArgs = args;
command = args[0];
this.locals = locals != null ? locals : new CommandLocals();
boolean isHanging = false;
SuggestionContext suggestionContext = SuggestionContext.hangingValue();
// Eliminate empty args and combine multiword args first
List<Integer> argIndexList = new ArrayList<Integer>(args.length);
List<String> argList = new ArrayList<String>(args.length);
for (int i = 1; i < args.length; ++i) {
isHanging = false;
String arg = args[i];
if (arg.isEmpty()) {
isHanging = true;
continue;
}
argIndexList.add(i);
switch (arg.charAt(0)) {
case '\'':
case '"':
final StringBuilder build = new StringBuilder();
final char quotedChar = arg.charAt(0);
int endIndex;
for (endIndex = i; endIndex < args.length; ++endIndex) {
final String arg2 = args[endIndex];
if (arg2.charAt(arg2.length() - 1) == quotedChar && arg2.length() > 1) {
if (endIndex != i) build.append(' ');
build.append(arg2.substring(endIndex == i ? 1 : 0, arg2.length() - 1));
break;
} else if (endIndex == i) {
build.append(arg2.substring(1));
} else {
build.append(' ').append(arg2);
}
}
if (endIndex < args.length) {
arg = build.toString();
i = endIndex;
}
// In case there is an empty quoted string
if (arg.isEmpty()) {
continue;
}
// else raise exception about hanging quotes?
}
argList.add(arg);
}
// Then flags
this.originalArgIndices = new ArrayList<Integer>(argIndexList.size());
this.parsedArgs = new ArrayList<String>(argList.size());
for (int nextArg = 0; nextArg < argList.size(); ) {
// Fetch argument
String arg = argList.get(nextArg++);
suggestionContext = SuggestionContext.hangingValue();
// Not a flag?
if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z\\?]+$")) {
if (!isHanging) {
suggestionContext = SuggestionContext.lastValue();
}
originalArgIndices.add(argIndexList.get(nextArg - 1));
parsedArgs.add(arg);
continue;
}
// Handle flag parsing terminator --
if (arg.equals("--")) {
while (nextArg < argList.size()) {
originalArgIndices.add(argIndexList.get(nextArg));
parsedArgs.add(argList.get(nextArg++));
}
break;
}
// Go through the flag characters
for (int i = 1; i < arg.length(); ++i) {
char flagName = arg.charAt(i);
if (valueFlags.contains(flagName)) {
if (this.valueFlags.containsKey(flagName)) {
throw new CommandException("Value flag '" + flagName + "' already given");
}
if (nextArg >= argList.size()) {
if (allowHangingFlag) {
suggestionContext = SuggestionContext.flag(flagName);
break;
} else {
throw new CommandException("No value specified for the '-" + flagName + "' flag.");
}
}
// If it is a value flag, read another argument and add it
this.valueFlags.put(flagName, argList.get(nextArg++));
if (!isHanging) {
suggestionContext = SuggestionContext.flag(flagName);
}
} else {
booleanFlags.add(flagName);
}
}
}
this.suggestionContext = suggestionContext;
}
public SuggestionContext getSuggestionContext() {
return suggestionContext;
}
public String getCommand() {
return command;
}
public boolean matches(String command) {
return this.command.equalsIgnoreCase(command);
}
public String getString(int index) {
return parsedArgs.get(index);
}
public String getString(int index, String def) {
return index < parsedArgs.size() ? parsedArgs.get(index) : def;
}
public String getJoinedStrings(int initialIndex) {
initialIndex = originalArgIndices.get(initialIndex);
StringBuilder buffer = new StringBuilder(originalArgs[initialIndex]);
for (int i = initialIndex + 1; i < originalArgs.length; ++i) {
buffer.append(" ").append(originalArgs[i]);
}
return buffer.toString();
}
public String getRemainingString(int start) {
return getString(start, parsedArgs.size() - 1);
}
public String getString(int start, int end) {
StringBuilder buffer = new StringBuilder(parsedArgs.get(start));
for (int i = start + 1; i < end + 1; ++i) {
buffer.append(" ").append(parsedArgs.get(i));
}
return buffer.toString();
}
public int getInteger(int index) throws NumberFormatException {
return Integer.parseInt(parsedArgs.get(index));
}
public int getInteger(int index, int def) throws NumberFormatException {
return index < parsedArgs.size() ? Integer.parseInt(parsedArgs.get(index)) : def;
}
public double getDouble(int index) throws NumberFormatException {
return Double.parseDouble(parsedArgs.get(index));
}
public double getDouble(int index, double def) throws NumberFormatException {
return index < parsedArgs.size() ? Double.parseDouble(parsedArgs.get(index)) : def;
}
public String[] getSlice(int index) {
String[] slice = new String[originalArgs.length - index];
System.arraycopy(originalArgs, index, slice, 0, originalArgs.length - index);
return slice;
}
public String[] getPaddedSlice(int index, int padding) {
String[] slice = new String[originalArgs.length - index + padding];
System.arraycopy(originalArgs, index, slice, padding, originalArgs.length - index);
return slice;
}
public String[] getParsedSlice(int index) {
String[] slice = new String[parsedArgs.size() - index];
System.arraycopy(parsedArgs.toArray(new String[parsedArgs.size()]), index, slice, 0, parsedArgs.size() - index);
return slice;
}
public String[] getParsedPaddedSlice(int index, int padding) {
String[] slice = new String[parsedArgs.size() - index + padding];
System.arraycopy(parsedArgs.toArray(new String[parsedArgs.size()]), index, slice, padding, parsedArgs.size() - index);
return slice;
}
public boolean hasFlag(char ch) {
return booleanFlags.contains(ch) || valueFlags.containsKey(ch);
}
public Set<Character> getFlags() {
return booleanFlags;
}
public Map<Character, String> getValueFlags() {
return valueFlags;
}
public String getFlag(char ch) {
return valueFlags.get(ch);
}
public String getFlag(char ch, String def) {
final String value = valueFlags.get(ch);
if (value == null) {
return def;
}
return value;
}
public int getFlagInteger(char ch) throws NumberFormatException {
return Integer.parseInt(valueFlags.get(ch));
}
public int getFlagInteger(char ch, int def) throws NumberFormatException {
final String value = valueFlags.get(ch);
if (value == null) {
return def;
}
return Integer.parseInt(value);
}
public double getFlagDouble(char ch) throws NumberFormatException {
return Double.parseDouble(valueFlags.get(ch));
}
public double getFlagDouble(char ch, double def) throws NumberFormatException {
final String value = valueFlags.get(ch);
if (value == null) {
return def;
}
return Double.parseDouble(value);
}
public int argsLength() {
return parsedArgs.size();
}
public CommandLocals getLocals() {
return locals;
}
}

View File

@ -0,0 +1,83 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import static com.google.common.base.Preconditions.checkNotNull;
public class CommandException extends Exception {
private List<String> commandStack = new ArrayList<String>();
public CommandException() {
super();
}
public CommandException(String message) {
super(message);
}
public CommandException(String message, Throwable t) {
super(message, t);
}
public CommandException(Throwable t) {
super(t);
}
public void prependStack(String name) {
commandStack.add(name);
}
/**
* Gets the command that was called, which will include the sub-command
* (i.e. "/br sphere").
*
* @param prefix the command shebang character (such as "/") -- may be empty
* @param spacedSuffix a suffix to put at the end (optional) -- may be null
* @return the command that was used
*/
public String getCommandUsed(String prefix, @Nullable String spacedSuffix) {
checkNotNull(prefix);
StringBuilder builder = new StringBuilder();
if (prefix != null) {
builder.append(prefix);
}
ListIterator<String> li = commandStack.listIterator(commandStack.size());
while (li.hasPrevious()) {
if (li.previousIndex() != commandStack.size() - 1) {
builder.append(" ");
}
builder.append(li.previous());
}
if (spacedSuffix != null) {
if (builder.length() > 0) {
builder.append(" ");
}
builder.append(spacedSuffix);
}
return builder.toString().trim();
}
}

View File

@ -0,0 +1,50 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import java.util.HashMap;
import java.util.Map;
public class CommandLocals {
private final Map<Object, Object> locals = new HashMap<Object, Object>();
public boolean containsKey(Object key) {
return locals.containsKey(key);
}
public boolean containsValue(Object value) {
return locals.containsValue(value);
}
public Object get(Object key) {
return locals.get(key);
}
@SuppressWarnings("unchecked")
public <T> T get(Class<T> key) {
return (T) locals.get(key);
}
public Object put(Object key, Object value) {
return locals.put(key, value);
}
}

View File

@ -0,0 +1,39 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Indicates a list of permissions that should be checked.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandPermissions {
/**
* A list of permissions. Only one permission has to be met
* for the command to be permitted.
*
* @return a list of permissions strings
*/
String[] value();
}

View File

@ -0,0 +1,27 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
/**
* Thrown when not enough permissions are satisfied.
*/
public class CommandPermissionsException extends CommandException {
}

View File

@ -0,0 +1,34 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
public class CommandUsageException extends CommandException {
protected String usage;
public CommandUsageException(String message, String usage) {
super(message);
this.usage = usage;
}
public String getUsage() {
return usage;
}
}

View File

@ -0,0 +1,591 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import com.sk89q.util.StringUtil;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Manager for handling commands. This allows you to easily process commands,
* including nested commands, by correctly annotating methods of a class.
*
* <p>To use this, it is merely a matter of registering classes containing
* the commands (as methods with the proper annotations) with the
* manager. When you want to process a command, use one of the
* {@code execute} methods. If something is wrong, such as incorrect
* usage, insufficient permissions, or a missing command altogether, an
* exception will be raised for upstream handling.</p>
*
* <p>Methods of a class to be registered can be static, but if an injector
* is registered with the class, the instances of the command classes
* will be created automatically and methods will be called non-statically.</p>
*
* <p>To mark a method as a command, use {@link Command}. For nested commands,
* see {@link NestedCommand}. To handle permissions, use
* {@link CommandPermissions}.</p>
*
* <p>This uses Java reflection extensively, but to reduce the overhead of
* reflection, command lookups are completely cached on registration. This
* allows for fast command handling. Method invocation still has to be done
* with reflection, but this is quite fast in that of itself.</p>
*
* @param <T> command sender class
*/
@SuppressWarnings("ProtectedField")
public abstract class CommandsManager<T> {
protected static final Logger logger =
Logger.getLogger(CommandsManager.class.getCanonicalName());
/**
* Mapping of commands (including aliases) with a description. Root
* commands are stored under a key of null, whereas child commands are
* cached under their respective {@link Method}. The child map has
* the key of the command name (one for each alias) with the
* method.
*/
protected Map<Method, Map<String, Method>> commands = new HashMap<Method, Map<String, Method>>();
/**
* Used to store the instances associated with a method.
*/
protected Map<Method, Object> instances = new HashMap<Method, Object>();
/**
* Mapping of commands (not including aliases) with a description. This
* is only for top level commands.
*/
protected Map<String, String> descs = new HashMap<String, String>();
/**
* Stores the injector used to getInstance.
*/
protected Injector injector;
/**
* Mapping of commands (not including aliases) with a description. This
* is only for top level commands.
*/
protected Map<String, String> helpMessages = new HashMap<String, String>();
/**
* Register an class that contains commands (denoted by {@link Command}.
* If no dependency injector is specified, then the methods of the
* class will be registered to be called statically. Otherwise, new
* instances will be created of the command classes and methods will
* not be called statically.
*
* @param cls the class to register
*/
public void register(Class<?> cls) {
registerMethods(cls, null);
}
/**
* Register an class that contains commands (denoted by {@link Command}.
* If no dependency injector is specified, then the methods of the
* class will be registered to be called statically. Otherwise, new
* instances will be created of the command classes and methods will
* not be called statically. A List of {@link Command} annotations from
* registered commands is returned.
*
* @param cls the class to register
* @return A List of {@link Command} annotations from registered commands,
* for use in eg. a dynamic command registration system.
*/
public List<Command> registerAndReturn(Class<?> cls) {
return registerMethods(cls, null);
}
/**
* Register the methods of a class. This will automatically construct
* instances as necessary.
*
* @param cls the class to register
* @param parent the parent method
* @return Commands Registered
*/
public List<Command> registerMethods(Class<?> cls, Method parent) {
try {
if (getInjector() == null) {
return registerMethods(cls, parent, null);
} else {
Object obj = getInjector().getInstance(cls);
return registerMethods(cls, parent, obj);
}
} catch (InvocationTargetException e) {
logger.log(Level.SEVERE, "Failed to register commands", e);
} catch (IllegalAccessException e) {
logger.log(Level.SEVERE, "Failed to register commands", e);
} catch (InstantiationException e) {
logger.log(Level.SEVERE, "Failed to register commands", e);
}
return null;
}
/**
* Register the methods of a class.
*
* @param cls the class to register
* @param parent the parent method
* @param obj the object whose methods will become commands if they are annotated
* @return a list of commands
*/
private List<Command> registerMethods(Class<?> cls, Method parent, Object obj) {
Map<String, Method> map;
List<Command> registered = new ArrayList<Command>();
// Make a new hash map to cache the commands for this class
// as looking up methods via reflection is fairly slow
if (commands.containsKey(parent)) {
map = commands.get(parent);
} else {
map = new HashMap<String, Method>();
commands.put(parent, map);
}
for (Method method : cls.getMethods()) {
if (!method.isAnnotationPresent(Command.class)) {
continue;
}
boolean isStatic = Modifier.isStatic(method.getModifiers());
Command cmd = method.getAnnotation(Command.class);
// Cache the aliases too
for (String alias : cmd.aliases()) {
map.put(alias, method);
}
// We want to be able invoke with an instance
if (!isStatic) {
// Can't register this command if we don't have an instance
if (obj == null) {
continue;
}
instances.put(method, obj);
}
// Build a list of commands and their usage details, at least for
// root level commands
if (parent == null) {
final String commandName = cmd.aliases()[0];
final String desc = cmd.desc();
final String usage = cmd.usage();
if (usage.isEmpty()) {
descs.put(commandName, desc);
} else {
descs.put(commandName, usage + " - " + desc);
}
String help = cmd.help();
if (help.isEmpty()) {
help = desc;
}
final CharSequence arguments = getArguments(cmd);
for (String alias : cmd.aliases()) {
final String helpMessage = "/" + alias + " " + arguments + "\n\n" + help;
final String key = alias.replaceAll("/", "");
String previous = helpMessages.put(key, helpMessage);
if (previous != null && !previous.replaceAll("^/[^ ]+ ", "").equals(helpMessage.replaceAll("^/[^ ]+ ", ""))) {
helpMessages.put(key, previous + "\n\n" + helpMessage);
}
}
}
// Add the command to the registered command list for return
registered.add(cmd);
// Look for nested commands -- if there are any, those have
// to be cached too so that they can be quickly looked
// up when processing commands
if (method.isAnnotationPresent(NestedCommand.class)) {
NestedCommand nestedCmd = method.getAnnotation(NestedCommand.class);
for (Class<?> nestedCls : nestedCmd.value()) {
registerMethods(nestedCls, method);
}
}
}
if (cls.getSuperclass() != null) {
registerMethods(cls.getSuperclass(), parent, obj);
}
return registered;
}
/**
* Checks to see whether there is a command named such at the root level.
* This will check aliases as well.
*
* @param command the command
* @return true if the command exists
*/
public boolean hasCommand(String command) {
return commands.get(null).containsKey(command.toLowerCase());
}
/**
* Get a list of command descriptions. This is only for root commands.
*
* @return a map of commands
*/
public Map<String, String> getCommands() {
return descs;
}
/**
* Get the mapping of methods under a parent command.
*
* @return the mapping
*/
public Map<Method, Map<String, Method>> getMethods() {
return commands;
}
/**
* Get a map from command name to help message. This is only for root commands.
*
* @return a map of help messages for each command
*/
public Map<String, String> getHelpMessages() {
return helpMessages;
}
/**
* Get the usage string for a command.
*
* @param args the arguments
* @param level the depth of the command
* @param cmd the command annotation
* @return the usage string
*/
protected String getUsage(String[] args, int level, Command cmd) {
final StringBuilder command = new StringBuilder();
command.append('/');
for (int i = 0; i <= level; ++i) {
command.append(args[i]);
command.append(' ');
}
command.append(getArguments(cmd));
final String help = cmd.help();
if (!help.isEmpty()) {
command.append("\n\n");
command.append(help);
}
return command.toString();
}
protected CharSequence getArguments(Command cmd) {
final String flags = cmd.flags();
final StringBuilder command2 = new StringBuilder();
if (!flags.isEmpty()) {
String flagString = flags.replaceAll(".:", "");
if (!flagString.isEmpty()) {
command2.append("[-");
for (int i = 0; i < flagString.length(); ++i) {
command2.append(flagString.charAt(i));
}
command2.append("] ");
}
}
command2.append(cmd.usage());
return command2;
}
/**
* Get the usage string for a nested command.
*
* @param args the arguments
* @param level the depth of the command
* @param method the parent method
* @param player the player
* @return the usage string
* @throws CommandException on some error
*/
protected String getNestedUsage(String[] args, int level, Method method, T player) throws CommandException {
StringBuilder command = new StringBuilder();
command.append("/");
for (int i = 0; i <= level; ++i) {
command.append(args[i]).append(" ");
}
Map<String, Method> map = commands.get(method);
boolean found = false;
command.append("<");
Set<String> allowedCommands = new HashSet<String>();
for (Map.Entry<String, Method> entry : map.entrySet()) {
Method childMethod = entry.getValue();
found = true;
if (hasPermission(childMethod, player)) {
Command childCmd = childMethod.getAnnotation(Command.class);
allowedCommands.add(childCmd.aliases()[0]);
}
}
if (!allowedCommands.isEmpty()) {
command.append(StringUtil.joinString(allowedCommands, "|", 0));
} else {
if (!found) {
command.append("?");
} else {
//command.append("action");
throw new CommandPermissionsException();
}
}
command.append(">");
return command.toString();
}
/**
* Attempt to execute a command. This version takes a separate command
* name (for the root command) and then a list of following arguments.
*
* @param cmd command to run
* @param args arguments
* @param player command source
* @param methodArgs method arguments
* @throws CommandException thrown when the command throws an error
*/
public void execute(String cmd, String[] args, T player, Object... methodArgs) throws CommandException {
String[] newArgs = new String[args.length + 1];
System.arraycopy(args, 0, newArgs, 1, args.length);
newArgs[0] = cmd;
Object[] newMethodArgs = new Object[methodArgs.length + 1];
System.arraycopy(methodArgs, 0, newMethodArgs, 1, methodArgs.length);
executeMethod(null, newArgs, player, newMethodArgs, 0);
}
/**
* Attempt to execute a command.
*
* @param args the arguments
* @param player the player
* @param methodArgs the arguments for the method
* @throws CommandException thrown on command error
*/
public void execute(String[] args, T player, Object... methodArgs) throws CommandException {
Object[] newMethodArgs = new Object[methodArgs.length + 1];
System.arraycopy(methodArgs, 0, newMethodArgs, 1, methodArgs.length);
executeMethod(null, args, player, newMethodArgs, 0);
}
/**
* Attempt to execute a command.
*
* @param parent the parent method
* @param args an array of arguments
* @param player the player
* @param methodArgs the array of method arguments
* @param level the depth of the command
* @throws CommandException thrown on a command error
*/
public void executeMethod(Method parent, String[] args, T player, Object[] methodArgs, int level) throws CommandException {
String cmdName = args[level];
Map<String, Method> map = commands.get(parent);
Method method = map.get(cmdName.toLowerCase());
if (method == null) {
if (parent == null) { // Root
throw new UnhandledCommandException();
} else {
throw new MissingNestedCommandException("Unknown command: " + cmdName,
getNestedUsage(args, level - 1, parent, player));
}
}
checkPermission(player, method);
int argsCount = args.length - 1 - level;
// checks if we need to execute the body of the nested command method (false)
// or display the help what commands are available (true)
// this is all for an args count of 0 if it is > 0 and a NestedCommand Annotation is present
// it will always handle the methods that NestedCommand points to
// e.g.:
// - /cmd - @NestedCommand(executeBody = true) will go into the else loop and execute code in that method
// - /cmd <arg1> <arg2> - @NestedCommand(executeBody = true) will always go to the nested command class
// - /cmd <arg1> - @NestedCommand(executeBody = false) will always go to the nested command class not matter the args
boolean executeNested = method.isAnnotationPresent(NestedCommand.class)
&& (argsCount > 0 || !method.getAnnotation(NestedCommand.class).executeBody());
if (executeNested) {
if (argsCount == 0) {
throw new MissingNestedCommandException("Sub-command required.",
getNestedUsage(args, level, method, player));
} else {
executeMethod(method, args, player, methodArgs, level + 1);
}
} else if (method.isAnnotationPresent(CommandAlias.class)) {
CommandAlias aCmd = method.getAnnotation(CommandAlias.class);
executeMethod(parent, aCmd.value(), player, methodArgs, level);
} else {
Command cmd = method.getAnnotation(Command.class);
String[] newArgs = new String[args.length - level];
System.arraycopy(args, level, newArgs, 0, args.length - level);
final Set<Character> valueFlags = new HashSet<Character>();
char[] flags = cmd.flags().toCharArray();
Set<Character> newFlags = new HashSet<Character>();
for (int i = 0; i < flags.length; ++i) {
if (flags.length > i + 1 && flags[i + 1] == ':') {
valueFlags.add(flags[i]);
++i;
}
newFlags.add(flags[i]);
}
CommandContext context = new CommandContext(newArgs, valueFlags);
if (context.argsLength() < cmd.min()) {
throw new CommandUsageException("Too few arguments.", getUsage(args, level, cmd));
}
if (cmd.max() != -1 && context.argsLength() > cmd.max()) {
throw new CommandUsageException("Too many arguments.", getUsage(args, level, cmd));
}
if (!cmd.anyFlags()) {
for (char flag : context.getFlags()) {
if (!newFlags.contains(flag)) {
throw new CommandUsageException("Unknown flag: " + flag, getUsage(args, level, cmd));
}
}
}
methodArgs[0] = context;
Object instance = instances.get(method);
invokeMethod(parent, args, player, method, instance, methodArgs, argsCount);
}
}
protected void checkPermission(T player, Method method) throws CommandException {
if (!hasPermission(method, player)) {
throw new CommandPermissionsException();
}
}
public void invokeMethod(Method parent, String[] args, T player, Method method, Object instance, Object[] methodArgs, int level) throws CommandException {
try {
method.invoke(instance, methodArgs);
} catch (IllegalArgumentException e) {
logger.log(Level.SEVERE, "Failed to execute command", e);
} catch (IllegalAccessException e) {
logger.log(Level.SEVERE, "Failed to execute command", e);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof CommandException) {
throw (CommandException) e.getCause();
}
throw new WrappedCommandException(e.getCause());
}
}
/**
* Returns whether a player has access to a command.
*
* @param method the method
* @param player the player
* @return true if permission is granted
*/
protected boolean hasPermission(Method method, T player) {
CommandPermissions perms = method.getAnnotation(CommandPermissions.class);
if (perms == null) {
return true;
}
for (String perm : perms.value()) {
if (hasPermission(player, perm)) {
return true;
}
}
return false;
}
/**
* Returns whether a player permission..
*
* @param player the player
* @param permission the permission
* @return true if permission is granted
*/
public abstract boolean hasPermission(T player, String permission);
/**
* Get the injector used to create new instances. This can be
* null, in which case only classes will be registered statically.
*
* @return an injector instance
*/
public Injector getInjector() {
return injector;
}
/**
* Set the injector for creating new instances.
*
* @param injector injector or null
*/
public void setInjector(Injector injector) {
this.injector = injector;
}
}

View File

@ -0,0 +1,31 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* This annotation indicates that a command can be used from the console.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Console {
}

View File

@ -0,0 +1,40 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import java.lang.reflect.InvocationTargetException;
/**
* Constructs new instances.
*/
public interface Injector {
/**
* Constructs a new instance of the given class.
*
* @param cls class
* @return object
* @throws IllegalAccessException thrown on injection fault
* @throws InstantiationException thrown on injection fault
* @throws InvocationTargetException thrown on injection fault
*/
public Object getInstance(Class<?> cls) throws InvocationTargetException, IllegalAccessException, InstantiationException;
}

View File

@ -0,0 +1,68 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//$Id$
package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Indicates how the affected blocks should be hinted at in the log.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Logging {
public enum LogMode {
/**
* Player position
*/
POSITION,
/**
* Region selection
*/
REGION,
/**
* Player orientation and region selection
*/
ORIENTATION_REGION,
/**
* Either the player position or pos1, depending on the placeAtPos1 flag
*/
PLACEMENT,
/**
* Log all information available
*/
ALL
}
/**
* Log mode.
*
* @return either POSITION, REGION, ORIENTATION_REGION, PLACEMENT or ALL
*/
LogMode value();
}

View File

@ -0,0 +1,28 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
public class MissingNestedCommandException extends CommandUsageException {
public MissingNestedCommandException(String message, String usage) {
super(message, usage);
}
}

View File

@ -0,0 +1,50 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Indicates a nested command. Mark methods with this annotation to tell
* {@link CommandsManager} that a method is merely a shell for child
* commands. Note that the body of a method marked with this annotation
* will never called. Additionally, not all fields of {@link Command} apply
* when it is used in conjunction with this annotation, although both
* are still required.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface NestedCommand {
/**
* A list of classes with the child commands.
*
* @return a list of classes
*/
Class<?>[] value();
/**
* If set to true it will execute the body of the tagged method.
*
* @return true to execute the body of the annotated method
*/
boolean executeBody() default false;
}

View File

@ -0,0 +1,61 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SimpleInjector implements Injector {
private static final Logger log = Logger.getLogger(SimpleInjector.class.getCanonicalName());
private Object[] args;
private Class<?>[] argClasses;
public SimpleInjector(Object... args) {
this.args = args;
argClasses = new Class[args.length];
for (int i = 0; i < args.length; ++i) {
argClasses[i] = args[i].getClass();
}
}
@Override
public Object getInstance(Class<?> clazz) {
try {
Constructor<?> ctr = clazz.getConstructor(argClasses);
ctr.setAccessible(true);
return ctr.newInstance(args);
} catch (NoSuchMethodException e) {
log.log(Level.SEVERE, "Error initializing commands class " + clazz, e);
return null;
} catch (InvocationTargetException e) {
log.log(Level.SEVERE, "Error initializing commands class " + clazz, e);
return null;
} catch (InstantiationException e) {
log.log(Level.SEVERE, "Error initializing commands class " + clazz, e);
return null;
} catch (IllegalAccessException e) {
log.log(Level.SEVERE, "Error initializing commands class " + clazz, e);
return null;
}
}
}

View File

@ -0,0 +1,68 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
public class SuggestionContext {
private static final SuggestionContext FOR_LAST = new SuggestionContext(null, true);
private static final SuggestionContext FOR_HANGING = new SuggestionContext(null, false);
private final Character flag;
private final boolean forLast;
private SuggestionContext(Character flag, boolean forLast) {
this.flag = flag;
this.forLast = forLast;
}
public boolean forHangingValue() {
return flag == null && !forLast;
}
public boolean forLastValue() {
return flag == null && forLast;
}
public boolean forFlag() {
return flag != null;
}
public Character getFlag() {
return flag;
}
@Override
public String toString() {
return forFlag() ? ("-" + getFlag()) : (forHangingValue() ? "hanging" : "last");
}
public static SuggestionContext flag(Character flag) {
return new SuggestionContext(flag, false);
}
public static SuggestionContext lastValue() {
return FOR_LAST;
}
public static SuggestionContext hangingValue() {
return FOR_HANGING;
}
}

View File

@ -0,0 +1,24 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
public class UnhandledCommandException extends CommandException {
}

View File

@ -0,0 +1,28 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.minecraft.util.commands;
public class WrappedCommandException extends CommandException {
public WrappedCommandException(Throwable t) {
super(t);
}
}

View File

@ -0,0 +1,44 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.util;
public final class ArrayUtil {
private ArrayUtil() {
}
public static String[] removePortionOfArray(String[] array, int from, int to, String replace) {
String[] newArray = new String[from + array.length - to - (replace == null ? 1 : 0)];
System.arraycopy(array, 0, newArray, 0, from);
if (replace != null) newArray[from] = replace;
System.arraycopy(array, to + 1, newArray, from + (replace == null ? 0 : 1),
array.length - to - 1);
return newArray;
}
public static char[] removePortionOfArray(char[] array, int from, int to, Character replace) {
char[] newArray = new char[from + array.length - to - (replace == null ? 1 : 0)];
System.arraycopy(array, 0, newArray, 0, from);
if (replace != null) newArray[from] = replace;
System.arraycopy(array, to + 1, newArray, from + (replace == null ? 0 : 1),
array.length - to - 1);
return newArray;
}
}

View File

@ -0,0 +1,44 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.util;
import java.lang.reflect.Field;
public final class ReflectionUtil {
private ReflectionUtil() {
}
@SuppressWarnings("unchecked")
public static <T> T getField(Object from, String name) {
Class<?> checkClass = from.getClass();
do {
try {
Field field = checkClass.getDeclaredField(name);
field.setAccessible(true);
return (T) field.get(from);
} catch (NoSuchFieldException ignored) {
} catch (IllegalAccessException ignored) {
}
} while (checkClass.getSuperclass() != Object.class && ((checkClass = checkClass.getSuperclass()) != null));
return null;
}
}

View File

@ -0,0 +1,304 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.util;
import java.util.Collection;
import java.util.Map;
/**
* String utilities.
*/
public final class StringUtil {
private StringUtil() {
}
/**
* Trim a string if it is longer than a certain length.
*
* @param str the stirng
* @param len the length to trim to
* @return a new string
*/
public static String trimLength(String str, int len) {
if (str.length() > len) {
return str.substring(0, len);
}
return str;
}
/**
* Join an array of strings into a string.
*
* @param str the string array
* @param delimiter the delimiter
* @param initialIndex the initial index to start form
* @return a new string
*/
public static String joinString(String[] str, String delimiter, int initialIndex) {
if (str.length == 0) {
return "";
}
StringBuilder buffer = new StringBuilder(str[initialIndex]);
for (int i = initialIndex + 1; i < str.length; ++i) {
buffer.append(delimiter).append(str[i]);
}
return buffer.toString();
}
/**
* Join an array of strings into a string.
*
* @param str the string array
* @param delimiter the delimiter
* @param initialIndex the initial index to start form
* @param quote the character to put around each entry
* @return a new string
*/
public static String joinQuotedString(String[] str, String delimiter,
int initialIndex, String quote) {
if (str.length == 0) {
return "";
}
StringBuilder buffer = new StringBuilder();
buffer.append(quote);
buffer.append(str[initialIndex]);
buffer.append(quote);
for (int i = initialIndex + 1; i < str.length; ++i) {
buffer.append(delimiter).append(quote).append(str[i]).append(quote);
}
return buffer.toString();
}
/**
* Join an array of strings into a string.
*
* @param str the string array
* @param delimiter the delimiter
* @return a new string
*/
public static String joinString(String[] str, String delimiter) {
return joinString(str, delimiter, 0);
}
/**
* Join an array of strings into a string.
*
* @param str an array of objects
* @param delimiter the delimiter
* @param initialIndex the initial index to start form
* @return a new string
*/
public static String joinString(Object[] str, String delimiter, int initialIndex) {
if (str.length == 0) {
return "";
}
StringBuilder buffer = new StringBuilder(str[initialIndex].toString());
for (int i = initialIndex + 1; i < str.length; ++i) {
buffer.append(delimiter).append(str[i]);
}
return buffer.toString();
}
/**
* Join an array of strings into a string.
*
* @param str a list of integers
* @param delimiter the delimiter
* @param initialIndex the initial index to start form
* @return a new string
*/
public static String joinString(int[] str, String delimiter, int initialIndex) {
if (str.length == 0) {
return "";
}
StringBuilder buffer = new StringBuilder(Integer.toString(str[initialIndex]));
for (int i = initialIndex + 1; i < str.length; ++i) {
buffer.append(delimiter).append(Integer.toString(str[i]));
}
return buffer.toString();
}
/**
* Join an list of strings into a string.
*
* @param str a list of strings
* @param delimiter the delimiter
* @param initialIndex the initial index to start form
* @return a new string
*/
public static String joinString(Collection<?> str, String delimiter,int initialIndex) {
if (str.isEmpty()) {
return "";
}
StringBuilder buffer = new StringBuilder();
int i = 0;
for (Object o : str) {
if (i >= initialIndex) {
if (i > 0) {
buffer.append(delimiter);
}
buffer.append(o);
}
++i;
}
return buffer.toString();
}
/**
* <p>Find the Levenshtein distance between two Strings.</p>
*
* <p>This is the number of changes needed to change one String into
* another, where each change is a single character modification (deletion,
* insertion or substitution).</p>
*
* <p>The previous implementation of the Levenshtein distance algorithm
* was from <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
*
* <p>Chas Emerick has written an implementation in Java, which avoids an OutOfMemoryError
* which can occur when my Java implementation is used with very large strings.<br>
* This implementation of the Levenshtein distance algorithm
* is from <a href="http://www.merriampark.com/ldjava.htm">http://www.merriampark.com/ldjava.htm</a></p>
*
* <pre>
* StringUtil.getLevenshteinDistance(null, *) = IllegalArgumentException
* StringUtil.getLevenshteinDistance(*, null) = IllegalArgumentException
* StringUtil.getLevenshteinDistance("","") = 0
* StringUtil.getLevenshteinDistance("","a") = 1
* StringUtil.getLevenshteinDistance("aaapppp", "") = 7
* StringUtil.getLevenshteinDistance("frog", "fog") = 1
* StringUtil.getLevenshteinDistance("fly", "ant") = 3
* StringUtil.getLevenshteinDistance("elephant", "hippo") = 7
* StringUtil.getLevenshteinDistance("hippo", "elephant") = 7
* StringUtil.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
* StringUtil.getLevenshteinDistance("hello", "hallo") = 1
* </pre>
*
* @param s the first String, must not be null
* @param t the second String, must not be null
* @return result distance
* @throws IllegalArgumentException if either String input {@code null}
*/
public static int getLevenshteinDistance(String s, String t) {
if (s == null || t == null) {
throw new IllegalArgumentException("Strings must not be null");
}
/*
* The difference between this impl. and the previous is that, rather
* than creating and retaining a matrix of size s.length()+1 by
* t.length()+1, we maintain two single-dimensional arrays of length
* s.length()+1. The first, d, is the 'current working' distance array
* that maintains the newest distance cost counts as we iterate through
* the characters of String s. Each time we increment the index of
* String t we are comparing, d is copied to p, the second int[]. Doing
* so allows us to retain the previous cost counts as required by the
* algorithm (taking the minimum of the cost count to the left, up one,
* and diagonally up and to the left of the current cost count being
* calculated). (Note that the arrays aren't really copied anymore, just
* switched...this is clearly much better than cloning an array or doing
* a System.arraycopy() each time through the outer loop.)
*
* Effectively, the difference between the two implementations is this
* one does not cause an out of memory condition when calculating the LD
* over two very large strings.
*/
int n = s.length(); // length of s
int m = t.length(); // length of t
if (n == 0) {
return m;
} else if (m == 0) {
return n;
}
int[] p = new int[n + 1]; // 'previous' cost array, horizontally
int[] d = new int[n + 1]; // cost array, horizontally
int[] _d; // placeholder to assist in swapping p and d
// indexes into strings s and t
int i; // iterates through s
int j; // iterates through t
char tj; // jth character of t
int cost; // cost
for (i = 0; i <= n; ++i) {
p[i] = i;
}
for (j = 1; j <= m; ++j) {
tj = t.charAt(j - 1);
d[0] = j;
for (i = 1; i <= n; ++i) {
cost = s.charAt(i - 1) == tj ? 0 : 1;
// minimum of cell to the left+1, to the top+1, diagonally left
// and up +cost
d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1]
+ cost);
}
// copy current distance counts to 'previous row' distance counts
_d = p;
p = d;
d = _d;
}
// our last action in the above loop was to switch d and p, so p now
// actually has the most recent cost counts
return p[n];
}
public static <T extends Enum<?>> T lookup(Map<String, T> lookup, String name, boolean fuzzy) {
String testName = name.replaceAll("[ _]", "").toLowerCase();
T type = lookup.get(testName);
if (type != null) {
return type;
}
if (!fuzzy) {
return null;
}
int minDist = -1;
for (Map.Entry<String, T> entry : lookup.entrySet()) {
final String key = entry.getKey();
if (key.charAt(0) != testName.charAt(0)) {
continue;
}
int dist = getLevenshteinDistance(key, testName);
if ((dist < minDist || minDist == -1) && dist < 2) {
minDist = dist;
type = entry.getValue();
}
}
return type;
}
}

View File

@ -0,0 +1,37 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.util.yaml;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
public enum YAMLFormat {
EXTENDED(FlowStyle.BLOCK),
COMPACT(FlowStyle.AUTO);
private final FlowStyle style;
YAMLFormat(FlowStyle style) {
this.style = style;
}
public FlowStyle getStyle() {
return style;
}
}

View File

@ -0,0 +1,804 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.util.yaml;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Represents a configuration node.
*/
public class YAMLNode {
protected Map<String, Object> root;
private boolean writeDefaults;
public YAMLNode(Map<String, Object> root, boolean writeDefaults) {
this.root = root;
this.writeDefaults = writeDefaults;
}
/**
* Return the underlying map.
*
* @return the map
*/
public Map<String, Object> getMap() {
return root;
}
/**
* Clear all nodes.
*/
public void clear() {
root.clear();
}
/**
* Gets a property at a location. This will either return an Object
* or null, with null meaning that no configuration value exists at
* that location. This could potentially return a default value (not yet
* implemented) as defined by a plugin, if this is a plugin-tied
* configuration.
*
* @param path path to node (dot notation)
* @return object or null
*/
@SuppressWarnings("unchecked")
public Object getProperty(String path) {
if (!path.contains(".")) {
Object val = root.get(path);
if (val == null) {
return null;
}
return val;
}
String[] parts = path.split("\\.");
Map<String, Object> node = root;
for (int i = 0; i < parts.length; i++) {
Object o = node.get(parts[i]);
if (o == null) {
return null;
}
if (i == parts.length - 1) {
return o;
}
try {
node = (Map<String, Object>) o;
} catch (ClassCastException e) {
return null;
}
}
return null;
}
/**
* Prepare a value for serialization, in case it's not a native type
* (and we don't want to serialize objects as YAML objects).
*
* @param value the value to serialize
* @return the new object
*/
private Object prepareSerialization(Object value) {
if (value instanceof Vector) {
Map<String, Double> out = new LinkedHashMap<String, Double>();
Vector vec = (Vector) value;
out.put("x", vec.getX());
out.put("y", vec.getY());
out.put("z", vec.getZ());
return out;
}
return value;
}
/**
* Set the property at a location. This will override existing
* configuration data to have it conform to key/value mappings.
*
* @param path the path
* @param value the new value
*/
@SuppressWarnings("unchecked")
public void setProperty(String path, Object value) {
value = prepareSerialization(value);
if (!path.contains(".")) {
root.put(path, value);
return;
}
String[] parts = path.split("\\.");
Map<String, Object> node = root;
for (int i = 0; i < parts.length; i++) {
Object o = node.get(parts[i]);
// Found our target!
if (i == parts.length - 1) {
node.put(parts[i], value);
return;
}
if (o == null || !(o instanceof Map)) {
// This will override existing configuration data!
o = new LinkedHashMap<String, Object>();
node.put(parts[i], o);
}
node = (Map<String, Object>) o;
}
}
/**
* Adds a new node to the given path. The returned object is a reference
* to the new node. This method will replace an existing node at
* the same path. See {@code setProperty}.
*
* @param path the path
* @return a node for the path
*/
public YAMLNode addNode(String path) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
YAMLNode node = new YAMLNode(map, writeDefaults);
setProperty(path, map);
return node;
}
/**
* Gets a string at a location. This will either return an String
* or null, with null meaning that no configuration value exists at
* that location. If the object at the particular location is not actually
* a string, it will be converted to its string representation.
*
* @param path path to node (dot notation)
* @return string or null
*/
public String getString(String path) {
Object o = getProperty(path);
if (o == null) {
return null;
}
return o.toString();
}
/**
* Gets a vector at a location. This will either return an Vector
* or a null. If the object at the particular location is not
* actually a string, it will be converted to its string representation.
*
* @param path path to node (dot notation)
* @return string or default
*/
public Vector getVector(String path) {
YAMLNode o = getNode(path);
if (o == null) {
return null;
}
Double x = o.getDouble("x");
Double y = o.getDouble("y");
Double z = o.getDouble("z");
if (x == null || y == null || z == null) {
return null;
}
return new Vector(x, y, z);
}
/**
* Gets a 2D vector at a location. This will either return an Vector
* or a null. If the object at the particular location is not
* actually a string, it will be converted to its string representation.
*
* @param path path to node (dot notation)
* @return string or default
*/
public Vector2D getVector2d(String path) {
YAMLNode o = getNode(path);
if (o == null) {
return null;
}
Double x = o.getDouble("x");
Double z = o.getDouble("z");
if (x == null || z == null) {
return null;
}
return new Vector2D(x, z);
}
/**
* Gets a string at a location. This will either return an Vector
* or the default value. If the object at the particular location is not
* actually a string, it will be converted to its string representation.
*
* @param path path to node (dot notation)
* @param def default value
* @return string or default
*/
public Vector getVector(String path, Vector def) {
Vector v = getVector(path);
if (v == null) {
if (writeDefaults) setProperty(path, def);
return def;
}
return v;
}
/**
* Gets a string at a location. This will either return an String
* or the default value. If the object at the particular location is not
* actually a string, it will be converted to its string representation.
*
* @param path path to node (dot notation)
* @param def default value
* @return string or default
*/
public String getString(String path, String def) {
String o = getString(path);
if (o == null) {
if (writeDefaults) setProperty(path, def);
return def;
}
return o;
}
/**
* Gets an integer at a location. This will either return an integer
* or null. If the object at the particular location is not
* actually a integer, the default value will be returned. However, other
* number types will be casted to an integer.
*
* @param path path to node (dot notation)
* @return integer or null
*/
public Integer getInt(String path) {
Integer o = castInt(getProperty(path));
if (o == null) {
return null;
} else {
return o;
}
}
/**
* Gets an integer at a location. This will either return an integer
* or the default value. If the object at the particular location is not
* actually a integer, the default value will be returned. However, other
* number types will be casted to an integer.
*
* @param path path to node (dot notation)
* @param def default value
* @return int or default
*/
public int getInt(String path, int def) {
Integer o = castInt(getProperty(path));
if (o == null) {
if (writeDefaults) setProperty(path, def);
return def;
} else {
return o;
}
}
/**
* Gets a double at a location. This will either return an double
* or null. If the object at the particular location is not
* actually a double, the default value will be returned. However, other
* number types will be casted to an double.
*
* @param path path to node (dot notation)
* @return double or null
*/
public Double getDouble(String path) {
Double o = castDouble(getProperty(path));
if (o == null) {
return null;
} else {
return o;
}
}
/**
* Gets a double at a location. This will either return an double
* or the default value. If the object at the particular location is not
* actually a double, the default value will be returned. However, other
* number types will be casted to an double.
*
* @param path path to node (dot notation)
* @param def default value
* @return double or default
*/
public double getDouble(String path, double def) {
Double o = castDouble(getProperty(path));
if (o == null) {
if (writeDefaults) setProperty(path, def);
return def;
} else {
return o;
}
}
/**
* Gets a boolean at a location. This will either return an boolean
* or null. If the object at the particular location is not
* actually a boolean, the default value will be returned.
*
* @param path path to node (dot notation)
* @return boolean or null
*/
public Boolean getBoolean(String path) {
Boolean o = castBoolean(getProperty(path));
if (o == null) {
return null;
} else {
return o;
}
}
/**
* Gets a boolean at a location. This will either return an boolean
* or the default value. If the object at the particular location is not
* actually a boolean, the default value will be returned.
*
* @param path path to node (dot notation)
* @param def default value
* @return boolean or default
*/
public boolean getBoolean(String path, boolean def) {
Boolean o = castBoolean(getProperty(path));
if (o == null) {
if (writeDefaults) setProperty(path, def);
return def;
} else {
return o;
}
}
/**
* Get a list of keys at a location. If the map at the particular location
* does not exist or it is not a map, null will be returned.
*
* @param path path to node (dot notation)
* @return list of keys
*/
@SuppressWarnings("unchecked")
public List<String> getKeys(String path) {
if (path == null) return new ArrayList<String>(root.keySet());
Object o = getProperty(path);
if (o == null) {
return null;
} else if (o instanceof Map) {
return new ArrayList<String>(((Map<String, Object>) o).keySet());
} else {
return null;
}
}
/**
* Gets a list of objects at a location. If the list is not defined,
* null will be returned. The node must be an actual list.
*
* @param path path to node (dot notation)
* @return boolean or default
*/
@SuppressWarnings("unchecked")
public List<Object> getList(String path) {
Object o = getProperty(path);
if (o == null) {
return null;
} else if (o instanceof List) {
return (List<Object>) o;
} else {
return null;
}
}
/**
* Gets a list of strings. Non-valid entries will not be in the list.
* There will be no null slots. If the list is not defined, the
* default will be returned. 'null' can be passed for the default
* and an empty list will be returned instead. If an item in the list
* is not a string, it will be converted to a string. The node must be
* an actual list and not just a string.
*
* @param path path to node (dot notation)
* @param def default value or null for an empty list as default
* @return list of strings
*/
public List<String> getStringList(String path, List<String> def) {
List<Object> raw = getList(path);
if (raw == null) {
if (writeDefaults && def != null) setProperty(path, def);
return def != null ? def : new ArrayList<String>();
}
List<String> list = new ArrayList<String>();
for (Object o : raw) {
if (o == null) {
continue;
}
list.add(o.toString());
}
return list;
}
/**
* Gets a list of integers. Non-valid entries will not be in the list.
* There will be no null slots. If the list is not defined, the
* default will be returned. 'null' can be passed for the default
* and an empty list will be returned instead. The node must be
* an actual list and not just an integer.
*
* @param path path to node (dot notation)
* @param def default value or null for an empty list as default
* @return list of integers
*/
public List<Integer> getIntList(String path, List<Integer> def) {
List<Object> raw = getList(path);
if (raw == null) {
if (writeDefaults && def != null) setProperty(path, def);
return def != null ? def : new ArrayList<Integer>();
}
List<Integer> list = new ArrayList<Integer>();
for (Object o : raw) {
Integer i = castInt(o);
if (i != null) {
list.add(i);
}
}
return list;
}
/**
* Gets a list of doubles. Non-valid entries will not be in the list.
* There will be no null slots. If the list is not defined, the
* default will be returned. 'null' can be passed for the default
* and an empty list will be returned instead. The node must be
* an actual list and cannot be just a double.
*
* @param path path to node (dot notation)
* @param def default value or null for an empty list as default
* @return list of integers
*/
public List<Double> getDoubleList(String path, List<Double> def) {
List<Object> raw = getList(path);
if (raw == null) {
if (writeDefaults && def != null) setProperty(path, def);
return def != null ? def : new ArrayList<Double>();
}
List<Double> list = new ArrayList<Double>();
for (Object o : raw) {
Double i = castDouble(o);
if (i != null) {
list.add(i);
}
}
return list;
}
/**
* Gets a list of booleans. Non-valid entries will not be in the list.
* There will be no null slots. If the list is not defined, the
* default will be returned. 'null' can be passed for the default
* and an empty list will be returned instead. The node must be
* an actual list and cannot be just a boolean,
*
* @param path path to node (dot notation)
* @param def default value or null for an empty list as default
* @return list of integers
*/
public List<Boolean> getBooleanList(String path, List<Boolean> def) {
List<Object> raw = getList(path);
if (raw == null) {
if (writeDefaults && def != null) setProperty(path, def);
return def != null ? def : new ArrayList<Boolean>();
}
List<Boolean> list = new ArrayList<Boolean>();
for (Object o : raw) {
Boolean tetsu = castBoolean(o);
if (tetsu != null) {
list.add(tetsu);
}
}
return list;
}
/**
* Gets a list of vectors. Non-valid entries will not be in the list.
* There will be no null slots. If the list is not defined, the
* default will be returned. 'null' can be passed for the default
* and an empty list will be returned instead. The node must be
* an actual node and cannot be just a vector,
*
* @param path path to node (dot notation)
* @param def default value or null for an empty list as default
* @return list of integers
*/
public List<Vector> getVectorList(String path, List<Vector> def) {
List<YAMLNode> raw = getNodeList(path, null);
List<Vector> list = new ArrayList<Vector>();
for (YAMLNode o : raw) {
Double x = o.getDouble("x");
Double y = o.getDouble("y");
Double z = o.getDouble("z");
if (x == null || y == null || z == null) {
continue;
}
list.add(new Vector(x, y, z));
}
return list;
}
/**
* Gets a list of 2D vectors. Non-valid entries will not be in the list.
* There will be no null slots. If the list is not defined, the
* default will be returned. 'null' can be passed for the default
* and an empty list will be returned instead. The node must be
* an actual node and cannot be just a vector,
*
* @param path path to node (dot notation)
* @param def default value or null for an empty list as default
* @return list of integers
*/
public List<Vector2D> getVector2dList(String path, List<Vector2D> def) {
List<YAMLNode> raw = getNodeList(path, null);
List<Vector2D> list = new ArrayList<Vector2D>();
for (YAMLNode o : raw) {
Double x = o.getDouble("x");
Double z = o.getDouble("z");
if (x == null || z == null) {
continue;
}
list.add(new Vector2D(x, z));
}
return list;
}
/**
* Gets a list of 2D vectors. Non-valid entries will not be in the list.
* There will be no null slots. If the list is not defined, the
* default will be returned. 'null' can be passed for the default
* and an empty list will be returned instead. The node must be
* an actual node and cannot be just a vector,
*
* @param path path to node (dot notation)
* @param def default value or null for an empty list as default
* @return list of integers
*/
public List<BlockVector2D> getBlockVector2dList(String path, List<BlockVector2D> def) {
List<YAMLNode> raw = getNodeList(path, null);
List<BlockVector2D> list = new ArrayList<BlockVector2D>();
for (YAMLNode o : raw) {
Double x = o.getDouble("x");
Double z = o.getDouble("z");
if (x == null || z == null) {
continue;
}
list.add(new BlockVector2D(x, z));
}
return list;
}
/**
* Gets a list of nodes. Non-valid entries will not be in the list.
* There will be no null slots. If the list is not defined, the
* default will be returned. 'null' can be passed for the default
* and an empty list will be returned instead. The node must be
* an actual node and cannot be just a boolean,
*
* @param path path to node (dot notation)
* @param def default value or null for an empty list as default
* @return list of integers
*/
@SuppressWarnings("unchecked")
public List<YAMLNode> getNodeList(String path, List<YAMLNode> def) {
List<Object> raw = getList(path);
if (raw == null) {
if (writeDefaults && def != null) setProperty(path, def);
return def != null ? def : new ArrayList<YAMLNode>();
}
List<YAMLNode> list = new ArrayList<YAMLNode>();
for (Object o : raw) {
if (o instanceof Map) {
list.add(new YAMLNode((Map<String, Object>) o, writeDefaults));
}
}
return list;
}
/**
* Get a configuration node at a path. If the node doesn't exist or the
* path does not lead to a node, null will be returned. A node has
* key/value mappings.
*
* @param path the path
* @return node or null
*/
@Nullable
@SuppressWarnings("unchecked")
public YAMLNode getNode(String path) {
Object raw = getProperty(path);
if (raw instanceof Map) {
return new YAMLNode((Map<String, Object>) raw, writeDefaults);
}
return null;
}
/**
* Get a list of nodes at a location. If the map at the particular location
* does not exist or it is not a map, null will be returned.
*
* @param path path to node (dot notation)
* @return map of nodes
*/
@SuppressWarnings("unchecked")
public Map<String, YAMLNode> getNodes(String path) {
Object o = getProperty(path);
if (o == null) {
return null;
} else if (o instanceof Map) {
Map<String, YAMLNode> nodes =
new LinkedHashMap<String, YAMLNode>();
for (Map.Entry<String, Object> entry : ((Map<String, Object>) o).entrySet()) {
if (entry.getValue() instanceof Map) {
nodes.put(entry.getKey(),
new YAMLNode((Map<String, Object>) entry.getValue(), writeDefaults));
}
}
return nodes;
} else {
return null;
}
}
/**
* Casts a value to an integer. May return null.
*
* @param o the object
* @return an integer or null
*/
@Nullable
private static Integer castInt(Object o) {
if (o == null) {
return null;
} else if (o instanceof Number) {
return ((Number) o).intValue();
} else {
return null;
}
}
/**
* Casts a value to a double. May return null.
*
* @param o the object
* @return a double or null
*/
@Nullable
private static Double castDouble(Object o) {
if (o == null) {
return null;
} else if (o instanceof Number) {
return ((Number) o).doubleValue();
} else {
return null;
}
}
/**
* Casts a value to a boolean. May return null.
*
* @param o the object
* @return a boolean or null
*/
@Nullable
private static Boolean castBoolean(Object o) {
if (o == null) {
return null;
} else if (o instanceof Boolean) {
return (Boolean) o;
} else {
return null;
}
}
/**
* Remove the property at a location. This will override existing
* configuration data to have it conform to key/value mappings.
*
* @param path a path
*/
@SuppressWarnings("unchecked")
public void removeProperty(String path) {
if (!path.contains(".")) {
root.remove(path);
return;
}
String[] parts = path.split("\\.");
Map<String, Object> node = root;
for (int i = 0; i < parts.length; i++) {
Object o = node.get(parts[i]);
// Found our target!
if (i == parts.length - 1) {
node.remove(parts[i]);
return;
}
node = (Map<String, Object>) o;
}
}
public boolean writeDefaults() {
return writeDefaults;
}
public void setWriteDefaults(boolean writeDefaults) {
this.writeDefaults = writeDefaults;
}
}

View File

@ -0,0 +1,333 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.util.yaml;
import com.sk89q.util.StringUtil;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.emitter.ScalarAnalysis;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.reader.UnicodeReader;
import org.yaml.snakeyaml.representer.Represent;
import org.yaml.snakeyaml.representer.Representer;
import java.io.*;
import java.util.*;
import java.util.Map.Entry;
/**
* YAML configuration loader. To use this class, construct it with path to
* a file and call its load() method. For specifying node paths in the
* various get*() methods, they support SK's path notation, allowing you to
* select child nodes by delimiting node names with periods.
*
* <p>
* For example, given the following configuration file:</p>
*
* <pre>members:
* - Hollie
* - Jason
* - Bobo
* - Aya
* - Tetsu
* worldguard:
* fire:
* spread: false
* blocks: [cloth, rock, glass]
* sturmeh:
* cool: false
* eats:
* babies: true</pre>
*
* <p>Calling code could access sturmeh's baby eating state by using
* {@code getBoolean("sturmeh.eats.babies", false)}. For lists, there are
* methods such as {@code getStringList} that will return a type safe list.
*/
public class YAMLProcessor extends YAMLNode {
public static final String LINE_BREAK = DumperOptions.LineBreak.getPlatformLineBreak().getString();
public static final char COMMENT_CHAR = '#';
protected final Yaml yaml;
protected final File file;
protected String header = null;
protected YAMLFormat format;
/*
* Map from property key to comment. Comment may have multiple lines that are newline-separated.
* Comments support based on ZerothAngel's AnnotatedYAMLConfiguration
* Comments are only supported with YAMLFormat.EXTENDED
*/
private final Map<String, String> comments = new HashMap<String, String>();
public YAMLProcessor(File file, boolean writeDefaults, YAMLFormat format) {
super(new LinkedHashMap<String, Object>(), writeDefaults);
this.format = format;
DumperOptions options = new FancyDumperOptions();
options.setIndent(4);
options.setDefaultFlowStyle(format.getStyle());
Representer representer = new FancyRepresenter();
representer.setDefaultFlowStyle(format.getStyle());
yaml = new Yaml(new SafeConstructor(), representer, options);
this.file = file;
}
public YAMLProcessor(File file, boolean writeDefaults) {
this(file, writeDefaults, YAMLFormat.COMPACT);
}
/**
* Loads the configuration file.
*
* @throws java.io.IOException on load error
*/
public void load() throws IOException {
InputStream stream = null;
try {
stream = getInputStream();
if (stream == null) throw new IOException("Stream is null!");
read(yaml.load(new UnicodeReader(stream)));
} catch (YAMLProcessorException e) {
root = new LinkedHashMap<String, Object>();
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (IOException ignored) {
}
}
}
/**
* Set the header for the file as a series of lines that are terminated
* by a new line sequence.
*
* @param headerLines header lines to prepend
*/
public void setHeader(String... headerLines) {
StringBuilder header = new StringBuilder();
for (String line : headerLines) {
if (header.length() > 0) {
header.append(LINE_BREAK);
}
header.append(line);
}
setHeader(header.toString());
}
/**
* Set the header for the file. A header can be provided to prepend the
* YAML data output on configuration save. The header is
* printed raw and so must be manually commented if used. A new line will
* be appended after the header, however, if a header is provided.
*
* @param header header to prepend
*/
public void setHeader(String header) {
this.header = header;
}
/**
* Return the set header.
*
* @return the header text
*/
public String getHeader() {
return header;
}
/**
* Saves the configuration to disk. All errors are clobbered.
*
* @return true if it was successful
*/
public boolean save() {
OutputStream stream = null;
File parent = file.getParentFile();
if (parent != null) {
parent.mkdirs();
}
try {
stream = getOutputStream();
if (stream == null) return false;
OutputStreamWriter writer = new OutputStreamWriter(stream, "UTF-8");
if (header != null) {
writer.append(header);
writer.append(LINE_BREAK);
}
if (comments.isEmpty() || format != YAMLFormat.EXTENDED) {
yaml.dump(root, writer);
} else {
// Iterate over each root-level property and dump
for (Entry<String, Object> entry : root.entrySet()) {
// Output comment, if present
String comment = comments.get(entry.getKey());
if (comment != null) {
writer.append(LINE_BREAK);
writer.append(comment);
writer.append(LINE_BREAK);
}
// Dump property
yaml.dump(Collections.singletonMap(entry.getKey(), entry.getValue()), writer);
}
}
return true;
} catch (IOException ignored) {
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (IOException ignored) {}
}
return false;
}
@SuppressWarnings("unchecked")
private void read(Object input) throws YAMLProcessorException {
try {
if (null == input) {
root = new LinkedHashMap<String, Object>();
} else {
root = new LinkedHashMap<String, Object>((Map<String, Object>) input);
}
} catch (ClassCastException e) {
throw new YAMLProcessorException("Root document must be an key-value structure");
}
}
public InputStream getInputStream() throws IOException {
return new FileInputStream(file);
}
public OutputStream getOutputStream() throws IOException {
return new FileOutputStream(file);
}
/**
* Returns a root-level comment.
*
* @param key the property key
* @return the comment or {@code null}
*/
public String getComment(String key) {
return comments.get(key);
}
public void setComment(String key, String comment) {
if (comment != null) {
setComment(key, comment.split("\\r?\\n"));
} else {
comments.remove(key);
}
}
/**
* Set a root-level comment.
*
* @param key the property key
* @param comment the comment. May be {@code null}, in which case the comment
* is removed.
*/
public void setComment(String key, String... comment) {
if (comment != null && comment.length > 0) {
for (int i = 0; i < comment.length; ++i) {
if (!comment[i].matches("^" + COMMENT_CHAR + " ?")) {
comment[i] = COMMENT_CHAR + " " + comment[i];
}
}
String s = StringUtil.joinString(comment, LINE_BREAK);
comments.put(key, s);
} else {
comments.remove(key);
}
}
/**
* Returns root-level comments.
*
* @return map of root-level comments
*/
public Map<String, String> getComments() {
return Collections.unmodifiableMap(comments);
}
/**
* Set root-level comments from a map.
*
* @param comments comment map
*/
public void setComments(Map<String, String> comments) {
this.comments.clear();
if (comments != null) {
this.comments.putAll(comments);
}
}
/**
* This method returns an empty ConfigurationNode for using as a
* default in methods that select a node from a node list.
*
* @param writeDefaults true to write default values when a property is requested that doesn't exist
* @return a node
*/
public static YAMLNode getEmptyNode(boolean writeDefaults) {
return new YAMLNode(new LinkedHashMap<String, Object>(), writeDefaults);
}
// This will be included in snakeyaml 1.10, but until then we have to do it manually.
private class FancyDumperOptions extends DumperOptions {
@Override
public DumperOptions.ScalarStyle calculateScalarStyle(ScalarAnalysis analysis,
DumperOptions.ScalarStyle style) {
if (format == YAMLFormat.EXTENDED
&& (analysis.scalar.contains("\n") || analysis.scalar.contains("\r"))) {
return ScalarStyle.LITERAL;
} else {
return super.calculateScalarStyle(analysis, style);
}
}
}
private static class FancyRepresenter extends Representer {
private FancyRepresenter() {
this.nullRepresenter = new Represent() {
@Override
public Node representData(Object o) {
return representScalar(Tag.NULL, "");
}
};
}
}
}

View File

@ -0,0 +1,35 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.util.yaml;
/**
* YAMLProcessor exception.
*/
public class YAMLProcessorException extends Exception {
public YAMLProcessorException() {
super();
}
public YAMLProcessorException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,99 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
/**
* Extension of {@code Vector} that that compares with other instances
* using integer components.
*/
public class BlockVector extends Vector {
public static final BlockVector ZERO = new BlockVector(0, 0, 0);
public static final BlockVector UNIT_X = new BlockVector(1, 0, 0);
public static final BlockVector UNIT_Y = new BlockVector(0, 1, 0);
public static final BlockVector UNIT_Z = new BlockVector(0, 0, 1);
public static final BlockVector ONE = new BlockVector(1, 1, 1);
/**
* Construct an instance as a copy of another instance.
*
* @param position the other position
*/
public BlockVector(Vector position) {
super(position);
}
/**
* Construct a new instance.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public BlockVector(int x, int y, int z) {
super(x, y, z);
}
/**
* Construct a new instance.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public BlockVector(float x, float y, float z) {
super(x, y, z);
}
/**
* Construct a new instance.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public BlockVector(double x, double y, double z) {
super(x, y, z);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector)) {
return false;
}
Vector other = (Vector) obj;
return (int) other.getX() == (int) this.x && (int) other.getY() == (int) this.y
&& (int) other.getZ() == (int) this.z;
}
@Override
public int hashCode() {
return ((int) x << 19) ^
((int) y << 12) ^
(int) z;
}
@Override
public BlockVector toBlockVector() {
return this;
}
}

View File

@ -0,0 +1,94 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
/**
* Extension of {@code Vector2D} that that compares with other instances
* using integer components.
*/
public class BlockVector2D extends Vector2D {
public static final BlockVector2D ZERO = new BlockVector2D(0, 0);
public static final BlockVector2D UNIT_X = new BlockVector2D(1, 0);
public static final BlockVector2D UNIT_Z = new BlockVector2D(0, 1);
public static final BlockVector2D ONE = new BlockVector2D(1, 1);
/**
* Construct an instance from another instance.
*
* @param position the position to copy
*/
public BlockVector2D(Vector2D position) {
super(position);
}
/**
* Construct a new instance.
*
* @param x the X coordinate
* @param z the Z coordinate
*/
public BlockVector2D(int x, int z) {
super(x, z);
}
/**
* Construct a new instance.
*
* @param x the X coordinate
* @param z the Z coordinate
*/
public BlockVector2D(float x, float z) {
super(x, z);
}
/**
* Construct a new instance.
*
* @param x the X coordinate
* @param z the Z coordinate
*/
public BlockVector2D(double x, double z) {
super(x, z);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector2D)) {
return false;
}
Vector2D other = (Vector2D) obj;
return (int) other.x == (int) this.x && (int) other.z == (int) this.z;
}
@Override
public int hashCode() {
return (Integer.valueOf((int) x).hashCode() >> 13) ^
Integer.valueOf((int) z).hashCode();
}
@Override
public BlockVector2D toBlockVector2D() {
return this;
}
}

View File

@ -0,0 +1,124 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
/**
* @deprecated Replace all uses of {@link WorldVector}s with {@link Location}s
*/
@SuppressWarnings("deprecation")
@Deprecated
public class BlockWorldVector extends WorldVector {
/**
* Construct an instance from another instance.
*
* @param position the position to copy
*/
public BlockWorldVector(WorldVector position) {
super(position.getWorld(), position);
}
/**
* Construct an instance from another instance.
*
* @param world the world
* @param position the position to copy
*/
public BlockWorldVector(LocalWorld world, Vector position) {
super(world, position);
}
/**
* Construct a new instance.
*
* @param world another instance
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public BlockWorldVector(WorldVector world, int x, int y, int z) {
super(world.getWorld(), x, y, z);
}
/**
* Construct a new instance.
*
* @param world another instance
* @param v the other vector
*/
public BlockWorldVector(WorldVector world, Vector v) {
super(world.getWorld(), v.getX(), v.getY(), v.getZ());
}
/**
* Construct a new instance.
*
* @param world a world
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public BlockWorldVector(LocalWorld world, int x, int y, int z) {
super(world, x, y, z);
}
/**
* Construct a new instance.
*
* @param world a world
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public BlockWorldVector(LocalWorld world, float x, float y, float z) {
super(world, x, y, z);
}
/**
* Construct a new instance.
*
* @param world a world
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public BlockWorldVector(LocalWorld world, double x, double y, double z) {
super(world, x, y, z);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector)) {
return false;
}
Vector other = (Vector) obj;
return (int) other.getX() == (int) this.x && (int) other.getY() == (int) this.y
&& (int) other.getZ() == (int) this.z;
}
@Override
public int hashCode() {
return (Integer.valueOf((int) x).hashCode() << 19) ^
(Integer.valueOf((int) y).hashCode() << 12) ^
Integer.valueOf((int) z).hashCode();
}
}

View File

@ -0,0 +1,105 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
/**
* @deprecated Replace all uses of {@link WorldVector}s with {@link Location}s
*/
@SuppressWarnings("deprecation")
@Deprecated
public class BlockWorldVector2D extends WorldVector2D {
/**
* Construct a new instance.
*
* @param world the world
* @param x the X coordinate
* @param z the Z coordinate
*/
public BlockWorldVector2D(LocalWorld world, double x, double z) {
super(world, x, z);
}
/**
* Construct a new instance.
*
* @param world the world
* @param x the X coordinate
* @param z the Z coordinate
*/
public BlockWorldVector2D(LocalWorld world, float x, float z) {
super(world, x, z);
}
/**
* Construct a new instance.
*
* @param world the world
* @param x the X coordinate
* @param z the Z coordinate
*/
public BlockWorldVector2D(LocalWorld world, int x, int z) {
super(world, x, z);
}
/**
* Construct a new instance.
*
* @param world the world
* @param position a position
*/
public BlockWorldVector2D(LocalWorld world, Vector2D position) {
super(world, position);
}
/**
* Construct a new instance with X and Z set to (0, 0).
*
* @param world the world
*/
public BlockWorldVector2D(LocalWorld world) {
super(world);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof WorldVector2D)) {
return false;
}
WorldVector2D other = (WorldVector2D) obj;
return other.getWorld().equals(world)
&& (int) other.getX() == (int) this.x
&& (int) other.getZ() == (int) this.z;
}
@Override
public int hashCode() {
int result = super.hashCode();
long temp;
result = 31 * result + world.hashCode();
temp = Double.doubleToLongBits(x);
result = 31 * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(z);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
}

View File

@ -0,0 +1,695 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.command.ClipboardCommands;
import com.sk89q.worldedit.command.SchematicCommands;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.schematic.SchematicFormat;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.world.DataException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The clipboard remembers the state of a cuboid region.
*
* @deprecated This is slowly being replaced with {@link Clipboard}, which is
* far more versatile. Transforms are supported using affine
* transformations and full entity support is provided because
* the clipboard properly implements {@link Extent}. However,
* the new clipboard class is only available in WorldEdit 6.x and
* beyond. We intend on keeping this deprecated class in WorldEdit
* for an extended amount of time so there is no rush to
* switch (but new features will not be supported). To copy between
* a clipboard and a world (or between any two {@code Extent}s),
* one can use {@link ForwardExtentCopy}. See
* {@link ClipboardCommands} and {@link SchematicCommands} for
* more information.
*/
@Deprecated
public class CuboidClipboard {
/**
* An enum of possible flip directions.
*/
public enum FlipDirection {
NORTH_SOUTH,
WEST_EAST,
UP_DOWN
}
private BaseBlock[][][] data;
private Vector offset;
private Vector origin;
private Vector size;
private List<CopiedEntity> entities = new ArrayList<CopiedEntity>();
/**
* Constructs the clipboard.
*
* @param size the dimensions of the clipboard (should be at least 1 on every dimension)
*/
public CuboidClipboard(Vector size) {
checkNotNull(size);
this.size = size;
data = new BaseBlock[size.getBlockX()][size.getBlockY()][size.getBlockZ()];
origin = new Vector();
offset = new Vector();
}
/**
* Constructs the clipboard.
*
* @param size the dimensions of the clipboard (should be at least 1 on every dimension)
* @param origin the origin point where the copy was made, which must be the
* {@link CuboidRegion#getMinimumPoint()} relative to the copy
*/
public CuboidClipboard(Vector size, Vector origin) {
checkNotNull(size);
checkNotNull(origin);
this.size = size;
data = new BaseBlock[size.getBlockX()][size.getBlockY()][size.getBlockZ()];
this.origin = origin;
offset = new Vector();
}
/**
* Constructs the clipboard.
*
* @param size the dimensions of the clipboard (should be at least 1 on every dimension)
* @param origin the origin point where the copy was made, which must be the
* {@link CuboidRegion#getMinimumPoint()} relative to the copy
* @param offset the offset from the minimum point of the copy where the user was
*/
public CuboidClipboard(Vector size, Vector origin, Vector offset) {
checkNotNull(size);
checkNotNull(origin);
checkNotNull(offset);
this.size = size;
data = new BaseBlock[size.getBlockX()][size.getBlockY()][size.getBlockZ()];
this.origin = origin;
this.offset = offset;
}
/**
* Get the width (X-direction) of the clipboard.
*
* @return width
*/
public int getWidth() {
return size.getBlockX();
}
/**
* Get the length (Z-direction) of the clipboard.
*
* @return length
*/
public int getLength() {
return size.getBlockZ();
}
/**
* Get the height (Y-direction) of the clipboard.
*
* @return height
*/
public int getHeight() {
return size.getBlockY();
}
/**
* Rotate the clipboard in 2D. It can only rotate by angles divisible by 90.
*
* @param angle in degrees
*/
@SuppressWarnings("deprecation")
public void rotate2D(int angle) {
angle = angle % 360;
if (angle % 90 != 0) { // Can only rotate 90 degrees at the moment
return;
}
final boolean reverse = angle < 0;
final int numRotations = Math.abs((int) Math.floor(angle / 90.0));
final int width = getWidth();
final int length = getLength();
final int height = getHeight();
final Vector sizeRotated = size.transform2D(angle, 0, 0, 0, 0);
final int shiftX = sizeRotated.getX() < 0 ? -sizeRotated.getBlockX() - 1 : 0;
final int shiftZ = sizeRotated.getZ() < 0 ? -sizeRotated.getBlockZ() - 1 : 0;
final BaseBlock[][][] newData = new BaseBlock
[Math.abs(sizeRotated.getBlockX())]
[Math.abs(sizeRotated.getBlockY())]
[Math.abs(sizeRotated.getBlockZ())];
for (int x = 0; x < width; ++x) {
for (int z = 0; z < length; ++z) {
final Vector2D v = new Vector2D(x, z).transform2D(angle, 0, 0, shiftX, shiftZ);
final int newX = v.getBlockX();
final int newZ = v.getBlockZ();
for (int y = 0; y < height; ++y) {
final BaseBlock block = data[x][y][z];
newData[newX][y][newZ] = block;
if (block == null) {
continue;
}
if (reverse) {
for (int i = 0; i < numRotations; ++i) {
block.rotate90Reverse();
}
} else {
for (int i = 0; i < numRotations; ++i) {
block.rotate90();
}
}
}
}
}
data = newData;
size = new Vector(Math.abs(sizeRotated.getBlockX()),
Math.abs(sizeRotated.getBlockY()),
Math.abs(sizeRotated.getBlockZ()));
offset = offset.transform2D(angle, 0, 0, 0, 0)
.subtract(shiftX, 0, shiftZ);
}
/**
* Flip the clipboard.
*
* @param dir direction to flip
*/
public void flip(FlipDirection dir) {
flip(dir, false);
}
/**
* Flip the clipboard.
*
* @param dir direction to flip
* @param aroundPlayer flip the offset around the player
*/
@SuppressWarnings("deprecation")
public void flip(FlipDirection dir, boolean aroundPlayer) {
checkNotNull(dir);
final int width = getWidth();
final int length = getLength();
final int height = getHeight();
switch (dir) {
case WEST_EAST:
final int wid = (int) Math.ceil(width / 2.0f);
for (int xs = 0; xs < wid; ++xs) {
for (int z = 0; z < length; ++z) {
for (int y = 0; y < height; ++y) {
final BaseBlock block1 = data[xs][y][z];
if (block1 != null) {
block1.flip(dir);
}
// Skip the center plane
if (xs == width - xs - 1) {
continue;
}
final BaseBlock block2 = data[width - xs - 1][y][z];
if (block2 != null) {
block2.flip(dir);
}
data[xs][y][z] = block2;
data[width - xs - 1][y][z] = block1;
}
}
}
if (aroundPlayer) {
offset = offset.setX(1 - offset.getX() - width);
}
break;
case NORTH_SOUTH:
final int len = (int) Math.ceil(length / 2.0f);
for (int zs = 0; zs < len; ++zs) {
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
final BaseBlock block1 = data[x][y][zs];
if (block1 != null) {
block1.flip(dir);
}
// Skip the center plane
if (zs == length - zs - 1) {
continue;
}
final BaseBlock block2 = data[x][y][length - zs - 1];
if (block2 != null) {
block2.flip(dir);
}
data[x][y][zs] = block2;
data[x][y][length - zs - 1] = block1;
}
}
}
if (aroundPlayer) {
offset = offset.setZ(1 - offset.getZ() - length);
}
break;
case UP_DOWN:
final int hei = (int) Math.ceil(height / 2.0f);
for (int ys = 0; ys < hei; ++ys) {
for (int x = 0; x < width; ++x) {
for (int z = 0; z < length; ++z) {
final BaseBlock block1 = data[x][ys][z];
if (block1 != null) {
block1.flip(dir);
}
// Skip the center plane
if (ys == height - ys - 1) {
continue;
}
final BaseBlock block2 = data[x][height - ys - 1][z];
if (block2 != null) {
block2.flip(dir);
}
data[x][ys][z] = block2;
data[x][height - ys - 1][z] = block1;
}
}
}
if (aroundPlayer) {
offset = offset.setY(1 - offset.getY() - height);
}
break;
}
}
/**
* Copies blocks to the clipboard.
*
* @param editSession the EditSession from which to take the blocks
*/
public void copy(EditSession editSession) {
for (int x = 0; x < size.getBlockX(); ++x) {
for (int y = 0; y < size.getBlockY(); ++y) {
for (int z = 0; z < size.getBlockZ(); ++z) {
data[x][y][z] =
editSession.getBlock(new Vector(x, y, z).add(getOrigin()));
}
}
}
}
/**
* Copies blocks to the clipboard.
*
* @param editSession The EditSession from which to take the blocks
* @param region A region that further constrains which blocks to take.
*/
public void copy(EditSession editSession, Region region) {
for (int x = 0; x < size.getBlockX(); ++x) {
for (int y = 0; y < size.getBlockY(); ++y) {
for (int z = 0; z < size.getBlockZ(); ++z) {
final Vector pt = new Vector(x, y, z).add(getOrigin());
if (region.contains(pt)) {
data[x][y][z] = editSession.getBlock(pt);
} else {
data[x][y][z] = null;
}
}
}
}
}
/**
* Paste the clipboard at the given location using the given {@code EditSession}.
*
* <p>This method blocks the server/game until the entire clipboard is
* pasted. In the future, {@link ForwardExtentCopy} will be recommended,
* which, if combined with the proposed operation scheduler framework,
* will not freeze the game/server.</p>
*
* @param editSession the EditSession to which blocks are to be copied to
* @param newOrigin the new origin point (must correspond to the minimum point of the cuboid)
* @param noAir true to not copy air blocks in the source
* @throws MaxChangedBlocksException thrown if too many blocks were changed
*/
public void paste(EditSession editSession, Vector newOrigin, boolean noAir) throws MaxChangedBlocksException {
paste(editSession, newOrigin, noAir, false);
}
/**
* Paste the clipboard at the given location using the given {@code EditSession}.
*
* <p>This method blocks the server/game until the entire clipboard is
* pasted. In the future, {@link ForwardExtentCopy} will be recommended,
* which, if combined with the proposed operation scheduler framework,
* will not freeze the game/server.</p>
*
* @param editSession the EditSession to which blocks are to be copied to
* @param newOrigin the new origin point (must correspond to the minimum point of the cuboid)
* @param noAir true to not copy air blocks in the source
* @param entities true to copy entities
* @throws MaxChangedBlocksException thrown if too many blocks were changed
*/
public void paste(EditSession editSession, Vector newOrigin, boolean noAir, boolean entities) throws MaxChangedBlocksException {
place(editSession, newOrigin.add(offset), noAir);
if (entities) {
pasteEntities(newOrigin.add(offset));
}
}
/**
* Paste the clipboard at the given location using the given {@code EditSession}.
*
* <p>This method blocks the server/game until the entire clipboard is
* pasted. In the future, {@link ForwardExtentCopy} will be recommended,
* which, if combined with the proposed operation scheduler framework,
* will not freeze the game/server.</p>
*
* @param editSession the EditSession to which blocks are to be copied to
* @param newOrigin the new origin point (must correspond to the minimum point of the cuboid)
* @param noAir true to not copy air blocks in the source
* @throws MaxChangedBlocksException thrown if too many blocks were changed
*/
public void place(EditSession editSession, Vector newOrigin, boolean noAir) throws MaxChangedBlocksException {
for (int x = 0; x < size.getBlockX(); ++x) {
for (int y = 0; y < size.getBlockY(); ++y) {
for (int z = 0; z < size.getBlockZ(); ++z) {
final BaseBlock block = data[x][y][z];
if (block == null) {
continue;
}
if (noAir && block.isAir()) {
continue;
}
editSession.setBlock(new Vector(x, y, z).add(newOrigin), block);
}
}
}
}
/**
* Paste the stored entities to the given position.
*
* @param newOrigin the new origin
* @return a list of entities that were pasted
*/
public LocalEntity[] pasteEntities(Vector newOrigin) {
LocalEntity[] entities = new LocalEntity[this.entities.size()];
for (int i = 0; i < this.entities.size(); ++i) {
CopiedEntity copied = this.entities.get(i);
if (copied.entity.spawn(copied.entity.getPosition().setPosition(copied.relativePosition.add(newOrigin)))) {
entities[i] = copied.entity;
}
}
return entities;
}
/**
* Store an entity.
*
* @param entity the entity
*/
public void storeEntity(LocalEntity entity) {
this.entities.add(new CopiedEntity(entity));
}
/**
* Get the block at the given position.
*
* <p>If the position is out of bounds, air will be returned.</p>
*
* @param position the point, relative to the origin of the copy (0, 0, 0) and not to the actual copy origin
* @return air, if this block was outside the (non-cuboid) selection while copying
* @throws ArrayIndexOutOfBoundsException if the position is outside the bounds of the CuboidClipboard
* @deprecated use {@link #getBlock(Vector)} instead
*/
@Deprecated
public BaseBlock getPoint(Vector position) throws ArrayIndexOutOfBoundsException {
final BaseBlock block = getBlock(position);
if (block == null) {
return new BaseBlock(BlockID.AIR);
}
return block;
}
/**
* Get the block at the given position.
*
* <p>If the position is out of bounds, air will be returned.</p>
*
* @param position the point, relative to the origin of the copy (0, 0, 0) and not to the actual copy origin
* @return null, if this block was outside the (non-cuboid) selection while copying
* @throws ArrayIndexOutOfBoundsException if the position is outside the bounds of the CuboidClipboard
*/
public BaseBlock getBlock(Vector position) throws ArrayIndexOutOfBoundsException {
return data[position.getBlockX()][position.getBlockY()][position.getBlockZ()];
}
/**
* Set the block at a position in the clipboard.
*
* @param position the point, relative to the origin of the copy (0, 0, 0) and not to the actual copy origin.
* @param block the block to set
* @throws ArrayIndexOutOfBoundsException if the position is outside the bounds of the CuboidClipboard
*/
public void setBlock(Vector position, BaseBlock block) {
data[position.getBlockX()][position.getBlockY()][position.getBlockZ()] = block;
}
/**
* Get the dimensions of the clipboard.
*
* @return the dimensions, where (1, 1, 1) is 1 wide, 1 across, 1 deep
*/
public Vector getSize() {
return size;
}
/**
* Saves the clipboard data to a .schematic-format file.
*
* @param path the path to the file to save
* @throws IOException thrown on I/O error
* @throws DataException thrown on error writing the data for other reasons
* @deprecated use {@link SchematicFormat#MCEDIT}
*/
@Deprecated
public void saveSchematic(File path) throws IOException, DataException {
checkNotNull(path);
SchematicFormat.MCEDIT.save(this, path);
}
/**
* Load a .schematic file into a clipboard.
*
* @param path the path to the file to load
* @return a clipboard
* @throws IOException thrown on I/O error
* @throws DataException thrown on error writing the data for other reasons
* @deprecated use {@link SchematicFormat#MCEDIT}
*/
@Deprecated
public static CuboidClipboard loadSchematic(File path) throws DataException, IOException {
checkNotNull(path);
return SchematicFormat.MCEDIT.load(path);
}
/**
* Get the origin point, which corresponds to where the copy was
* originally copied from. The origin is the lowest possible X, Y, and
* Z components of the cuboid region that was copied.
*
* @return the origin
*/
public Vector getOrigin() {
return origin;
}
/**
* Set the origin point, which corresponds to where the copy was
* originally copied from. The origin is the lowest possible X, Y, and
* Z components of the cuboid region that was copied.
*
* @param origin the origin to set
*/
public void setOrigin(Vector origin) {
checkNotNull(origin);
this.origin = origin;
}
/**
* Get the offset of the player to the clipboard's minimum point
* (minimum X, Y, Z coordinates).
*
* <p>The offset is inverse (multiplied by -1).</p>
*
* @return the offset the offset
*/
public Vector getOffset() {
return offset;
}
/**
* Set the offset of the player to the clipboard's minimum point
* (minimum X, Y, Z coordinates).
*
* <p>The offset is inverse (multiplied by -1).</p>
*
* @param offset the new offset
*/
public void setOffset(Vector offset) {
this.offset = offset;
}
/**
* Get the block distribution inside a clipboard.
*
* @return a block distribution
*/
public List<Countable<Integer>> getBlockDistribution() {
List<Countable<Integer>> distribution = new ArrayList<Countable<Integer>>();
Map<Integer, Countable<Integer>> map = new HashMap<Integer, Countable<Integer>>();
int maxX = getWidth();
int maxY = getHeight();
int maxZ = getLength();
for (int x = 0; x < maxX; ++x) {
for (int y = 0; y < maxY; ++y) {
for (int z = 0; z < maxZ; ++z) {
final BaseBlock block = data[x][y][z];
if (block == null) {
continue;
}
int id = block.getId();
if (map.containsKey(id)) {
map.get(id).increment();
} else {
Countable<Integer> c = new Countable<Integer>(id, 1);
map.put(id, c);
distribution.add(c);
}
}
}
}
Collections.sort(distribution);
// Collections.reverse(distribution);
return distribution;
}
/**
* Get the block distribution inside a clipboard with data values.
*
* @return a block distribution
*/
// TODO reduce code duplication
public List<Countable<BaseBlock>> getBlockDistributionWithData() {
List<Countable<BaseBlock>> distribution = new ArrayList<Countable<BaseBlock>>();
Map<BaseBlock, Countable<BaseBlock>> map = new HashMap<BaseBlock, Countable<BaseBlock>>();
int maxX = getWidth();
int maxY = getHeight();
int maxZ = getLength();
for (int x = 0; x < maxX; ++x) {
for (int y = 0; y < maxY; ++y) {
for (int z = 0; z < maxZ; ++z) {
final BaseBlock block = data[x][y][z];
if (block == null) {
continue;
}
// Strip the block from metadata that is not part of our key
final BaseBlock bareBlock = new BaseBlock(block.getId(), block.getData());
if (map.containsKey(bareBlock)) {
map.get(bareBlock).increment();
} else {
Countable<BaseBlock> c = new Countable<BaseBlock>(bareBlock, 1);
map.put(bareBlock, c);
distribution.add(c);
}
}
}
}
Collections.sort(distribution);
// Collections.reverse(distribution);
return distribution;
}
/**
* Stores a copied entity.
*/
private class CopiedEntity {
private final LocalEntity entity;
private final Vector relativePosition;
private CopiedEntity(LocalEntity entity) {
this.entity = entity;
this.relativePosition = entity.getPosition().getPosition().subtract(getOrigin());
}
}
}

View File

@ -0,0 +1,42 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
/**
* Thrown when a disallowed item is used.
*/
public class DisallowedItemException extends WorldEditException {
private String type;
public DisallowedItemException(String type) {
this.type = type;
}
public DisallowedItemException(String type, String message) {
super(message);
this.type = type;
}
public String getID() {
return type;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,234 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.util.eventbus.EventBus;
import com.sk89q.worldedit.world.World;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Creates new {@link EditSession}s. To get an instance of this factory,
* use {@link WorldEdit#getEditSessionFactory()}.
*
* <p>It is no longer possible to replace the instance of this in WorldEdit
* with a custom one. Use {@link EditSessionEvent} to override
* the creation of {@link EditSession}s.</p>
*/
public class EditSessionFactory {
/**
* Construct an edit session with a maximum number of blocks.
*
* @param world the world
* @param maxBlocks the maximum number of blocks that can be changed, or -1 to use no limit
* @return an instance
*/
public EditSession getEditSession(World world, int maxBlocks) {
// ============ READ ME ============
// This method is actually implemented if you call WorldEdit.getEditSessionFactory()
// as it returns an instance of EditSessionFactoryImpl seen below.
// Previously, other plugins would create their own EditSessionFactory and extend ours and
// then use it to return custom EditSessions so the plugin could log block changes, etc.
// However, that method only allows one plugin to hook into WorldEdit at a time,
// so now we recommend catching the EditSessionEvent and hooking into our
// new(er) Extent framework.
throw new RuntimeException("Method needs to be implemented");
}
/**
* Construct an edit session with a maximum number of blocks.
*
* @param world the world
* @param maxBlocks the maximum number of blocks that can be changed, or -1 to use no limit
* @param player the player that the {@link EditSession} is for
* @return an instance
*/
public EditSession getEditSession(World world, int maxBlocks, Player player) {
// ============ READ ME ============
// This method is actually implemented if you call WorldEdit.getEditSessionFactory()
// as it returns an instance of EditSessionFactoryImpl seen below.
// Previously, other plugins would create their own EditSessionFactory and extend ours and
// then use it to return custom EditSessions so the plugin could log block changes, etc.
// However, that method only allows one plugin to hook into WorldEdit at a time,
// so now we recommend catching the EditSessionEvent and hooking into our
// new(er) Extent framework.
throw new RuntimeException("Method needs to be implemented");
}
/**
* Construct an edit session with a maximum number of blocks and a block bag.
*
* @param world the world
* @param maxBlocks the maximum number of blocks that can be changed, or -1 to use no limit
* @param blockBag an optional {@link BlockBag} to use, otherwise null
* @return an instance
*/
public EditSession getEditSession(World world, int maxBlocks, BlockBag blockBag) {
// ============ READ ME ============
// This method is actually implemented if you call WorldEdit.getEditSessionFactory()
// as it returns an instance of EditSessionFactoryImpl seen below.
// Previously, other plugins would create their own EditSessionFactory and extend ours and
// then use it to return custom EditSessions so the plugin could log block changes, etc.
// However, that method only allows one plugin to hook into WorldEdit at a time,
// so now we recommend catching the EditSessionEvent and hooking into our
// new(er) Extent framework.
throw new RuntimeException("Method needs to be implemented");
}
/**
* Construct an edit session with a maximum number of blocks and a block bag.
*
* @param world the world
* @param maxBlocks the maximum number of blocks that can be changed, or -1 to use no limit
* @param blockBag an optional {@link BlockBag} to use, otherwise null
* @param player the player that the {@link EditSession} is for
* @return an instance
*/
public EditSession getEditSession(World world, int maxBlocks, BlockBag blockBag, Player player) {
// ============ READ ME ============
// This method is actually implemented if you call WorldEdit.getEditSessionFactory()
// as it returns an instance of EditSessionFactoryImpl seen below.
// Previously, other plugins would create their own EditSessionFactory and extend ours and
// then use it to return custom EditSessions so the plugin could log block changes, etc.
// However, that method only allows one plugin to hook into WorldEdit at a time,
// so now we recommend catching the EditSessionEvent and hooking into our
// new(er) Extent framework.
throw new RuntimeException("Method needs to be implemented");
}
// ------------------------------------------------------------------------
// Methods being deprecated
// ------------------------------------------------------------------------
/**
* Construct an edit session.
*
* @param world the world
* @param maxBlocks the maximum number of blocks that can be changed, or -1 to use no limit
* @return an instance
* @deprecated We are replacing {@link LocalWorld} with {@link World}, so use {@link #getEditSession(World, int)} instead
*/
@Deprecated
public EditSession getEditSession(LocalWorld world, int maxBlocks) {
return getEditSession((World) world, maxBlocks);
}
/**
* Construct an edit session.
*
* @param world the world
* @param maxBlocks the maximum number of blocks that can be changed, or -1 to use no limit
* @param player the player that the {@link EditSession} is for
* @return an instance
* @deprecated We are replacing {@link LocalWorld} with {@link World}, so use {@link #getEditSession(World, int, Player)} instead
*/
@Deprecated
public EditSession getEditSession(LocalWorld world, int maxBlocks, LocalPlayer player) {
return getEditSession((World) world, maxBlocks, player);
}
/**
* Construct an edit session.
*
* @param world the world
* @param maxBlocks the maximum number of blocks that can be changed, or -1 to use no limit
* @param blockBag an optional {@link BlockBag} to use, otherwise null
* @return an instance
* @deprecated We are replacing {@link LocalWorld} with {@link World}, so use {@link #getEditSession(World, int, BlockBag)} instead
*/
@Deprecated
public EditSession getEditSession(LocalWorld world, int maxBlocks, BlockBag blockBag) {
return getEditSession((World) world, maxBlocks, blockBag);
}
/**
* Construct an edit session.
*
* @param world the world
* @param maxBlocks the maximum number of blocks that can be changed, or -1 to use no limit
* @param blockBag an optional {@link BlockBag} to use, otherwise null
* @param player the player that the {@link EditSession} is for
* @return an instance
* @deprecated We are replacing {@link LocalWorld} with {@link World}, so use {@link #getEditSession(World, int, BlockBag, Player)} instead
*/
@Deprecated
public EditSession getEditSession(LocalWorld world, int maxBlocks, BlockBag blockBag, LocalPlayer player) {
return getEditSession((World) world, maxBlocks, blockBag, player);
}
/**
* Internal factory for {@link EditSession}s.
*/
static final class EditSessionFactoryImpl extends EditSessionFactory {
private final EventBus eventBus;
/**
* Create a new factory.
*
* @param eventBus the event bus
*/
EditSessionFactoryImpl(EventBus eventBus) {
checkNotNull(eventBus);
this.eventBus = eventBus;
}
@Override
public EditSession getEditSession(World world, int maxBlocks) {
return new EditSession(eventBus, world, maxBlocks, null, new EditSessionEvent(world, null, maxBlocks, null));
}
@Override
public EditSession getEditSession(World world, int maxBlocks, Player player) {
return new EditSession(eventBus, world, maxBlocks, null, new EditSessionEvent(world, player, maxBlocks, null));
}
@Override
public EditSession getEditSession(World world, int maxBlocks, BlockBag blockBag) {
return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, null, maxBlocks, null));
}
@Override
public EditSession getEditSession(World world, int maxBlocks, BlockBag blockBag, Player player) {
return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, player, maxBlocks, null));
}
}
}

View File

@ -0,0 +1,27 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
/**
* Thrown when there is no clipboard set.
*/
public class EmptyClipboardException extends WorldEditException {
}

View File

@ -0,0 +1,27 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
/**
* Raised when a region is not fully defined.
*/
public class IncompleteRegionException extends WorldEditException {
}

View File

@ -0,0 +1,31 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
/**
* Thrown when an invalid item is specified.
*/
public class InvalidItemException extends DisallowedItemException {
public InvalidItemException(String type, String message) {
super(type, message);
}
}

Some files were not shown because too many files have changed in this diff Show More