TAG_Byte_Array tag.
+ * @author Graham Edgecombe
+ *
+ */
+public final class ByteArrayTag extends Tag {
+
+ /**
+ * The value.
+ */
+ private final byte[] value;
+
+ /**
+ * Creates the tag.
+ * @param name The name.
+ * @param value The value.
+ */
+ 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.toString();
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/ByteTag.java b/src/com/garbagemule/MobArena/util/jnbt/ByteTag.java
new file mode 100644
index 0000000..b03463d
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/ByteTag.java
@@ -0,0 +1,73 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * The TAG_Byte tag.
+ * @author Graham Edgecombe
+ *
+ */
+public final class ByteTag extends Tag {
+
+ /**
+ * The value.
+ */
+ private final byte value;
+
+ /**
+ * Creates the tag.
+ * @param name The name.
+ * @param value The value.
+ */
+ 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;
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/CompoundTag.java b/src/com/garbagemule/MobArena/util/jnbt/CompoundTag.java
new file mode 100644
index 0000000..3b59a9c
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/CompoundTag.java
@@ -0,0 +1,82 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * The TAG_Compound tag.
+ * @author Graham Edgecombe
+ *
+ */
+public final class CompoundTag extends Tag {
+
+ /**
+ * The value.
+ */
+ private final MapTAG_Double tag.
+ * @author Graham Edgecombe
+ *
+ */
+public final class DoubleTag extends Tag {
+
+ /**
+ * The value.
+ */
+ private final double value;
+
+ /**
+ * Creates the tag.
+ * @param name The name.
+ * @param value The value.
+ */
+ 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;
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/EndTag.java b/src/com/garbagemule/MobArena/util/jnbt/EndTag.java
new file mode 100644
index 0000000..e9ff5fe
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/EndTag.java
@@ -0,0 +1,60 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * The TAG_End tag.
+ * @author Graham Edgecombe
+ *
+ */
+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";
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/FloatTag.java b/src/com/garbagemule/MobArena/util/jnbt/FloatTag.java
new file mode 100644
index 0000000..7ff0ad5
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/FloatTag.java
@@ -0,0 +1,73 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * The TAG_Float tag.
+ * @author Graham Edgecombe
+ *
+ */
+public final class FloatTag extends Tag {
+
+ /**
+ * The value.
+ */
+ private final float value;
+
+ /**
+ * Creates the tag.
+ * @param name The name.
+ * @param value The value.
+ */
+ 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;
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/IntTag.java b/src/com/garbagemule/MobArena/util/jnbt/IntTag.java
new file mode 100644
index 0000000..f728a43
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/IntTag.java
@@ -0,0 +1,73 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * The TAG_Int tag.
+ * @author Graham Edgecombe
+ *
+ */
+public final class IntTag extends Tag {
+
+ /**
+ * The value.
+ */
+ private final int value;
+
+ /**
+ * Creates the tag.
+ * @param name The name.
+ * @param value The value.
+ */
+ 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;
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/ListTag.java b/src/com/garbagemule/MobArena/util/jnbt/ListTag.java
new file mode 100644
index 0000000..e5b6a18
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/ListTag.java
@@ -0,0 +1,97 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * The TAG_List tag.
+ * @author Graham Edgecombe
+ *
+ */
+public final class ListTag extends Tag {
+
+ /**
+ * The type.
+ */
+ private final Class extends Tag> type;
+
+ /**
+ * The value.
+ */
+ private final ListTAG_Long tag.
+ * @author Graham Edgecombe
+ *
+ */
+public final class LongTag extends Tag {
+
+ /**
+ * The value.
+ */
+ private final long value;
+
+ /**
+ * Creates the tag.
+ * @param name The name.
+ * @param value The value.
+ */
+ 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;
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/NBTConstants.java b/src/com/garbagemule/MobArena/util/jnbt/NBTConstants.java
new file mode 100644
index 0000000..b03c11c
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/NBTConstants.java
@@ -0,0 +1,72 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+import java.nio.charset.Charset;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * A class which holds constant values.
+ * @author Graham Edgecombe
+ *
+ */
+public final class NBTConstants {
+
+ /**
+ * The character set used by NBT (UTF-8).
+ */
+ public static final Charset CHARSET = Charset.forName("UTF-8");
+
+ /**
+ * Tag type constants.
+ */
+ 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;
+
+ /**
+ * Default private constructor.
+ */
+ private NBTConstants() {
+
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/NBTInputStream.java b/src/com/garbagemule/MobArena/util/jnbt/NBTInputStream.java
new file mode 100644
index 0000000..6446dde
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/NBTInputStream.java
@@ -0,0 +1,179 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+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;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * This class reads NBT, or
+ * Named Binary Tag streams, and produces an object graph of
+ * subclasses of the Tag object.
The NBT format was created by Markus Persson, and the specification may + * be found at + * http://www.minecraft.net/docs/NBT.txt.
+ * @author Graham Edgecombe + * + */ +public final class NBTInputStream implements Closeable { + + /** + * The data input stream. + */ + private final DataInputStream is; + + /** + * Creates a newNBTInputStream, 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(new GZIPInputStream(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();
+
+ ListThis class writes NBT, or
+ * Named Binary Tag Tag objects to an underlying
+ * OutputStream.
The NBT format was created by Markus Persson, and the specification may + * be found at + * http://www.minecraft.net/docs/NBT.txt.
+ * @author Graham Edgecombe + * + */ +public final class NBTOutputStream implements Closeable { + + /** + * The output stream. + */ + private final DataOutputStream os; + + /** + * Creates a newNBTOutputStream, 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(new GZIPOutputStream(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;
+ default:
+ throw new IOException("Invalid tag type: " + type + ".");
+ }
+ }
+
+ /**
+ * Writes a 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 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 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 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();
+ ListTAG_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 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 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 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 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 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 TAG_Empty tag.
+ * @param tag The tag.
+ * @throws IOException if an I/O error occurs.
+ */
+ private void writeEndTagPayload(EndTag tag) {
+ /* empty */
+ }
+
+ @Override
+ public void close() throws IOException {
+ os.close();
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/NBTUtils.java b/src/com/garbagemule/MobArena/util/jnbt/NBTUtils.java
new file mode 100644
index 0000000..ce97632
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/NBTUtils.java
@@ -0,0 +1,152 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * A class which contains NBT-related utility methods.
+ * @author Graham Edgecombe
+ *
+ */
+public final class 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 {
+ 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 {
+ 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;
+ default:
+ throw new IllegalArgumentException("Invalid tag type : " + type + ".");
+ }
+ }
+
+ /**
+ * Default private constructor.
+ */
+ private NBTUtils() {
+
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/ShortTag.java b/src/com/garbagemule/MobArena/util/jnbt/ShortTag.java
new file mode 100644
index 0000000..d94386b
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/ShortTag.java
@@ -0,0 +1,73 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * The TAG_Short tag.
+ * @author Graham Edgecombe
+ *
+ */
+public final class ShortTag extends Tag {
+
+ /**
+ * The value.
+ */
+ private final short value;
+
+ /**
+ * Creates the tag.
+ * @param name The name.
+ * @param value The value.
+ */
+ 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;
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/StringTag.java b/src/com/garbagemule/MobArena/util/jnbt/StringTag.java
new file mode 100644
index 0000000..a894c8b
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/StringTag.java
@@ -0,0 +1,73 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * The TAG_String tag.
+ * @author Graham Edgecombe
+ *
+ */
+public final class StringTag extends Tag {
+
+ /**
+ * The value.
+ */
+ private final String value;
+
+ /**
+ * Creates the tag.
+ * @param name The name.
+ * @param value The value.
+ */
+ public StringTag(String name, String value) {
+ super(name);
+ 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;
+ }
+
+}
diff --git a/src/com/garbagemule/MobArena/util/jnbt/Tag.java b/src/com/garbagemule/MobArena/util/jnbt/Tag.java
new file mode 100644
index 0000000..19a5daf
--- /dev/null
+++ b/src/com/garbagemule/MobArena/util/jnbt/Tag.java
@@ -0,0 +1,70 @@
+package com.garbagemule.MobArena.util.jnbt;
+
+/*
+ * JNBT License
+ *
+ * Copyright (c) 2010 Graham Edgecombe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the JNBT team nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Represents a single NBT tag.
+ * @author Graham Edgecombe
+ *
+ */
+public abstract class Tag {
+
+ /**
+ * The name of this tag.
+ */
+ private final String name;
+
+ /**
+ * Creates the tag with the specified name.
+ * @param name The name.
+ */
+ public Tag(String 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 of this tag.
+ */
+ public abstract Object getValue();
+
+}
diff --git a/src/com/garbagemule/MobArena/waves/AbstractWave.java b/src/com/garbagemule/MobArena/waves/AbstractWave.java
new file mode 100644
index 0000000..9942bc2
--- /dev/null
+++ b/src/com/garbagemule/MobArena/waves/AbstractWave.java
@@ -0,0 +1,199 @@
+package com.garbagemule.MobArena.waves;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Creature;
+import org.bukkit.entity.LivingEntity;
+
+import com.garbagemule.MobArena.Arena;
+import com.garbagemule.MobArena.util.WaveUtils;
+
+public abstract class AbstractWave implements Wave
+{
+ private Arena arena;
+ private World world;
+ private String waveName;
+ private int wave, frequency, priority;
+ private WaveBranch branch;
+ private WaveType type;
+ private WaveGrowth growth;
+
+ /**
+ * Basic wave constructor.
+ * @param name The config-file identifier
+ * @param wave Initial wave number. This is the first wave number this wave can spawn at.
+ * @param frequency How often the wave can spawn.
+ * @param priority The priority of the wave.
+ * @param branch The branch type (single, recurrent)
+ */
+ public AbstractWave(Arena arena, String waveName, int wave, int frequency, int priority, WaveBranch branch)
+ {
+ this.arena = arena;
+ this.world = arena.getWorld();
+ this.waveName = waveName;
+ this.wave = wave;
+ this.frequency = frequency;
+ this.priority = priority;
+ this.branch = branch;
+ }
+
+ // Default recurrent wave constructor
+ public AbstractWave(Arena arena, String name, int wave, int frequency, int priority)
+ {
+ this(arena, name, wave, frequency, priority, WaveBranch.RECURRENT);
+ }
+
+ // Default single wave constructor
+ public AbstractWave(Arena arena, String name, int wave)
+ {
+ this(arena, name, wave, 0, 0, WaveBranch.SINGLE);
+ }
+
+ /**
+ * Check if a wave matches a wave number.
+ * SINGLE WAVES match, if their wave number is the same as the
+ * parameter.
+ * RECURRENT WAVES match, if their wave number subtracted from
+ * the parameter divides the frequency. The wave number must be
+ * greater than or equal to the parameter.
+ * @param wave The wave number to compare
+ * @return true, if the wave matches the wave number
+ */
+ public boolean matches(int wave)
+ {
+ if (branch == WaveBranch.SINGLE)
+ return this.wave == wave;
+
+ if (branch == WaveBranch.RECURRENT && wave >= this.wave)
+ return ((wave - this.wave) % frequency == 0);
+
+ return false;
+ }
+
+ /**
+ * Spawn an MACreature in the given location. The actual LivingEntity
+ * spawned is returned.
+ * @param creature The MACreature to spawn
+ * @param loc The location to spawn the MACreature in
+ * @return The resulting LivingEntity
+ */
+ public LivingEntity spawnMonster(MACreature creature, Location loc)
+ {
+ // Spawn and add to collection
+ LivingEntity e = creature.spawn(getArena(), getWorld(), loc);
+ getArena().addMonster(e);
+
+ // Grab a random target.
+ if (e instanceof Creature)
+ {
+ Creature c = (Creature) e;
+ c.setTarget(WaveUtils.getClosestPlayer(getArena(), e));
+ }
+
+ return e;
+ }
+
+ /**
+ * Helper method for spawning a bunch of monsters over a
+ * collection of spawnpoints. Used by wave types DEFAULT,
+ * SPECIAL and SWARM.
+ * @param monsters A collection of monsters to spawn, and how many of each
+ * @param spawnpoints The spawnpoints to spawn the monsters over
+ */
+ public void spawnAll(Map